1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxcrt/fx_basic.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxge/fx_ge.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ClipRgn::CFX_ClipRgn(int width, int height)
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Type = RectI;
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Box.left = m_Box.top = 0;
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Box.right = width;
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Box.bottom = height;
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ClipRgn::CFX_ClipRgn(const FX_RECT& rect)
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Type = RectI;
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Box = rect;
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ClipRgn::CFX_ClipRgn(const CFX_ClipRgn& src)
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Type = src.m_Type;
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Box = src.m_Box;
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Mask = src.m_Mask;
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ClipRgn::~CFX_ClipRgn()
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ClipRgn::Reset(const FX_RECT& rect)
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Type = RectI;
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Box = rect;
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Mask.SetNull();
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ClipRgn::IntersectRect(const FX_RECT& rect)
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Type == RectI) {
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Box.Intersect(rect);
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Type == MaskF) {
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        IntersectMaskRect(rect, m_Box, m_Mask);
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ClipRgn::IntersectMaskRect(FX_RECT rect, FX_RECT mask_rect, CFX_DIBitmapRef Mask)
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CFX_DIBitmap* mask_dib = Mask;
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Type = MaskF;
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Box = rect;
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Box.Intersect(mask_rect);
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Box.IsEmpty()) {
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Type = RectI;
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Box == mask_rect) {
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Mask = Mask;
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* new_dib = m_Mask.New();
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!new_dib) {
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    new_dib->Create(m_Box.Width(), m_Box.Height(), FXDIB_8bppMask);
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int row = m_Box.top; row < m_Box.bottom; row ++) {
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE dest_scan = new_dib->GetBuffer() + new_dib->GetPitch() * (row - m_Box.top);
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPBYTE src_scan = mask_dib->GetBuffer() + mask_dib->GetPitch() * (row - mask_rect.top);
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int col = m_Box.left; col < m_Box.right; col ++) {
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dest_scan[col - m_Box.left] = src_scan[col - mask_rect.left];
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_ClipRgn::IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask)
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CFX_DIBitmap* mask_dib = Mask;
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(mask_dib->GetFormat() == FXDIB_8bppMask);
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT mask_box(left, top, left + mask_dib->GetWidth(), top + mask_dib->GetHeight());
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Type == RectI) {
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        IntersectMaskRect(m_Box, mask_box, Mask);
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Type == MaskF) {
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_RECT new_box = m_Box;
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        new_box.Intersect(mask_box);
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (new_box.IsEmpty()) {
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Type = RectI;
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Mask.SetNull();
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Box = new_box;
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_DIBitmapRef new_mask;
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_DIBitmap* new_dib = new_mask.New();
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!new_dib) {
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        new_dib->Create(new_box.Width(), new_box.Height(), FXDIB_8bppMask);
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const CFX_DIBitmap* old_dib = m_Mask;
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int row = new_box.top; row < new_box.bottom; row ++) {
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE old_scan = old_dib->GetBuffer() + (row - m_Box.top) * old_dib->GetPitch();
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE mask_scan = mask_dib->GetBuffer() + (row - top) * mask_dib->GetPitch();
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE new_scan = new_dib->GetBuffer() + (row - new_box.top) * new_dib->GetPitch();
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int col = new_box.left; col < new_box.right; col ++) {
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                new_scan[col - new_box.left] = old_scan[col - m_Box.left] * mask_scan[col - left] / 255;
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Box = new_box;
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Mask = new_mask;
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(FALSE);
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_PathData::CFX_PathData()
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PointCount = m_AllocCount = 0;
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPoints = NULL;
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_PathData::~CFX_PathData()
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pPoints) {
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pPoints);
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_PathData::SetPointCount(int nPoints)
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PointCount = nPoints;
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AllocCount < nPoints) {
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pPoints) {
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_Free(m_pPoints);
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pPoints = NULL;
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pPoints = FX_Alloc(FX_PATHPOINT, nPoints);
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_pPoints) {
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_AllocCount = nPoints;
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_PathData::AllocPointCount(int nPoints)
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_AllocCount < nPoints) {
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_PATHPOINT* pNewBuf = FX_Alloc(FX_PATHPOINT, nPoints);
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!pNewBuf) {
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_PointCount) {
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXSYS_memcpy32(pNewBuf, m_pPoints, m_PointCount * sizeof(FX_PATHPOINT));
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pPoints) {
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_Free(m_pPoints);
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pPoints = pNewBuf;
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_AllocCount = nPoints;
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_PathData::CFX_PathData(const CFX_PathData& src)
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPoints = NULL;
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PointCount = m_AllocCount = src.m_PointCount;
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPoints = FX_Alloc(FX_PATHPOINT, src.m_PointCount);
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pPoints) {
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_PathData::TrimPoints(int nPoints)
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PointCount <= nPoints) {
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SetPointCount(nPoints);
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_PathData::AddPointCount(int addPoints)
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int new_count = m_PointCount + addPoints;
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!AllocPointCount(new_count)) {
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PointCount = new_count;
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_AffineMatrix* pMatrix)
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int old_count = m_PointCount;
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!AddPointCount(pSrc->m_PointCount)) {
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(m_pPoints + old_count, pSrc->m_pPoints, pSrc->m_PointCount * sizeof(FX_PATHPOINT));
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pMatrix == NULL) {
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < pSrc->m_PointCount; i ++) {
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pMatrix->Transform(m_pPoints[old_count + i].m_PointX, m_pPoints[old_count + i].m_PointY);
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_PathData::SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag)
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(index < m_PointCount);
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPoints[index].m_PointX = x;
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPoints[index].m_PointY = y;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPoints[index].m_Flag = flag;
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_PathData::AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top)
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int old_count = m_PointCount;
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!AddPointCount(5)) {
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_PATHPOINT* pPoints = m_pPoints + old_count;
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPoints[0].m_PointX = pPoints[1].m_PointX = pPoints[4].m_PointX = left;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPoints[2].m_PointX = pPoints[3].m_PointX = right;
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPoints[0].m_PointY = pPoints[3].m_PointY = pPoints[4].m_PointY = bottom;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPoints[1].m_PointY = pPoints[2].m_PointY = top;
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPoints[0].m_Flag = FXPT_MOVETO;
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPoints[1].m_Flag = pPoints[2].m_Flag = pPoints[3].m_Flag = FXPT_LINETO;
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPoints[4].m_Flag = FXPT_LINETO | FXPT_CLOSEFIGURE;
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_FloatRect CFX_PathData::GetBoundingBox() const
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FloatRect rect;
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PointCount) {
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY);
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 1; i < m_PointCount; i ++) {
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return rect;
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void _UpdateLineEndPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y, FX_FLOAT end_x, FX_FLOAT end_y,
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                 FX_FLOAT hw)
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (start_x == end_x) {
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (start_y == end_y) {
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rect.UpdateRect(end_x + hw, end_y + hw);
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rect.UpdateRect(end_x - hw, end_y - hw);
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT point_y;
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (end_y < start_y) {
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            point_y = end_y - hw;
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            point_y = end_y + hw;
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.UpdateRect(end_x + hw, point_y);
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.UpdateRect(end_x - hw, point_y);
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (start_y == end_y) {
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT point_x;
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (end_x < start_x) {
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            point_x = end_x - hw;
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            point_x = end_x + hw;
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.UpdateRect(point_x, end_y + hw);
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.UpdateRect(point_x, end_y - hw);
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT dx = end_x - start_x;
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT dy = end_y - start_y;
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT ll = FXSYS_sqrt2(dx, dy);
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT mx = end_x + hw * dx / ll;
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT my = end_y + hw * dy / ll;
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT dx1 = hw * dy / ll;
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT dy1 = hw * dx / ll;
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rect.UpdateRect(mx - dx1, my + dy1);
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rect.UpdateRect(mx + dx1, my - dy1);
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void _UpdateLineJoinPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y,
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  FX_FLOAT middle_x, FX_FLOAT middle_y, FX_FLOAT end_x, FX_FLOAT end_y,
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  FX_FLOAT half_width, FX_FLOAT miter_limit)
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    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;
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20;
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20;
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bStartVert && bEndVert) {
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int start_dir = middle_y > start_y ? 1 : -1;
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT point_y = middle_y + half_width * start_dir;
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.UpdateRect(middle_x + half_width, point_y);
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.UpdateRect(middle_x - half_width, point_y);
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bStartVert) {
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x);
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        start_c = middle_y - FXSYS_Mul(start_k, middle_x);
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y);
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        start_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, start_len, start_x - middle_x));
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bEndVert) {
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x);
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        end_c = middle_y - FXSYS_Mul(end_k, middle_x);
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y);
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        end_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, end_len, end_x - middle_x));
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bStartVert) {
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT outside_x = start_x;
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (end_x < start_x) {
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            outside_x += half_width;
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            outside_x -= half_width;
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT outside_y;
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc;
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc;
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.UpdateRect(outside_x, outside_y);
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bEndVert) {
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT outside_x = end_x;
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (start_x < end_x) {
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            outside_x += half_width;
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            outside_x -= half_width;
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT outside_y;
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc;
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc;
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.UpdateRect(outside_x, outside_y);
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) {
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int start_dir = middle_x > start_x ? 1 : -1;
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int end_dir = end_x > middle_x ? 1 : -1;
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (start_dir == end_dir) {
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width);
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y, half_width);
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT start_outside_c = start_c;
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        start_outside_c += start_dc;
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        start_outside_c -= start_dc;
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT end_outside_c = end_c;
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        end_outside_c += end_dc;
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        end_outside_c -= end_dc;
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k);
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c;
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rect.UpdateRect(join_x, join_y);
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FloatRect rect(100000 * 1.0f, 100000 * 1.0f, -100000 * 1.0f, -100000 * 1.0f);
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int iPoint = 0;
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT half_width = line_width;
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int iStartPoint, iEndPoint, iMiddlePoint;
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bJoin;
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (iPoint < m_PointCount) {
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pPoints[iPoint].m_Flag == FXPT_MOVETO) {
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iStartPoint = iPoint + 1;
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iEndPoint = iPoint;
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bJoin = FALSE;
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_pPoints[iPoint].m_Flag == FXPT_BEZIERTO) {
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rect.UpdateRect(m_pPoints[iPoint].m_PointX, m_pPoints[iPoint].m_PointY);
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rect.UpdateRect(m_pPoints[iPoint + 1].m_PointX, m_pPoints[iPoint + 1].m_PointY);
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iPoint += 2;
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (iPoint == m_PointCount - 1 || m_pPoints[iPoint + 1].m_Flag == FXPT_MOVETO) {
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iStartPoint = iPoint - 1;
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iEndPoint = iPoint;
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                bJoin = FALSE;
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iStartPoint = iPoint - 1;
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iMiddlePoint = iPoint;
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iEndPoint = iPoint + 1;
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                bJoin = TRUE;
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT start_x = m_pPoints[iStartPoint].m_PointX;
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT start_y = m_pPoints[iStartPoint].m_PointY;
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT end_x = m_pPoints[iEndPoint].m_PointX;
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT end_y = m_pPoints[iEndPoint].m_PointY;
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bJoin) {
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_FLOAT middle_x = m_pPoints[iMiddlePoint].m_PointX;
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_FLOAT middle_y = m_pPoints[iMiddlePoint].m_PointY;
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _UpdateLineJoinPoints(rect, start_x, start_y, middle_x, middle_y, end_x, end_y, half_width, miter_limit);
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _UpdateLineEndPoints(rect, start_x, start_y, end_x, end_y, half_width);
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        iPoint ++;
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return rect;
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_PathData::Transform(const CFX_AffineMatrix* pMatrix)
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pMatrix == NULL) {
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < m_PointCount; i ++) {
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst int g_Distant[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_PathData::GetZeroAreaPath(CFX_PathData& NewPath, CFX_AffineMatrix* pMatrix, FX_BOOL&bThin, FX_BOOL bAdjust) const
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PointCount < 3) {
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PointCount == 3 && (m_pPoints[0].m_Flag & FXPT_TYPE) == FXPT_MOVETO &&
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            (m_pPoints[1].m_Flag & FXPT_TYPE) == FXPT_LINETO && (m_pPoints[2].m_Flag & FXPT_TYPE) == FXPT_LINETO
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            && m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) {
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        NewPath.AddPointCount(2);
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bAdjust) {
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pMatrix) {
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_FLOAT x = m_pPoints[0].m_PointX, y = m_pPoints[0].m_PointY;
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pMatrix->TransformPoint(x, y);
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                x = (int)x + 0.5f;
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                y = (int)y + 0.5f;
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NewPath.SetPoint(0, x, y, FXPT_MOVETO);
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                x = m_pPoints[1].m_PointX, y = m_pPoints[1].m_PointY;
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pMatrix->TransformPoint(x, y);
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                x = (int)x + 0.5f;
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                y = (int)y + 0.5f;
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NewPath.SetPoint(1, x, y, FXPT_LINETO);
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pMatrix->SetIdentity();
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_FLOAT x = (int)m_pPoints[0].m_PointX + 0.5f, y = (int)m_pPoints[0].m_PointY + 0.5f;
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NewPath.SetPoint(0, x, y, FXPT_MOVETO);
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                x = (int)m_pPoints[1].m_PointX + 0.5f, y = (int)m_pPoints[1].m_PointY + 0.5f;
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NewPath.SetPoint(1, x, y, FXPT_LINETO);
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NewPath.SetPoint(0, m_pPoints[0].m_PointX, m_pPoints[0].m_PointY, FXPT_MOVETO);
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NewPath.SetPoint(1, m_pPoints[1].m_PointX, m_pPoints[1].m_PointY, FXPT_LINETO);
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pPoints[0].m_PointX != m_pPoints[1].m_PointX && m_pPoints[0].m_PointY != m_pPoints[1].m_PointY) {
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bThin = TRUE;
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (((m_PointCount > 3) && (m_PointCount % 2))) {
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int mid = m_PointCount / 2;
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bZeroArea = FALSE;
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_PathData t_path;
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < mid; i++) {
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!(m_pPoints[mid - i - 1].m_PointX == m_pPoints[mid + i + 1].m_PointX
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    && m_pPoints[mid - i - 1].m_PointY == m_pPoints[mid + i + 1].m_PointY &&
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    ((m_pPoints[mid - i - 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && (m_pPoints[mid + i + 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO))) {
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                bZeroArea = TRUE;
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int new_count = t_path.GetPointCount();
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            t_path.AddPointCount(2);
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            t_path.SetPoint(new_count, m_pPoints[mid - i].m_PointX, m_pPoints[mid - i].m_PointY, FXPT_MOVETO);
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            t_path.SetPoint(new_count + 1, m_pPoints[mid - i - 1].m_PointX, m_pPoints[mid - i - 1].m_PointY, FXPT_LINETO);
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!bZeroArea) {
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NewPath.Append(&t_path, NULL);
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bThin = TRUE;
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int stratPoint = 0;
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int next = 0, i;
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < m_PointCount; i++) {
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int point_type = m_pPoints[i].m_Flag & FXPT_TYPE;
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (point_type == FXPT_MOVETO) {
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            stratPoint = i;
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (point_type == FXPT_LINETO) {
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            next = (i + 1 - stratPoint) % (m_PointCount - stratPoint) + stratPoint;
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && (m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_MOVETO) {
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if((m_pPoints[i - 1].m_PointX == m_pPoints[i].m_PointX && m_pPoints[i].m_PointX == m_pPoints[next].m_PointX)
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        && ((m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) * (m_pPoints[i].m_PointY - m_pPoints[next].m_PointY) > 0)) {
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int pre = i;
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY)
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            < FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[next].m_PointY)) {
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pre --;
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        next--;
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int new_count = NewPath.GetPointCount();
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NewPath.AddPointCount(2);
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoints[pre].m_PointY, FXPT_MOVETO);
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_pPoints[next].m_PointY, FXPT_LINETO);
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if((m_pPoints[i - 1].m_PointY == m_pPoints[i].m_PointY && m_pPoints[i].m_PointY == m_pPoints[next].m_PointY)
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                          && ((m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) * (m_pPoints[i].m_PointX - m_pPoints[next].m_PointX) > 0)) {
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int pre = i;
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX)
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            < FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[next].m_PointX)) {
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pre --;
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        next--;
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int new_count = NewPath.GetPointCount();
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NewPath.AddPointCount(2);
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoints[pre].m_PointY, FXPT_MOVETO);
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_pPoints[next].m_PointY, FXPT_LINETO);
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if ((m_pPoints[i - 1].m_Flag & FXPT_TYPE) == FXPT_MOVETO && (m_pPoints[next].m_Flag & FXPT_TYPE) == FXPT_LINETO &&
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                           m_pPoints[i - 1].m_PointX == m_pPoints[next].m_PointX && m_pPoints[i - 1].m_PointY == m_pPoints[next].m_PointY
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                           && m_pPoints[next].m_Flag & FXPT_CLOSEFIGURE) {
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int new_count = NewPath.GetPointCount();
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NewPath.AddPointCount(2);
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NewPath.SetPoint(new_count, m_pPoints[i - 1].m_PointX, m_pPoints[i - 1].m_PointY, FXPT_MOVETO);
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    NewPath.SetPoint(new_count + 1, m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, FXPT_LINETO);
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    bThin = TRUE;
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (point_type == FXPT_BEZIERTO) {
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            i += 2;
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PointCount > 3 && NewPath.GetPointCount()) {
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bThin = TRUE;
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (NewPath.GetPointCount() == 0) {
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_PathData::IsRect() const
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PointCount != 5 && m_PointCount != 4) {
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX ||
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            (m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) ||
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 1; i < 4; i ++) {
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) {
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pPoints[i].m_PointX != m_pPoints[i - 1].m_PointX && m_pPoints[i].m_PointY != m_pPoints[i - 1].m_PointY) {
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_PointCount == 5 || (m_pPoints[3].m_Flag & FXPT_CLOSEFIGURE);
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_PathData::IsRect(const CFX_AffineMatrix* pMatrix, CFX_FloatRect* pRect) const
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pMatrix == NULL) {
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!IsRect()) {
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pRect) {
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pRect->left = m_pPoints[0].m_PointX;
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pRect->right = m_pPoints[2].m_PointX;
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pRect->bottom = m_pPoints[0].m_PointY;
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pRect->top = m_pPoints[2].m_PointY;
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pRect->Normalize();
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PointCount != 5 && m_PointCount != 4) {
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PointCount == 4 && m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT x[5], y[5];
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < m_PointCount; i ++) {
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, x[i], y[i]);
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (i) {
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) {
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (x[i] != x[i - 1] && y[i] != y[i - 1]) {
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pRect) {
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pRect->left = x[0];
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pRect->right = x[2];
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pRect->bottom = y[0];
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pRect->top = y[2];
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pRect->Normalize();
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_PathData::Copy(const CFX_PathData &src)
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!SetPointCount(src.m_PointCount)) {
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_GraphStateData::CFX_GraphStateData()
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LineCap = LineCapButt;
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashCount = 0;
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashArray = NULL;
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashPhase = 0;
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LineJoin = LineJoinMiter;
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_MiterLimit = 10 * 1.0f;
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LineWidth = 1.0f;
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_GraphStateData::CFX_GraphStateData(const CFX_GraphStateData& src)
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashArray = NULL;
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Copy(src);
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_GraphStateData::Copy(const CFX_GraphStateData& src)
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LineCap = src.m_LineCap;
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashCount = src.m_DashCount;
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_DashArray) {
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_DashArray);
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashArray = NULL;
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashPhase = src.m_DashPhase;
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LineJoin = src.m_LineJoin;
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_MiterLimit = src.m_MiterLimit;
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LineWidth = src.m_LineWidth;
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_DashCount) {
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_DashArray = FX_Alloc(FX_FLOAT, m_DashCount);
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_DashArray) {
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(m_DashArray, src.m_DashArray, m_DashCount * sizeof(FX_FLOAT));
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_GraphStateData::~CFX_GraphStateData()
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_DashArray) {
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_DashArray);
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_GraphStateData::SetDashCount(int count)
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_DashArray) {
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_DashArray);
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashArray = NULL;
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashCount = count;
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (count == 0) {
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DashArray = FX_Alloc(FX_FLOAT, count);
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
655