static void _UpdateLineEndPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y, FX_FLOAT end_x, FX_FLOAT end_y, FX_FLOAT hw) { if (start_x == end_x) { if (start_y == end_y) { rect.UpdateRect(end_x + hw, end_y + hw); rect.UpdateRect(end_x - hw, end_y - hw); return; } FX_FLOAT point_y; if (end_y < start_y) { point_y = end_y - hw; } else { point_y = end_y + hw; } rect.UpdateRect(end_x + hw, point_y); rect.UpdateRect(end_x - hw, point_y); return; } if (start_y == end_y) { FX_FLOAT point_x; if (end_x < start_x) { point_x = end_x - hw; } else { point_x = end_x + hw; } rect.UpdateRect(point_x, end_y + hw); rect.UpdateRect(point_x, end_y - hw); return; } FX_FLOAT dx = end_x - start_x; FX_FLOAT dy = end_y - start_y; FX_FLOAT ll = FXSYS_sqrt2(dx, dy); FX_FLOAT mx = end_x + hw * dx / ll; FX_FLOAT my = end_y + hw * dy / ll; FX_FLOAT dx1 = hw * dy / ll; FX_FLOAT dy1 = hw * dx / ll; rect.UpdateRect(mx - dx1, my + dy1); rect.UpdateRect(mx + dx1, my - dy1); }
CFX_FloatRect CFX_PathData::GetBoundingBox() const { CFX_FloatRect rect; if (m_PointCount) { rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY); for (int i = 1; i < m_PointCount; i++) { rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY); } } return rect; }
CFX_FloatRect _GetShadingBBox(CPDF_Stream* pStream, int type, const CFX_AffineMatrix* pMatrix, CPDF_Function** pFuncs, int nFuncs, CPDF_ColorSpace* pCS) { if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM || pFuncs == NULL || pCS == NULL) { return CFX_FloatRect(0, 0, 0, 0); } CPDF_MeshStream stream; if (!stream.Load(pStream, pFuncs, nFuncs, pCS)) { return CFX_FloatRect(0, 0, 0, 0); } CFX_FloatRect rect; FX_BOOL bStarted = FALSE; FX_BOOL bGouraud = type == 4 || type == 5; int full_point_count = type == 7 ? 16 : (type == 6 ? 12 : 1); int full_color_count = (type == 6 || type == 7) ? 4 : 1; while (!stream.m_BitStream.IsEOF()) { FX_DWORD flag; if (type != 5) { flag = stream.GetFlag(); } int point_count = full_point_count, color_count = full_color_count; if (!bGouraud && flag) { point_count -= 4; color_count -= 2; } for (int i = 0; i < point_count; i ++) { FX_FLOAT x, y; stream.GetCoords(x, y); if (bStarted) { rect.UpdateRect(x, y); } else { rect.InitRect(x, y); bStarted = TRUE; } } stream.m_BitStream.SkipBits(stream.m_nComps * stream.m_nCompBits * color_count); if (bGouraud) { stream.m_BitStream.ByteAlign(); } } rect.Transform(pMatrix); return rect; }
static void _UpdateLineJoinPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y, FX_FLOAT middle_x, FX_FLOAT middle_y, FX_FLOAT end_x, FX_FLOAT end_y, FX_FLOAT half_width, FX_FLOAT miter_limit) { FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0, start_dc = 0, end_len = 0, end_dc = 0; FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20; FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20; if (bStartVert && bEndVert) { int start_dir = middle_y > start_y ? 1 : -1; FX_FLOAT point_y = middle_y + half_width * start_dir; rect.UpdateRect(middle_x + half_width, point_y); rect.UpdateRect(middle_x - half_width, point_y); return; } if (!bStartVert) { start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x); start_c = middle_y - FXSYS_Mul(start_k, middle_x); start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y); start_dc = (FX_FLOAT)FXSYS_fabs( FXSYS_MulDiv(half_width, start_len, start_x - middle_x)); } if (!bEndVert) { end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x); end_c = middle_y - FXSYS_Mul(end_k, middle_x); end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y); end_dc = (FX_FLOAT)FXSYS_fabs( FXSYS_MulDiv(half_width, end_len, end_x - middle_x)); } if (bStartVert) { FX_FLOAT outside_x = start_x; if (end_x < start_x) { outside_x += half_width; } else { outside_x -= half_width; } FX_FLOAT outside_y; if (start_y < FXSYS_Mul(end_k, start_x) + end_c) { outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc; } else { outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc; } rect.UpdateRect(outside_x, outside_y); return; } if (bEndVert) { FX_FLOAT outside_x = end_x; if (start_x < end_x) { outside_x += half_width; } else { outside_x -= half_width; } FX_FLOAT outside_y; if (end_y < FXSYS_Mul(start_k, end_x) + start_c) { outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc; } else { outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc; } rect.UpdateRect(outside_x, outside_y); return; } if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) { int start_dir = middle_x > start_x ? 1 : -1; int end_dir = end_x > middle_x ? 1 : -1; if (start_dir == end_dir) { _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width); } else { _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y, half_width); } return; } FX_FLOAT start_outside_c = start_c; if (end_y < FXSYS_Mul(start_k, end_x) + start_c) { start_outside_c += start_dc; } else { start_outside_c -= start_dc; } FX_FLOAT end_outside_c = end_c; if (start_y < FXSYS_Mul(end_k, start_x) + end_c) { end_outside_c += end_dc; } else { end_outside_c -= end_dc; } FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k); FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c; rect.UpdateRect(join_x, join_y); }