SLNKDWF 2.11
svn path=/Slnkdwf/trunk/; revision=12487
This commit is contained in:
@@ -94,3 +94,18 @@ STDMETHODIMP CAbout::get_VersionString(BSTR* pVal)
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAbout::get_usTimer(DOUBLE* pVal)
|
||||
{
|
||||
LARGE_INTEGER currTime;
|
||||
LARGE_INTEGER frequency;
|
||||
(*pVal)=0;
|
||||
if (!QueryPerformanceFrequency(&frequency))
|
||||
return S_OK;
|
||||
if (!QueryPerformanceCounter(&currTime))
|
||||
return S_OK;
|
||||
|
||||
(*pVal) = ((double)currTime.QuadPart)*1000000/frequency.QuadPart;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
STDMETHOD(get_VersionMajor)(LONG* pVal);
|
||||
STDMETHOD(get_VersionMinor)(LONG* pVal);
|
||||
STDMETHOD(get_VersionString)(BSTR* pVal);
|
||||
STDMETHOD(get_usTimer)(DOUBLE* pVal);
|
||||
};
|
||||
|
||||
OBJECT_ENTRY_AUTO(__uuidof(About), CAbout)
|
||||
|
||||
@@ -39,7 +39,7 @@ void CSLNKContour::SetImpl(CSLNKContourImpl * pSLNKContour)
|
||||
m_dwgCenter->put_DwgY(dwgPt.m_y);
|
||||
};
|
||||
|
||||
STDMETHODIMP CSLNKContour::SetColor(ULONG rgb, BYTE Alpha /*=0*/)
|
||||
STDMETHODIMP CSLNKContour::SetColor(ULONG rgb, BYTE Alpha /*=255*/)
|
||||
{
|
||||
int b=rgb%256;
|
||||
int g=(rgb>>8)%256;
|
||||
|
||||
@@ -48,7 +48,7 @@ interface IWhipFile : IDispatch{
|
||||
[id(2), helpstring("method LoadStream")] HRESULT LoadStream([in] VARIANT EPlotStream);
|
||||
[id(3), helpstring("method SaveAs")] HRESULT SaveAs([in] BSTR WhipPath);
|
||||
[id(4), helpstring("method SetLabel")] HRESULT SetLabel([in] BSTR IdentLabel, [in] BSTR ExtraLabel);
|
||||
[id(5), helpstring("method SetColor")] HRESULT SetColor([in] BSTR IdentLabel, [in] ULONG rgb, [in, defaultvalue(0)] BYTE Alpha);
|
||||
[id(5), helpstring("method SetColor")] HRESULT SetColor([in] BSTR IdentLabel, [in] ULONG rgb, [in, defaultvalue(255)] BYTE Alpha);
|
||||
[id(8), helpstring("method SetLabelFont")] HRESULT SetLabelFont([in] BSTR FontName, [in] DOUBLE FontHeight, [in, defaultvalue(0)] DOUBLE FontHeightSymbols);
|
||||
[id(9), helpstring("method SetLabelPosition")] HRESULT SetLabelPosition([in, defaultvalue(1)] BYTE LabelPos);
|
||||
[propget, id(10), helpstring("method ContoursXML")] HRESULT ContoursXML([out, retval] BSTR* pVal);
|
||||
@@ -114,6 +114,7 @@ interface IAbout : IDispatch{
|
||||
[propget, id(5), helpstring("property VersionMajor")] HRESULT VersionMajor([out, retval] LONG* pVal);
|
||||
[propget, id(6), helpstring("property VersionMinor")] HRESULT VersionMinor([out, retval] LONG* pVal);
|
||||
[propget, id(7), helpstring("property VersionString")] HRESULT VersionString([out, retval] BSTR* pVal);
|
||||
[propget, id(8), helpstring("property usTimer")] HRESULT usTimer([out, retval] DOUBLE* pVal);
|
||||
};
|
||||
[
|
||||
object,
|
||||
@@ -222,7 +223,7 @@ interface IDWGPoint : IDispatch{
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface ISLNKContour : IDispatch{
|
||||
[id(2), helpstring("method SetColor")] HRESULT SetColor([in] ULONG rgb, [in, defaultvalue(0)] BYTE Alpha);
|
||||
[id(2), helpstring("method SetColor")] HRESULT SetColor([in] ULONG rgb, [in, defaultvalue(255)] BYTE Alpha);
|
||||
[id(3), helpstring("method SetUrl")] HRESULT SetUrl([in] BSTR Url, [in] BSTR FriendlyName);
|
||||
[propget, id(5), helpstring("property Area")] HRESULT Area([out, retval] DOUBLE* pVal);
|
||||
[propget, id(6), helpstring("property Extents")] HRESULT Extents([out, retval] IBoundingBox ** pVal);
|
||||
@@ -248,6 +249,7 @@ interface ISLNKSymbol : IDispatch{
|
||||
[propget, id(3), helpstring("property Rotation")] HRESULT Rotation([out, retval] LONG* pVal);
|
||||
[propput, id(3), helpstring("property Rotation")] HRESULT Rotation([in] LONG newVal);
|
||||
[propget, id(4), helpstring("property Contour")] HRESULT Contour([out, retval] ISLNKContour** pVal);
|
||||
[id(5), helpstring("method SetColor")] HRESULT SetColor([in] ULONG rgb, [in, defaultvalue(255)] BYTE Alpha);
|
||||
};
|
||||
[
|
||||
object,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Zorg dat versies alfabetisch altijd op elkaar volgen!
|
||||
#define SLNK_MAJOR_VERSION 2
|
||||
#define SLNK_MINOR_VERSION 10
|
||||
#define SLNK_MINOR_VERSION 11
|
||||
#define SLNK_BUILD_VERSION 0
|
||||
|
||||
// Define resource strings
|
||||
|
||||
@@ -74,3 +74,14 @@ STDMETHODIMP CSLNKSymbol::get_Contour(ISLNKContour** pVal)
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CSLNKSymbol::SetColor(ULONG rgb, BYTE Alpha /*=255*/)
|
||||
{
|
||||
int b=rgb%256;
|
||||
int g=(rgb>>8)%256;
|
||||
int r=(rgb>>16)%256;
|
||||
m_SLNKSymbol->m_Color.set(r, g, b, Alpha);
|
||||
m_SLNKSymbol->m_ColorSet = true;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ WT_Drawable *CSLNKSymbolDefinition::asBitmap(int pixeldx, int pixeldy, long pape
|
||||
}
|
||||
#endif
|
||||
|
||||
WT_Result CSLNKSymbolDefinition::serialize(WT_File & file)
|
||||
WT_Result CSLNKSymbolDefinition::serialize(WT_File & file, WT_Color pColor, BOOL pColorSet)
|
||||
{
|
||||
if (m_AsBitmap)
|
||||
{ // Wel even kopietje trekken omdat anders niet opnieuw getransformeerd wordt
|
||||
@@ -369,6 +369,13 @@ WT_Result CSLNKSymbolDefinition::serialize(WT_File & file)
|
||||
if (m_BuiltIn) // Die hebben alleen een bounding contour
|
||||
return WT_Result::Success;
|
||||
|
||||
// Vertrouw de huidige rendition niet! Het eerste lijntje van een symbool kan default wit verwachten (CO206.DWF)
|
||||
// Tijdens het serializen van het symbool hebben we niets met (desired)_rendition te maken
|
||||
if (pColorSet)
|
||||
pColor.serialize(file);
|
||||
else
|
||||
WT_Color(0,0,0).serialize(file); // Op de default zetten. TODO: Moet eigenlijk voor alle attributen
|
||||
|
||||
WT_Result result;
|
||||
// Open onze symbool DWF
|
||||
m_wtFile.set_file_mode(WT_File::File_Read);
|
||||
@@ -425,6 +432,11 @@ WT_Result CSLNKSymbolDefinition::serialize(WT_File & file)
|
||||
if (obj->object_id() == WT_Object::Color_ID)
|
||||
{ // Misschien een zwart-wit toggle doorvoeren? Of zelfs highlight?
|
||||
// m_iEPlotSection->get_PaperColor()
|
||||
if (pColorSet) // Hoeven we niet steeds weer te zetten
|
||||
{
|
||||
break;
|
||||
}
|
||||
//else gewoon naar de default doorvallen
|
||||
}
|
||||
if (obj->object_id() == WT_Object::Viewport_ID)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
WT_Logical_Point m_Center; // Wordt gezet bij berekenen boundingcontour
|
||||
double m_dwgScale;
|
||||
WT_Drawable *asBitmap(int pixeldx, int pixeldy, long paperColor);
|
||||
WT_Result serialize(WT_File & file);
|
||||
WT_Result serialize(WT_File & file, WT_Color pColor, BOOL pColorSet);
|
||||
WT_Result calculateBoundary(WT_Polygon &m_BoundingContour, WT_Transform *tm=NULL);
|
||||
|
||||
private:
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
CSLNKSymbolImpl::CSLNKSymbolImpl(void)
|
||||
{
|
||||
m_ColorSet = false;
|
||||
}
|
||||
|
||||
CSLNKSymbolImpl::~CSLNKSymbolImpl(void)
|
||||
@@ -21,6 +22,7 @@ CSLNKSymbolImpl::CSLNKSymbolImpl(double dwgX, double dwgY, CWhipFileState *State
|
||||
m_symbolName = "";
|
||||
m_Rotation = 0;
|
||||
m_Scale = 1.0;
|
||||
m_ColorSet = false;
|
||||
m_SLNKContour.m_parentWhipFileState = State;
|
||||
m_SLNKContour.m_fromSymbol=true;
|
||||
}
|
||||
@@ -80,9 +82,6 @@ WT_Result CSLNKSymbolImpl::serialize (WT_File & file, WT_Units & units,
|
||||
file.desired_rendition().line_weight() = WT_Line_Weight(0);
|
||||
}
|
||||
#endif
|
||||
// Vertrouw de huidige rendition niet! Het eerste lijntje van een symbool kan default wit verwachten (CO206.DWF)
|
||||
// Tijdens het serializen van het symbool hebben we niets met (desired)_rendition te maken
|
||||
WT_Color().serialize(file); // Op de default zetten. TODO: Moet eigenlijk voor alle attributen
|
||||
|
||||
double dx, dy;
|
||||
|
||||
@@ -133,7 +132,12 @@ WT_Result CSLNKSymbolImpl::serialize (WT_File & file, WT_Units & units,
|
||||
else
|
||||
#endif
|
||||
{ //Gewone vector versie
|
||||
symbdef->serialize(file);
|
||||
if (m_ColorSet && m_Color.rgba().m_rgb.a==0)
|
||||
{
|
||||
// Skip want toch onzichtbaar
|
||||
}
|
||||
else
|
||||
symbdef->serialize(file, m_Color, m_ColorSet);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -156,6 +160,8 @@ WT_Result CSLNKSymbolImpl::serialize (WT_File & file, WT_Units & units,
|
||||
// geroteerde symbolen overflow problemen)
|
||||
//
|
||||
|
||||
#undef BOUNDINGBOX_HERBEREKENEN
|
||||
#ifdef BOUNDINGBOX_HERBEREKENEN
|
||||
WT_Polygon pl;
|
||||
symbdef->calculateBoundary(pl, &SymbolTrans);
|
||||
if (pl.count()>0)
|
||||
@@ -163,6 +169,7 @@ WT_Result CSLNKSymbolImpl::serialize (WT_File & file, WT_Units & units,
|
||||
m_SLNKContour.set(pl.count(), pl.points(), true);
|
||||
}
|
||||
else // Builtin of bitmap
|
||||
#endif
|
||||
{
|
||||
m_SLNKContour.transform(SymbolTrans); // Pas op: de bounds zijn nu misschien nog verkeerd
|
||||
}
|
||||
|
||||
@@ -24,4 +24,6 @@ public:
|
||||
int m_Rotation;
|
||||
double m_Scale;
|
||||
CSLNKContourImpl m_SLNKContour;
|
||||
WT_Color m_Color;
|
||||
BOOL m_ColorSet;
|
||||
};
|
||||
|
||||
@@ -600,7 +600,7 @@ bool CWhipFile::GenerateSymbols(myWT_File &my_file)
|
||||
{
|
||||
double scale = m_State.m_contunits.application_to_dwf_transform()(0,0);
|
||||
// TODO: Echt uniek layernum (en URL num) bepalen
|
||||
my_file.desired_rendition().layer() = WT_Layer(my_file, 1000, "SLNK Symbols");
|
||||
my_file.desired_rendition().layer() = WT_Layer(my_file, 100000, "SLNK Symbols");
|
||||
|
||||
for (size_t i=0; i<m_State.m_SLNKSymbols.GetCount(); i++)
|
||||
{
|
||||
@@ -639,7 +639,7 @@ bool CWhipFile::GenerateSymbolLabels(myWT_File &my_file)
|
||||
clr.serialize(my_file); // Vertrouw niets. Expliciete serialize. Zie @@@
|
||||
|
||||
// TODO: Echt uniek layernum (en URL num) bepalen
|
||||
my_file.desired_rendition().layer() = WT_Layer(my_file, 1001, "SLNK Symbol Labels");
|
||||
my_file.desired_rendition().layer() = WT_Layer(my_file, 100001, "SLNK Symbol Labels");
|
||||
for (size_t i=0; i<m_State.m_SLNKSymbols.GetCount(); i++)
|
||||
{
|
||||
CSLNKSymbolImpl *symbol= m_State.m_SLNKSymbols[i];
|
||||
@@ -652,7 +652,7 @@ bool CWhipFile::GenerateSymbolLabels(myWT_File &my_file)
|
||||
WT_Transform wasTransform = my_file.heuristics().transform();
|
||||
WT_Boolean wasApplyTransform = my_file.heuristics().apply_transform();
|
||||
my_file.heuristics().set_apply_transform(WD_False); // Hebben we al rechtstreeks op de contour gedaan
|
||||
symbol->m_SLNKContour.SerializeLabel(my_file, CSLNKContourImpl::LABEL_OUTSIDEBOTTOM, fontheight, myDC);
|
||||
symbol->m_SLNKContour.SerializeLabel(my_file, CSLNKContourImpl::LABEL_OUTSIDEBOTTOM, fontheight, scale, myDC);
|
||||
// En transform weer terug
|
||||
my_file.heuristics().set_transform(wasTransform);
|
||||
my_file.heuristics().set_apply_transform(wasApplyTransform);
|
||||
@@ -680,7 +680,7 @@ bool CWhipFile::GenerateContouren(WT_File &my_planfile, myWT_File &my_file,
|
||||
WT_Object_Node current_node = my_file.desired_rendition().object_node();
|
||||
|
||||
// TODO: Echt uniek layernum (en URL num) bepalen
|
||||
my_file.desired_rendition().layer() = WT_Layer(my_file, 1002, "SLNK Contours");
|
||||
my_file.desired_rendition().layer() = WT_Layer(my_file, 100002, "SLNK Contours");
|
||||
|
||||
for (size_t i=0; i<m_State.m_SLNKContouren.GetCount(); i++)
|
||||
{
|
||||
@@ -708,7 +708,7 @@ bool CWhipFile::GenerateLabels(WT_File &my_planfile, myWT_File &my_file, double
|
||||
WT_Color keepColor = my_planfile.rendition().color();
|
||||
|
||||
// TODO: Echt uniek layernum (en URL num) bepalen
|
||||
my_file.desired_rendition().layer() = WT_Layer(my_file, 1003, "SLNK Labels");
|
||||
my_file.desired_rendition().layer() = WT_Layer(my_file, 100003, "SLNK Labels");
|
||||
|
||||
// Zet een DC op om bij 'Center' de afmetingen van de tekst te kunnen bepalen
|
||||
int fontheight= myRound(m_FontHeight * scale);
|
||||
@@ -729,7 +729,7 @@ bool CWhipFile::GenerateLabels(WT_File &my_planfile, myWT_File &my_file, double
|
||||
if (contour->m_contLabel.length()!=0 && contour->m_ExtraLabel != "")
|
||||
{ // We have got a proper label/contour
|
||||
// Alle teksten tekenen
|
||||
contour->SerializeLabel(my_file, m_LabelPos, fontheight, myDC);
|
||||
contour->SerializeLabel(my_file, m_LabelPos, fontheight, scale, myDC);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,7 +865,7 @@ STDMETHODIMP CWhipFile::SetLabel(BSTR IdentLabel, BSTR ExtraLabel)
|
||||
|
||||
// mei 2007: DEPRECATED
|
||||
// Lege Identlabel zet alle ruimtes op dezelfde kleur
|
||||
STDMETHODIMP CWhipFile::SetColor(BSTR IdentLabel, ULONG rgb, BYTE Alpha /*=0*/)
|
||||
STDMETHODIMP CWhipFile::SetColor(BSTR IdentLabel, ULONG rgb, BYTE Alpha /*=255*/)
|
||||
{
|
||||
try {
|
||||
for (size_t i=0; i<m_State.m_SLNKContouren.GetCount(); i++)
|
||||
|
||||
@@ -64,6 +64,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
STDMETHOD(SetColor)(ULONG rgb, BYTE Alpha);
|
||||
STDMETHOD(get_Scale)(DOUBLE* pVal);
|
||||
STDMETHOD(put_Scale)(DOUBLE newVal);
|
||||
STDMETHOD(get_Rotation)(LONG* pVal);
|
||||
|
||||
@@ -87,39 +87,39 @@ Subject 1.02: How do I find the distance from a point to a line?
|
||||
|
||||
Let the point be C (Cx,Cy) and the line be AB (Ax,Ay) to (Bx,By).
|
||||
Let P be the point of perpendicular projection of C on AB. The parameter
|
||||
r, which indicates P's position along AB, is computed by the dot product
|
||||
r, which indicates P's position along AB, is computed by the dot product
|
||||
of AC and AB divided by the square of the length of AB:
|
||||
|
||||
|
||||
(1) AC dot AB
|
||||
r = ---------
|
||||
r = ---------
|
||||
||AB||^2
|
||||
|
||||
|
||||
r has the following meaning:
|
||||
|
||||
|
||||
r=0 P = A
|
||||
r=1 P = B
|
||||
r<0 P is on the backward extension of AB
|
||||
r>1 P is on the forward extension of AB
|
||||
0<r<1 P is interior to AB
|
||||
|
||||
|
||||
The length of a line segment in d dimensions, AB is computed by:
|
||||
|
||||
|
||||
L = sqrt( (Bx-Ax)^2 + (By-Ay)^2 + ... + (Bd-Ad)^2)
|
||||
|
||||
so in 2D:
|
||||
|
||||
so in 2D:
|
||||
|
||||
L = sqrt( (Bx-Ax)^2 + (By-Ay)^2 )
|
||||
|
||||
|
||||
and the dot product of two vectors in d dimensions, U dot V is computed:
|
||||
|
||||
|
||||
D = (Ux * Vx) + (Uy * Vy) + ... + (Ud * Vd)
|
||||
|
||||
so in 2D:
|
||||
|
||||
D = (Ux * Vx) + (Uy * Vy)
|
||||
|
||||
|
||||
so in 2D:
|
||||
|
||||
D = (Ux * Vx) + (Uy * Vy)
|
||||
|
||||
So (1) expands to:
|
||||
|
||||
|
||||
(Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay)
|
||||
r = -------------------------------
|
||||
L^2
|
||||
@@ -131,7 +131,7 @@ Subject 1.02: How do I find the distance from a point to a line?
|
||||
|
||||
And the distance from A to P = r*L.
|
||||
|
||||
Use another parameter s to indicate the location along PC, with the
|
||||
Use another parameter s to indicate the location along PC, with the
|
||||
following meaning:
|
||||
s<0 C is left of AB
|
||||
s>0 C is right of AB
|
||||
@@ -155,7 +155,7 @@ Subject 1.02: How do I find the distance from a point to a line?
|
||||
//
|
||||
double px = ax + r*(bx-ax);
|
||||
double py = ay + r*(by-ay);
|
||||
//
|
||||
//
|
||||
double s = ((ay-cy)*(bx-ax)-(ax-cx)*(by-ay) ) / r_denomenator;
|
||||
|
||||
distanceLine = fabs(s)*sqrt(r_denomenator);
|
||||
@@ -196,10 +196,10 @@ Subject 1.02: How do I find the distance from a point to a line?
|
||||
|
||||
// Vind de hoek van de edge van ps die het dichts bij pt ligt
|
||||
// (het maakt ons niet uit of pt er binnen of buiten ligt)
|
||||
// A = P2Y - P1Y
|
||||
// B = P1X - P2X
|
||||
// C = P2X * P1Y - P2Y * P1X
|
||||
// DistToLine = Abs((A * PX + B * PY + C) / Sqr(A * A + B * B))
|
||||
// A = P2Y - P1Y
|
||||
// B = P1X - P2X
|
||||
// C = P2X * P1Y - P2Y * P1X
|
||||
// DistToLine = Abs((A * PX + B * PY + C) / Sqr(A * A + B * B))
|
||||
/*static*/ void CSLNKContourImpl::EdgeAngle(const WT_Logical_Point pt, const WT_Point_Set &ps, double &EdgeAngle, double &EdgeDistance)
|
||||
{
|
||||
double ptx = pt.m_x;
|
||||
@@ -217,11 +217,11 @@ Subject 1.02: How do I find the distance from a point to a line?
|
||||
pt1.m_x, pt1.m_y,
|
||||
pt2.m_x, pt2.m_y,
|
||||
DistSeg, DistLine);
|
||||
|
||||
|
||||
// Bij een 'ingedeukte' ruimte kan DistSeg == minDistSeg zijn. Dan wil
|
||||
// je juist een zo'n groot mogelijke afstand tot de virtuele projectie
|
||||
if (DistSeg < minDistSeg || (DistSeg == minDistSeg && DistLine > minDistLine))
|
||||
{
|
||||
{
|
||||
long dy = pt2.m_y - pt1.m_y;
|
||||
long dx = pt2.m_x - pt1.m_x;
|
||||
|
||||
@@ -243,7 +243,7 @@ Subject 1.02: How do I find the distance from a point to a line?
|
||||
EdgeDistance = minDistLine; //We rekenen met Seg maar projecteren uiteindelijk op Line
|
||||
}
|
||||
|
||||
// Signed Area needed for centroid!
|
||||
// Signed Area needed for centroid!
|
||||
// Negative is clockwise, Positve counterclockwise
|
||||
/*static*/double CSLNKContourImpl::DWFArea(const WT_Point_Set &pg)
|
||||
{
|
||||
@@ -322,7 +322,9 @@ WT_Logical_Point CSLNKContourImpl::LabelPosition(LABELPOS pos /*= LABEL_DEFAULT*
|
||||
return WT_Logical_Point((WT_Integer32)(ptx / dDWFArea6), (WT_Integer32)(pty / dDWFArea6));
|
||||
}
|
||||
|
||||
void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fontheight, HDC myDC)
|
||||
void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos,
|
||||
int fontheight, double scale,
|
||||
HDC myDC)
|
||||
{
|
||||
if (m_Color.rgba().m_rgb.a==255)
|
||||
{ // Volle achtergrond kleur
|
||||
@@ -345,7 +347,7 @@ void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fonthe
|
||||
tok.Replace("[BR]", "\n"); // We ondersteunen ook [BR] als newline
|
||||
|
||||
WT_Logical_Point ptTxt = LabelPosition(pos);
|
||||
// De wiskundige label-positie is bepaald. Nu iets corrigeren om
|
||||
// De wiskundige label-positie is bepaald. Nu iets corrigeren om
|
||||
// (afhankelijk van het font) mooier te zijn
|
||||
// Ook eventueel hori/vert centreren
|
||||
int width = -1; // Voor UBB code [c] van centreren
|
||||
@@ -361,7 +363,7 @@ void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fonthe
|
||||
{
|
||||
// Eerst een keer simuleren om grootte te bepalen
|
||||
ATLASSERT(myDC!=NULL);
|
||||
WT_Logical_Point ptBR = DrawOneLabel(my_file, pos, ptTxt, tok, fontheight, myDC);
|
||||
WT_Logical_Point ptBR = DrawOneLabel(my_file, ptTxt, tok, fontheight, scale, myDC);
|
||||
width = (ptBR.m_x - ptTxt.m_x);
|
||||
ptTxt.m_y -= (ptBR.m_y - ptTxt.m_y)/2 + fontheight*9/10;
|
||||
ptTxt.m_x += fontheight/4;
|
||||
@@ -371,7 +373,7 @@ void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fonthe
|
||||
{
|
||||
// Eerst een keer simuleren om grootte te bepalen
|
||||
ATLASSERT(myDC!=NULL);
|
||||
WT_Logical_Point ptBR = DrawOneLabel(my_file, pos, ptTxt, tok, fontheight, myDC);
|
||||
WT_Logical_Point ptBR = DrawOneLabel(my_file, ptTxt, tok, fontheight, scale, myDC);
|
||||
width = (ptBR.m_x - ptTxt.m_x);
|
||||
ptTxt.m_y -= fontheight;
|
||||
ptTxt.m_x -= (ptBR.m_x - ptTxt.m_x)/2;
|
||||
@@ -383,7 +385,7 @@ void CSLNKContourImpl::SerializeLabel(WT_File &my_file, LABELPOS pos, int fonthe
|
||||
if (!CSLNKContourImpl::PointInPolygon(ptTxt, *this))
|
||||
ptTxt = LabelPosition(CSLNKContourImpl::LABEL_DEFAULT);
|
||||
// Eerst een keer simuleren om grootte te bepalen
|
||||
WT_Logical_Point ptBR = DrawOneLabel(my_file, pos, ptTxt, tok, fontheight, myDC);
|
||||
WT_Logical_Point ptBR = DrawOneLabel(my_file, ptTxt, tok, fontheight, scale, myDC);
|
||||
width = (ptBR.m_x - ptTxt.m_x);
|
||||
ptTxt.m_x -= (ptBR.m_x - ptTxt.m_x)/2;
|
||||
ptTxt.m_y -= (ptBR.m_y - ptTxt.m_y)/2 + fontheight*9/10;
|
||||
@@ -400,7 +402,7 @@ pm.serialize(my_file);
|
||||
}
|
||||
|
||||
// Nu echt tekenen met width<>-2
|
||||
DrawOneLabel(my_file, pos, ptTxt, tok, fontheight, myDC, width);
|
||||
DrawOneLabel(my_file, ptTxt, tok, fontheight, scale, myDC, width);
|
||||
}
|
||||
|
||||
// Draw one (possibly multline) label
|
||||
@@ -409,15 +411,15 @@ pm.serialize(my_file);
|
||||
// Als width==-1 is centreren niet mogelijk/nodig
|
||||
// Als width>0 is centreren mogelijk via [c]
|
||||
WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
||||
LABELPOS pos,
|
||||
WT_Logical_Point ptTxt,
|
||||
CString tok,
|
||||
int fontheight,
|
||||
int fontheight,
|
||||
double scale,
|
||||
HDC myDC,
|
||||
int width/*=-2*/)// Voor centreren. Moet aanroeper al een keer bepaald hebben
|
||||
{
|
||||
long max_width=0; // Bepaal hiermee 'rechtsonder' van de tekst als myDC
|
||||
|
||||
|
||||
//TODO: UBB sluitcodes ondersteunen
|
||||
int curpos = 0;
|
||||
CString token = tok.Tokenize("\n", curpos);
|
||||
@@ -425,9 +427,12 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
||||
bool centering=false;
|
||||
while( token != "" )
|
||||
{
|
||||
// invariant (ook bij binnenkomst): ptTxt.m_y bevat het linksonderpunt van de huidige regel
|
||||
// uitgaande van fontheight. Bij [s] gebruik moeten we dus corrigeren
|
||||
//CString f(token);
|
||||
int skipextra = 0; // Extra skip bij underline
|
||||
long size=100;
|
||||
int thisLineHeight=fontheight; // mooie default
|
||||
|
||||
// Supported UBB-like codes:
|
||||
// [[This is literal text in square brackets]
|
||||
@@ -435,9 +440,10 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
||||
// [b]This text is bold
|
||||
// [u]This text is underline
|
||||
// [cFF00FF]This text is colored
|
||||
// [s50]This text is 50% sized
|
||||
// [s50]This text is 50% sized van standaard labelfont
|
||||
// [S800]This text is 800 height sized
|
||||
// Bovenstaand alleen voor de huidige regel
|
||||
// [c] Centreer alle regels binnen bounding box (anders links gealigned)
|
||||
// [c] Centreer alle(!) volgende regels binnen bounding box (anders links gealigned)
|
||||
while (token[0] == '[')
|
||||
{
|
||||
token.Delete(0);
|
||||
@@ -467,7 +473,7 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
||||
if (end==1)
|
||||
{
|
||||
token.Delete(0);
|
||||
if (width>0) centering = true;
|
||||
centering = true;
|
||||
break;
|
||||
}
|
||||
if (end >= 0)
|
||||
@@ -485,15 +491,21 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
||||
}
|
||||
case 's': // Size
|
||||
{
|
||||
BOOL bigS = (token[0]=='S');
|
||||
int end = token.Find(']');
|
||||
if (end >= 0)
|
||||
{
|
||||
if (sscanf(token, "s%d]", &size))
|
||||
token.Delete(0);
|
||||
if (sscanf(token, "%d]", &size))
|
||||
{
|
||||
int fh = myRound(double(size)*fontheight/100);
|
||||
ptTxt.m_y += (fontheight - fh);
|
||||
if (bigS)
|
||||
thisLineHeight = myRound(size * scale);
|
||||
else
|
||||
thisLineHeight = myRound(double(size)*fontheight/100);
|
||||
|
||||
ptTxt.m_y -= (thisLineHeight - fontheight); // Correctie op de invariant voor huidige regel
|
||||
if (width != -2)
|
||||
my_file.desired_rendition().font().height() = fh;
|
||||
my_file.desired_rendition().font().height() = thisLineHeight;
|
||||
}
|
||||
token.Delete(0, end);
|
||||
}
|
||||
@@ -511,7 +523,7 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
||||
RECT rc = { 0, 0, 0, 0};
|
||||
DrawText(myDC, token, token.GetLength(), &rc, DT_CALCRECT); // Grootte bepalen
|
||||
// Tekst horizontaal centreren
|
||||
horoffset = width/2 - MulDiv(rc.right*size/100,fontheight,FONT_SIZER)/2;
|
||||
horoffset = width/2 - MulDiv(rc.right,thisLineHeight,FONT_SIZER)/2;
|
||||
}
|
||||
WT_String txt;
|
||||
if (WT_String::is_ascii(token.GetLength(), token))
|
||||
@@ -543,7 +555,7 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
||||
|
||||
// Tekst horizontaal en verticaal centreren
|
||||
// ptRes.m_y += rc.bottom; halen we wel uit ptY
|
||||
max_width = max(max_width, MulDiv(rc.right,size,100));
|
||||
max_width = max(max_width, MulDiv(rc.right,thisLineHeight,fontheight));
|
||||
}
|
||||
|
||||
line ++;
|
||||
@@ -568,7 +580,7 @@ WT_Logical_Point CSLNKContourImpl::DrawOneLabel(WT_File &my_file,
|
||||
- (m_fromSymbol) Symbool (al dan niet met m_Key gedefinieerd)
|
||||
- Ingebouwd (star)
|
||||
- Gedefinieerd (bounding octagon)
|
||||
|
||||
|
||||
Als solidOnly dan alleen als alpha==255 en een label (wel herkend)
|
||||
****************************************************************************/
|
||||
WT_Result CSLNKContourImpl::serialize(WT_File & file, BOOL solidOnly)
|
||||
@@ -588,7 +600,7 @@ WT_Result CSLNKContourImpl::serialize(WT_File & file, BOOL solidOnly)
|
||||
{ // We have got a proper label/contour
|
||||
if (m_fromSymbol ||
|
||||
(m_Color.rgba().m_rgb.a==255 && solidOnly) ||
|
||||
(m_Color.rgba().m_rgb.a<255 && !solidOnly))
|
||||
(m_Color.rgba().m_rgb.a<255 && !solidOnly))
|
||||
{
|
||||
// Start a node for 'everything'. Dit is wat we concreet teruggeven bij klikken in de tekening
|
||||
WT_Object_Node my_node(file,m_next_node_num++,m_Key);
|
||||
@@ -617,11 +629,11 @@ WT_Result CSLNKContourImpl::serialize(WT_File & file, BOOL solidOnly)
|
||||
WT_RGBA32 rgba[3];
|
||||
WT_RGBA32 clr(this.m_Color.rgba());
|
||||
rgba[0] = clr;
|
||||
rgba[1] = WT_RGBA32 (clr.m_rgb.r+64>255?255:clr.m_rgb.r+64,
|
||||
clr.m_rgb.g+64>255?255:clr.m_rgb.g+64,
|
||||
rgba[1] = WT_RGBA32 (clr.m_rgb.r+64>255?255:clr.m_rgb.r+64,
|
||||
clr.m_rgb.g+64>255?255:clr.m_rgb.g+64,
|
||||
clr.m_rgb.b+64>255?255:clr.m_rgb.b+64, clr.m_rgb.a);
|
||||
rgba[1] = WT_RGBA32 (clr.m_rgb.r-64<0?0:clr.m_rgb.r-64,
|
||||
clr.m_rgb.g-64<0?0:clr.m_rgb.g-64,
|
||||
rgba[1] = WT_RGBA32 (clr.m_rgb.r-64<0?0:clr.m_rgb.r-64,
|
||||
clr.m_rgb.g-64<0?0:clr.m_rgb.g-64,
|
||||
clr.m_rgb.b-64<0?0:clr.m_rgb.b-64, clr.m_rgb.a);
|
||||
rgba[2] = rgba[1];
|
||||
|
||||
|
||||
@@ -54,12 +54,13 @@ public:
|
||||
WT_Logical_Point LabelPosition(LABELPOS pos = LABEL_DEFAULT);
|
||||
void SerializeLabel(WT_File &my_file, LABELPOS pos,
|
||||
int fontheight,
|
||||
double scale,
|
||||
HDC myDC);
|
||||
WT_Logical_Point DrawOneLabel(WT_File &my_file,
|
||||
LABELPOS pos,
|
||||
WT_Logical_Point ptTxt,
|
||||
CString tok,
|
||||
int fontheight,
|
||||
double scale,
|
||||
HDC myDC, int width=-2);
|
||||
|
||||
static WT_Integer32 m_next_node_num;
|
||||
|
||||
@@ -62,21 +62,22 @@ STDMETHODIMP CWhip2DCImpl::Load(HDC hDC, CEPlotSectionImpl *EPlotStream,
|
||||
m_State.m_mul=0;
|
||||
my_input_file.set_file_mode(WT_File::File_Read);
|
||||
|
||||
if (0) { // altijd 'gewoon' recht rekenen
|
||||
if (m_State.m_lRotation != 0)
|
||||
{
|
||||
WT_Logical_Point lCenter(0,0);
|
||||
WT_Transform trans(lCenter, 1.0, 1.0, m_State.m_lRotation);
|
||||
my_input_file.heuristics().set_transform(trans);
|
||||
m_State.m_Trans = WT_Transform(lCenter, 1.0, 1.0, m_State.m_lRotation);
|
||||
my_input_file.heuristics().set_transform(m_State.m_Trans);
|
||||
my_input_file.heuristics().set_apply_transform(true);
|
||||
my_input_file.rendition().font().rotation() = MulDiv(m_State.m_lRotation,16384,90);
|
||||
}
|
||||
|
||||
}
|
||||
WT_Result result;
|
||||
if (my_input_file.open() != WT_Result::Success)
|
||||
throw myCString("\nCWhip2DCImpl::Load: unable to open file '%s'", m_WhipPath.ascii());
|
||||
|
||||
BOOL ViewportDone = FALSE;
|
||||
double dScale = 0.0;
|
||||
double dScale = 1.0;
|
||||
// Doorloop de DWF totdat alles gelezen is
|
||||
// Stop als we een view/viewport hebben (dan wordt m_mul gezet) tenzij maximize, dan lezen we alles
|
||||
while ((result = my_input_file.process_next_object()) == WT_Result::Success
|
||||
@@ -92,6 +93,21 @@ STDMETHODIMP CWhip2DCImpl::Load(HDC hDC, CEPlotSectionImpl *EPlotStream,
|
||||
WT_View *view = (WT_View *)my_input_file.current_object();
|
||||
if (!maximize)
|
||||
m_State.SetExtents(view->view()); // m_mul wordt gezet en de loop eindigt
|
||||
else
|
||||
{
|
||||
// 'Move' alles naar het midden van het eerste kwadrant
|
||||
// Anders kunnen we later bij bounds bepaling overflow krijgen
|
||||
|
||||
// Waar roteren we eigenlijk omheen?
|
||||
WT_Logical_Point lCenter;
|
||||
if (m_State.m_lRotation==0||m_State.m_lRotation==90||m_State.m_lRotation==180||m_State.m_lRotation==270)
|
||||
lCenter = WT_Logical_Point(INT_MAX/2,INT_MAX/2);
|
||||
else
|
||||
lCenter = WT_Logical_Point(0, 0);
|
||||
|
||||
m_State.m_Trans = WT_Transform (lCenter, 1.0, 1.0, m_State.m_lRotation);
|
||||
my_input_file.heuristics().set_transform(m_State.m_Trans);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (obj->object_id() == WT_Object::Viewport_ID)
|
||||
@@ -140,6 +156,7 @@ STDMETHODIMP CWhip2DCImpl::Load(HDC hDC, CEPlotSectionImpl *EPlotStream,
|
||||
}
|
||||
}
|
||||
result = my_input_file.close(); // closing Input file.
|
||||
|
||||
if (m_State.m_mul==0 && result == WT_Result::Success)
|
||||
{ // Blijkbaar geen view en/of viewport gevonden
|
||||
m_State.SetExtents(m_State.m_MinMax); // Die hebben we dan in de vorige slag wel bepaald
|
||||
@@ -223,9 +240,7 @@ STDMETHODIMP CWhip2DCImpl::Paint(VARIANT_BOOL forceBW)
|
||||
|
||||
if (m_State.m_lRotation != 0) // Tijdens het laden roteren
|
||||
{
|
||||
WT_Logical_Point lCenter(0,0);
|
||||
WT_Transform trans(lCenter, 1.0, 1.0, m_State.m_lRotation);
|
||||
my_input_file.heuristics().set_transform(trans);
|
||||
my_input_file.heuristics().set_transform(m_State.m_Trans);
|
||||
my_input_file.heuristics().set_apply_transform(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
BOOL m_Maximize;
|
||||
BOOL m_centerImage;
|
||||
long m_lRotation;
|
||||
WT_Transform m_Trans; // Voor tijdens rotatie
|
||||
double m_mul; // schaal onze DWF-coordinaten naar bitmap coordinaten
|
||||
|
||||
CSize m_Size;
|
||||
|
||||
0
Whiptk702/.gitignore
vendored
0
Whiptk702/.gitignore
vendored
720
Whiptk702/ellipse.cpp
Normal file
720
Whiptk702/ellipse.cpp
Normal file
@@ -0,0 +1,720 @@
|
||||
// Copyright (c) 1996-2001 by Autodesk, Inc.
|
||||
//
|
||||
// By using this code, you are agreeing to the terms and conditions of
|
||||
// the License Agreement included in the documentation for this code.
|
||||
//
|
||||
// AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AS TO THE CORRECTNESS
|
||||
// OF THIS CODE OR ANY DERIVATIVE WORKS WHICH INCORPORATE IT. AUTODESK
|
||||
// PROVIDES THE CODE ON AN "AS-IS" BASIS AND EXPLICITLY DISCLAIMS ANY
|
||||
// LIABILITY, INCLUDING CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
|
||||
// OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
|
||||
//
|
||||
// Use, duplication, or disclosure by the U.S. Government is subject to
|
||||
// restrictions set forth in FAR 52.227-19 (Commercial Computer Software
|
||||
// Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
|
||||
// Data and Computer Software), as applicable.
|
||||
//
|
||||
// $Header: /NewRoot/DWF Toolkit/v6/develop/global/src/dwf/whiptk/ellipse.cpp 1 9/12/04 8:52p Evansg $
|
||||
|
||||
#include "whiptk/pch.h"
|
||||
#include "whiptk/wversion.h"
|
||||
|
||||
const double PI = 3.14159265358979323846;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Object::WT_ID WT_Filled_Ellipse::object_id() const
|
||||
{
|
||||
return Filled_Ellipse_ID;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Object::WT_ID WT_Outline_Ellipse::object_id() const
|
||||
{
|
||||
return Outline_Ellipse_ID;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#if DESIRED_CODE(WHIP_OUTPUT)
|
||||
WT_Result WT_Filled_Ellipse::serialize(WT_File & file) const
|
||||
{
|
||||
return WT_Ellipse::serialize (file, WD_True);
|
||||
}
|
||||
#else
|
||||
WT_Result WT_Filled_Ellipse::serialize(WT_File &) const
|
||||
{
|
||||
return WT_Result::Success;
|
||||
}
|
||||
#endif // DESIRED_CODE()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#if DESIRED_CODE(WHIP_OUTPUT)
|
||||
WT_Result WT_Outline_Ellipse::serialize(WT_File & file) const
|
||||
{
|
||||
return WT_Ellipse::serialize (file, WD_False);
|
||||
}
|
||||
#else
|
||||
WT_Result WT_Outline_Ellipse::serialize(WT_File &) const
|
||||
{
|
||||
return WT_Result::Success;
|
||||
}
|
||||
#endif // DESIRED_CODE()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#if DESIRED_CODE(WHIP_OUTPUT)
|
||||
WT_Result WT_Ellipse::serialize(WT_File & file, WT_Boolean filled) const
|
||||
{
|
||||
WD_CHECK (file.dump_delayed_drawable());
|
||||
|
||||
// TODO: Check rendition incarnation
|
||||
|
||||
// Attributes that Filled_Ellipses care about:
|
||||
// color, line weight, line cap, line join,
|
||||
// line pattern, fill mode, visibility, URL
|
||||
// layer
|
||||
|
||||
WT_Integer32 parts_to_sync = WT_Rendition::Color_Bit |
|
||||
// WT_Rendition::Color_Map_Bit |
|
||||
// WT_Rendition::Fill_Bit |
|
||||
WT_Rendition::Fill_Pattern_Bit |
|
||||
WT_Rendition::Merge_Control_Bit |
|
||||
WT_Rendition::BlockRef_Bit |
|
||||
WT_Rendition::Visibility_Bit |
|
||||
// WT_Rendition::Marker_Size_Bit |
|
||||
// WT_Rendition::Marker_Symbol_Bit |
|
||||
WT_Rendition::URL_Bit |
|
||||
WT_Rendition::Viewport_Bit |
|
||||
WT_Rendition::Layer_Bit |
|
||||
WT_Rendition::Object_Node_Bit;
|
||||
|
||||
|
||||
if (filled)
|
||||
{
|
||||
if (!file.rendition().fill().fill())
|
||||
{
|
||||
file.desired_rendition().fill() = WD_True;
|
||||
parts_to_sync |= WT_Rendition::Fill_Bit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parts_to_sync |= WT_Rendition::Line_Weight_Bit |
|
||||
WT_Rendition::Pen_Pattern_Bit |
|
||||
WT_Rendition::Line_Pattern_Bit |
|
||||
WT_Rendition::Dash_Pattern_Bit |
|
||||
WT_Rendition::Line_Style_Bit;
|
||||
|
||||
if (file.rendition().fill().fill())
|
||||
{
|
||||
file.desired_rendition().fill() = WD_False;
|
||||
parts_to_sync |= WT_Rendition::Fill_Bit;
|
||||
}
|
||||
}
|
||||
|
||||
WD_CHECK (file.desired_rendition().sync(file, parts_to_sync));
|
||||
|
||||
if (file.heuristics().apply_transform())
|
||||
((WT_Filled_Ellipse *)this)->transform(file.heuristics().transform()); // Cast "this" from const to alterable
|
||||
|
||||
if (file.heuristics().allow_binary_data())
|
||||
{
|
||||
WT_Logical_Point relpos = file.update_current_point(m_position);
|
||||
|
||||
// Binary output
|
||||
if (m_major != m_minor)
|
||||
{
|
||||
// output as Ellipse
|
||||
WD_CHECK (file.write ((WT_Byte)'e'));
|
||||
WD_CHECK (file.write (1, &relpos));
|
||||
WD_CHECK (file.write (m_major));
|
||||
WD_CHECK (file.write (m_minor));
|
||||
WD_CHECK (file.write (m_start));
|
||||
WD_CHECK (file.write ((WT_Unsigned_Integer16)(m_end & 0xFFFF)));
|
||||
return file.write (m_tilt);
|
||||
}
|
||||
else if (m_start != m_end)
|
||||
{
|
||||
// Output a 32 bit partial circle
|
||||
|
||||
// merge any ellipse tilt into the circle angles
|
||||
long start = ((long)m_start + (long)m_tilt) & 0x0000FFFF;
|
||||
long end = ((long)m_end + (long)m_tilt) & 0x0000FFFF;
|
||||
|
||||
WD_CHECK (file.write ((WT_Byte)0x92));
|
||||
WD_CHECK (file.write (1, &relpos));
|
||||
WD_CHECK (file.write (m_major));
|
||||
WD_CHECK (file.write ((WT_Unsigned_Integer16)start));
|
||||
return file.write ((WT_Unsigned_Integer16)end);
|
||||
}
|
||||
else if (WD_fits_in_short (relpos.m_x) && WD_fits_in_short (relpos.m_y) &&
|
||||
WD_fits_in_short (m_major))
|
||||
{
|
||||
// Output a 16 bit relative full circle
|
||||
WT_Logical_Point_16 tmp_point;
|
||||
tmp_point = relpos;
|
||||
|
||||
WD_CHECK (file.write ((WT_Byte)0x12));
|
||||
WD_CHECK (file.write (1, &tmp_point));
|
||||
return file.write ((WT_Integer16)m_major);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Output a 32 bit relative full circle
|
||||
WD_CHECK (file.write ((WT_Byte)'r'));
|
||||
WD_CHECK (file.write (1, &relpos));
|
||||
return file.write (m_major);
|
||||
}
|
||||
} // allow binary data
|
||||
else
|
||||
{
|
||||
// ASCII only output -----------------------
|
||||
WD_CHECK (file.write_geom_tab_level());
|
||||
|
||||
if (m_major != m_minor)
|
||||
{
|
||||
// output as Ellipse in ASCII
|
||||
|
||||
if ((m_start != m_end) || m_tilt)
|
||||
{
|
||||
// Full description of an ellipse
|
||||
WD_CHECK (file.write ("(Ellipse "));
|
||||
WD_CHECK (file.write_ascii (m_position));
|
||||
WD_CHECK (file.write ((WT_Byte) ' '));
|
||||
|
||||
WD_CHECK (file.write_ascii (m_major));
|
||||
WD_CHECK (file.write ((WT_Byte) ','));
|
||||
WD_CHECK (file.write_ascii (m_minor));
|
||||
WD_CHECK (file.write ((WT_Byte) ' '));
|
||||
|
||||
WD_CHECK (file.write_ascii (m_start));
|
||||
WD_CHECK (file.write ((WT_Byte) ','));
|
||||
WD_CHECK (file.write_ascii (m_end));
|
||||
WD_CHECK (file.write ((WT_Byte) ' '));
|
||||
|
||||
WD_CHECK (file.write_ascii (m_tilt));
|
||||
|
||||
return file.write((WT_Byte) ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// Basic description of an ellipse
|
||||
WD_CHECK (file.write ("E "));
|
||||
WD_CHECK (file.write_ascii (1, &m_position));
|
||||
WD_CHECK (file.write ((WT_Byte) ' '));
|
||||
|
||||
WD_CHECK (file.write_ascii (m_major));
|
||||
WD_CHECK (file.write ((WT_Byte) ','));
|
||||
return file.write_ascii (m_minor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// merge any ellipse tilt into the circle angles
|
||||
long start = ((long)m_start + (long)m_tilt) & 0x0000FFFF;
|
||||
long end = ((long)m_end + (long)m_tilt) & 0x0000FFFF;
|
||||
|
||||
// Output a circle in ASCII
|
||||
if (start != end)
|
||||
{
|
||||
// Full description of the circle/arc
|
||||
WD_CHECK (file.write ("(Circle "));
|
||||
WD_CHECK (file.write_ascii (m_position));
|
||||
WD_CHECK (file.write ((WT_Byte) ' '));
|
||||
WD_CHECK (file.write_ascii (m_major));
|
||||
|
||||
WD_CHECK (file.write ((WT_Byte) ' '));
|
||||
WD_CHECK (file.write_ascii (start));
|
||||
WD_CHECK (file.write ((WT_Byte) ','));
|
||||
WD_CHECK (file.write_ascii (end));
|
||||
|
||||
return file.write((WT_Byte) ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// Basic circle
|
||||
WD_CHECK (file.write ("R "));
|
||||
WD_CHECK (file.write_ascii (m_position));
|
||||
WD_CHECK (file.write ((WT_Byte) ' '));
|
||||
return file.write_ascii (m_major);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
WT_Result WT_Ellipse::serialize(WT_File &, WT_Boolean) const
|
||||
{
|
||||
return WT_Result::Success;
|
||||
}
|
||||
#endif // DESIRED_CODE()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
bool containsAngle(double angle, double angleStart, double angleEnd)
|
||||
{
|
||||
// get the orientation
|
||||
bool isCCW = angleStart < angleEnd;
|
||||
|
||||
// put the supplied parameter value on the extent side of the start angle
|
||||
if (isCCW)
|
||||
{
|
||||
while (angle < angleStart)
|
||||
angle += 2.0*PI;
|
||||
while (angle- 2.0*PI > angleStart)
|
||||
angle -= 2.0*PI;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (angle > angleStart)
|
||||
angle -= 2.0*PI;
|
||||
while (angle+2.0*PI < angleStart)
|
||||
angle += 2.0*PI;
|
||||
}
|
||||
|
||||
// do the range check
|
||||
if (isCCW)
|
||||
{
|
||||
// normal orientation
|
||||
if (angle >= angleStart && angle <= angleEnd)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// reversed orientation
|
||||
if (angle >= angleEnd && angle <= angleStart)
|
||||
return true;
|
||||
}
|
||||
|
||||
// not in range
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void WT_Ellipse::update_bounds(WT_File * file)
|
||||
{
|
||||
//Bounds algorithm lifted and ported from Kona
|
||||
|
||||
double maj = major();
|
||||
double min = minor();
|
||||
|
||||
double ang = tilt_radian();
|
||||
double csa = cos(ang);
|
||||
double sna = sin(ang);
|
||||
|
||||
double ax = maj * csa;
|
||||
double bx = min * sna;
|
||||
double ay = maj * sna;
|
||||
double by = min * csa;
|
||||
double xmax = sqrt(ax*ax + bx*bx);
|
||||
double ymax = sqrt(ay*ay + by*by);
|
||||
|
||||
double asValue = start_radian();;
|
||||
double css = cos(asValue);
|
||||
double sns = sin(asValue);
|
||||
double xs = ax*css - bx*sns;
|
||||
double ys = ay*css + by*sns;
|
||||
|
||||
double ae = end_radian();
|
||||
double cse = cos(ae);
|
||||
double sne = sin(ae);
|
||||
double xe = ax*cse - bx*sne;
|
||||
double ye = ay*cse + by*sne;
|
||||
|
||||
WT_Drawable::update_bounds(WT_Logical_Point((int)xs+m_position.m_x,(int)ys+m_position.m_y), file);
|
||||
WT_Drawable::update_bounds(WT_Logical_Point(((int)xs)+m_position.m_x+1,((int)ys)+m_position.m_y+1), file);
|
||||
WT_Drawable::update_bounds(WT_Logical_Point((int)xe+m_position.m_x,(int)ye+m_position.m_y), file);
|
||||
WT_Drawable::update_bounds(WT_Logical_Point(((int)xe)+m_position.m_x+1,((int)ye)+m_position.m_y+1), file);
|
||||
|
||||
double asnorm = atan2(sns, css);
|
||||
double aenorm = ae + (asnorm - asValue);
|
||||
|
||||
double txmax = atan2(-min*sna, maj*csa);
|
||||
double txmin = txmax - PI;
|
||||
if (txmin <= -PI)
|
||||
txmin += 2.0*PI;
|
||||
|
||||
if (containsAngle(txmax, asnorm, aenorm))
|
||||
WT_Drawable::update_bounds(WT_Logical_Point(((int)xmax)+m_position.m_x+1, ((int)ys)+m_position.m_y+1), file);
|
||||
if (containsAngle(txmin, asnorm, aenorm))
|
||||
WT_Drawable::update_bounds(WT_Logical_Point((int)-xmax+m_position.m_x, (int)ys+m_position.m_y), file);
|
||||
|
||||
double tymax = atan2(min*csa, maj*sna);
|
||||
double tymin = tymax - PI;
|
||||
if (tymin <= -PI)
|
||||
tymin += 2.0*PI;
|
||||
|
||||
if (containsAngle(tymax, asnorm, aenorm))
|
||||
WT_Drawable::update_bounds(WT_Logical_Point(((int)xs)+m_position.m_x+1, ((int)ymax)+m_position.m_y+1), file);
|
||||
if (containsAngle(tymin, asnorm, aenorm))
|
||||
WT_Drawable::update_bounds(WT_Logical_Point((int)xs+m_position.m_x, (int)-ymax+m_position.m_y), file);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Result WT_Ellipse::materialize(WT_Opcode const & opcode, WT_File & file)
|
||||
{
|
||||
WT_Logical_Point tmp_point;
|
||||
|
||||
switch (opcode.type())
|
||||
{
|
||||
case WT_Opcode::Single_Byte:
|
||||
{
|
||||
switch (opcode.token()[0])
|
||||
{
|
||||
case 'E':
|
||||
{
|
||||
// Ellipse, single-byte full ASCII
|
||||
switch (m_stage)
|
||||
{
|
||||
case Get_Position: WD_CHECK (file.read_ascii (m_position));
|
||||
m_stage = Get_Major;
|
||||
case Get_Major: WD_CHECK (file.read_ascii (tmp_point));
|
||||
m_major = tmp_point.m_x;
|
||||
m_minor = tmp_point.m_y;
|
||||
m_stage = Completed;
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
}
|
||||
|
||||
// Note: for full ASCII we *don't* de-relativize since we already have absolute coords.
|
||||
} break;
|
||||
case 'e':
|
||||
{
|
||||
// Ellipse, binary, long relative coordinates
|
||||
switch (m_stage)
|
||||
{
|
||||
case Get_Position: WD_CHECK (file.read (1, &m_position));
|
||||
m_stage = Get_Major;
|
||||
case Get_Major: WD_CHECK (file.read (m_major));
|
||||
m_stage = Get_Minor;
|
||||
case Get_Minor: WD_CHECK (file.read (m_minor));
|
||||
m_stage = Get_Start;
|
||||
case Get_Start: WD_CHECK (file.read (m_start));
|
||||
m_stage = Get_End;
|
||||
case Get_End: WT_Unsigned_Integer16 tmp;
|
||||
WD_CHECK (file.read (tmp));
|
||||
m_end = tmp;
|
||||
m_stage = Get_Tilt;
|
||||
case Get_Tilt: WD_CHECK (file.read (m_tilt));
|
||||
m_stage = Completed;
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
}
|
||||
|
||||
// convert from relative to absolute, transform if appropriate
|
||||
m_position = file.de_update_current_point(m_position);
|
||||
} break;
|
||||
case 'R':
|
||||
{
|
||||
// Basic Circle, Ascii
|
||||
switch (m_stage)
|
||||
{
|
||||
case Get_Position: WD_CHECK (file.read_ascii (m_position));
|
||||
m_stage = Get_Major;
|
||||
case Get_Major: WD_CHECK (file.read_ascii (m_major));
|
||||
m_minor = m_major;
|
||||
m_start = 0;
|
||||
m_end = 0;
|
||||
m_tilt = 0;
|
||||
m_stage = Completed;
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
}
|
||||
// Note: for full ASCII we *don't* de-relativize since we already have absolute coords.
|
||||
} break;
|
||||
case 'r':
|
||||
{
|
||||
// Full Circle, long relative coordinates
|
||||
switch (m_stage)
|
||||
{
|
||||
case Get_Position: WD_CHECK (file.read (1, &m_position));
|
||||
m_stage = Get_Major;
|
||||
case Get_Major: WD_CHECK (file.read (m_major));
|
||||
m_minor = m_major;
|
||||
m_start = 0;
|
||||
m_end = 0x00010000;
|
||||
m_tilt = 0;
|
||||
m_stage = Completed;
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
}
|
||||
|
||||
// convert from relative to absolute, transform if appropriate
|
||||
m_position = file.de_update_current_point(m_position);
|
||||
} break;
|
||||
case 0x12: // Ctrl-R
|
||||
{
|
||||
// Full Circle, short relative coordinates
|
||||
WT_Logical_Point_16 position;
|
||||
WT_Unsigned_Integer16 radius;
|
||||
|
||||
switch (m_stage)
|
||||
{
|
||||
case Get_Position: WD_CHECK (file.read (1, &position));
|
||||
m_position = position;
|
||||
m_stage = Get_Major;
|
||||
case Get_Major: WD_CHECK (file.read (radius));
|
||||
m_major = m_minor = radius;
|
||||
m_start = 0;
|
||||
m_end = 0x00010000;
|
||||
m_tilt = 0;
|
||||
m_stage = Completed;
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
}
|
||||
|
||||
// convert from relative to absolute, transform if appropriate
|
||||
m_position = file.de_update_current_point(m_position);
|
||||
} break;
|
||||
case 0x92: // X-Ctrl-R
|
||||
{
|
||||
// Partial or Full Circle, long relative coordinates, short angles
|
||||
switch (m_stage)
|
||||
{
|
||||
case Get_Position: WD_CHECK (file.read (1, &m_position));
|
||||
m_stage = Get_Major;
|
||||
case Get_Major: WD_CHECK (file.read (m_major));
|
||||
m_minor = m_major;
|
||||
m_stage = Get_Start;
|
||||
case Get_Start: WD_CHECK (file.read (m_start));
|
||||
m_stage = Get_End;
|
||||
case Get_End: WT_Unsigned_Integer16 tmp;
|
||||
WD_CHECK (file.read (tmp));
|
||||
m_end = tmp;
|
||||
m_stage = Completed;
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
}
|
||||
|
||||
// convert from relative to absolute, transform if appropriate
|
||||
m_position = file.de_update_current_point(m_position);
|
||||
} break;
|
||||
default:
|
||||
return WT_Result::Opcode_Not_Valid_For_This_Object;
|
||||
// break;
|
||||
} // switch
|
||||
} break;
|
||||
case WT_Opcode::Extended_ASCII:
|
||||
{
|
||||
if (!strcmp((char const *) opcode.token(), "(Circle"))
|
||||
{
|
||||
// Partial or Full Circle, absolute coordinates, short angles
|
||||
switch (m_stage)
|
||||
{
|
||||
case Get_Position: WD_CHECK (file.read_ascii (m_position));
|
||||
m_stage = Get_Major;
|
||||
case Get_Major: WD_CHECK (file.read_ascii (m_major));
|
||||
m_minor = m_major;
|
||||
m_stage = Get_Start;
|
||||
case Get_Start: WD_CHECK (file.read_ascii (tmp_point));
|
||||
if (tmp_point.m_x < 0 || tmp_point.m_y < 0)
|
||||
return WT_Result::Corrupt_File_Error;
|
||||
m_start = (WT_Unsigned_Integer16)(tmp_point.m_x & 0XFFFF);
|
||||
m_end = tmp_point.m_y & 0x0001FFFF;
|
||||
m_stage = Get_Close_Paren;
|
||||
case Get_Close_Paren:
|
||||
WD_CHECK (opcode.skip_past_matching_paren(file));
|
||||
m_stage = Completed;
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
}
|
||||
// Note: for full ASCII we *don't* de-relativize since we already have absolute coords.
|
||||
}
|
||||
else if (!strcmp((char const *) opcode.token(), "(Ellipse"))
|
||||
{
|
||||
// Ellipse, single-byte full ASCII
|
||||
|
||||
switch (m_stage)
|
||||
{
|
||||
case Get_Position: WD_CHECK (file.read_ascii (m_position));
|
||||
m_stage = Get_Major;
|
||||
case Get_Major: WD_CHECK (file.read_ascii (tmp_point));
|
||||
m_major = tmp_point.m_x;
|
||||
m_minor = tmp_point.m_y;
|
||||
m_stage = Get_Start;
|
||||
case Get_Start: WD_CHECK (file.read_ascii (tmp_point));
|
||||
if (tmp_point.m_x < 0 || tmp_point.m_y < 0)
|
||||
return WT_Result::Corrupt_File_Error;
|
||||
m_start = (WT_Unsigned_Integer16)(tmp_point.m_x & 0XFFFF);
|
||||
m_end = tmp_point.m_y & 0x0001FFFF;
|
||||
m_stage = Get_Tilt;
|
||||
case Get_Tilt: WD_CHECK (file.read_ascii (m_tilt));
|
||||
m_stage = Get_Close_Paren;
|
||||
case Get_Close_Paren:
|
||||
WD_CHECK (opcode.skip_past_matching_paren(file));
|
||||
m_stage = Completed;
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
}
|
||||
// Note: for full ASCII we *don't* de-relativize since we already have absolute coords.
|
||||
}
|
||||
else
|
||||
return WT_Result::Opcode_Not_Valid_For_This_Object;
|
||||
} break;
|
||||
case WT_Opcode::Extended_Binary:
|
||||
default:
|
||||
{
|
||||
return WT_Result::Opcode_Not_Valid_For_This_Object;
|
||||
} break;
|
||||
} // switch
|
||||
|
||||
if (file.heuristics().apply_transform())
|
||||
transform(file.heuristics().transform());
|
||||
|
||||
m_materialized = WD_True;
|
||||
|
||||
if (file.rendition().drawing_info().decimal_revision() <= WHIP20_DWF_FILE_VERSION)
|
||||
{
|
||||
// Note that in old versions, if m_start == m_end this is
|
||||
// a null ellipse/circle that shouldn't be drawn. In this case
|
||||
// we leave both m_start and m_end the same since Heidi knows not
|
||||
// to draw such a case.
|
||||
if (m_start == m_end)
|
||||
return WT_Result::Success;
|
||||
|
||||
// In old versions, a complete circle was when m_end was one less than m_start.
|
||||
// Adjust for the current definition which is that a complete circle is when
|
||||
// they are the same value. (If you want a null circle, just don't put it
|
||||
// in the DWF file, stupid!).
|
||||
if (m_end < 0x00010000)
|
||||
m_end++;
|
||||
}
|
||||
|
||||
if (m_end <= m_start)
|
||||
m_end += 0x00010000;
|
||||
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
WT_Result WT_Ellipse::skip_operand(WT_Opcode const & opcode, WT_File & file)
|
||||
{
|
||||
switch (opcode.type())
|
||||
{
|
||||
case WT_Opcode::Single_Byte:
|
||||
{
|
||||
switch (opcode.token()[0])
|
||||
{
|
||||
case 'E':
|
||||
{
|
||||
WT_Logical_Point tmp_pt;
|
||||
WD_CHECK(file.read_ascii(tmp_pt));
|
||||
WD_CHECK(file.read_ascii(tmp_pt));
|
||||
} break;
|
||||
case 'e':
|
||||
{
|
||||
// This is an ellipse, with 32-bit relative coords, 32-bit axes, 16-bit angles
|
||||
file.skip(2 * sizeof(WT_Integer32) +
|
||||
2 * sizeof(WT_Unsigned_Integer32) +
|
||||
3 * sizeof(WT_Unsigned_Integer16));
|
||||
} break;
|
||||
case 'R':
|
||||
{
|
||||
WT_Integer32 tmp;
|
||||
WT_Logical_Point tmp_pt;
|
||||
WD_CHECK(file.read_ascii(tmp_pt));
|
||||
WD_CHECK(file.read_ascii(tmp));
|
||||
} break;
|
||||
case 'r':
|
||||
{
|
||||
// This is a circle, with 32-bit relative coords, 32-bit radius
|
||||
file.skip(2 * sizeof(WT_Integer32) +
|
||||
sizeof(WT_Unsigned_Integer32));
|
||||
} break;
|
||||
case 0x12: // Ctrl-R
|
||||
{
|
||||
// This is a circle, with 16-bit relative coords, 16-bit radius
|
||||
file.skip(2 * sizeof(WT_Integer16) +
|
||||
sizeof(WT_Unsigned_Integer16));
|
||||
} break;
|
||||
case 0x92: // X-Ctrl-R
|
||||
{
|
||||
// This is a circle, with 32-bit relative coords, 32-bit radius, 16-bit angles
|
||||
file.skip(2 * sizeof(WT_Integer32) +
|
||||
sizeof(WT_Unsigned_Integer32) +
|
||||
2 * sizeof(WT_Unsigned_Integer16));
|
||||
} break;
|
||||
default:
|
||||
return WT_Result::Opcode_Not_Valid_For_This_Object;
|
||||
// break;
|
||||
} // switch
|
||||
|
||||
|
||||
} break;
|
||||
case WT_Opcode::Extended_ASCII:
|
||||
WD_CHECK(opcode.skip_past_matching_paren(file));
|
||||
break;
|
||||
case WT_Opcode::Extended_Binary:
|
||||
default:
|
||||
{
|
||||
return WT_Result::Opcode_Not_Valid_For_This_Object;
|
||||
} break;
|
||||
} // switch
|
||||
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void WT_Ellipse::transform(WT_Transform const & transform)
|
||||
{
|
||||
if (!m_transformed)
|
||||
{
|
||||
// m_position.m_x = (WT_Integer32)((m_position.m_x + transform.m_translate.m_x) * transform.m_x_scale);
|
||||
// m_position.m_y = (WT_Integer32)((m_position.m_y + transform.m_translate.m_y) * transform.m_y_scale);
|
||||
|
||||
// m_position.m_x = (WT_Integer32)((m_position.m_x * transform.m_x_scale) + transform.m_translate.m_x);
|
||||
// m_position.m_y = (WT_Integer32)((m_position.m_y * transform.m_y_scale) + transform.m_translate.m_y);
|
||||
|
||||
WT_Logical_Point orig_pt(m_position);
|
||||
|
||||
m_position = orig_pt * transform; // we should use *=, but there seems to be a problem?
|
||||
|
||||
m_major = (WT_Unsigned_Integer32)(m_major * transform.m_x_scale);
|
||||
m_minor = (WT_Unsigned_Integer32)(m_minor * transform.m_y_scale);
|
||||
|
||||
if (m_major < 0)
|
||||
m_major = - m_major;
|
||||
if (m_minor < 0)
|
||||
m_minor = - m_minor;
|
||||
|
||||
m_tilt = (WT_Unsigned_Integer16)(
|
||||
(WT_Unsigned_Integer16)
|
||||
( (long)m_tilt +
|
||||
(long)WD_90_DEGREES_AS_SHORT * ((double)transform.rotation() / 90)
|
||||
) & 0x0000FFFF);
|
||||
|
||||
// TODO: note that we can simplify some ellipses by incorporating the tilt in and
|
||||
// exchanging the major and minor axes or by rotating the start and end points.
|
||||
|
||||
m_transformed = WD_True;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Result WT_Filled_Ellipse::process(WT_File & file)
|
||||
{
|
||||
WD_Assert (file.filled_ellipse_action());
|
||||
return (file.filled_ellipse_action())(*this, file);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Result WT_Filled_Ellipse::default_process(WT_Filled_Ellipse &, WT_File &)
|
||||
{
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Result WT_Outline_Ellipse::process(WT_File & file)
|
||||
{
|
||||
WD_Assert (file.outline_ellipse_action());
|
||||
return (file.outline_ellipse_action())(*this, file);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Result WT_Outline_Ellipse::default_process(WT_Outline_Ellipse &, WT_File &)
|
||||
{
|
||||
return WT_Result::Success;
|
||||
}
|
||||
1065
Whiptk702/font_options.cpp
Normal file
1065
Whiptk702/font_options.cpp
Normal file
File diff suppressed because it is too large
Load Diff
99
Whiptk702/logical_point.cpp
Normal file
99
Whiptk702/logical_point.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) 1996-2001 by Autodesk, Inc.
|
||||
//
|
||||
// By using this code, you are agreeing to the terms and conditions of
|
||||
// the License Agreement included in the documentation for this code.
|
||||
//
|
||||
// AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AS TO THE CORRECTNESS
|
||||
// OF THIS CODE OR ANY DERIVATIVE WORKS WHICH INCORPORATE IT. AUTODESK
|
||||
// PROVIDES THE CODE ON AN "AS-IS" BASIS AND EXPLICITLY DISCLAIMS ANY
|
||||
// LIABILITY, INCLUDING CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
|
||||
// OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
|
||||
//
|
||||
// Use, duplication, or disclosure by the U.S. Government is subject to
|
||||
// restrictions set forth in FAR 52.227-19 (Commercial Computer Software
|
||||
// Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
|
||||
// Data and Computer Software), as applicable.
|
||||
//
|
||||
// $Header: /NewRoot/DWF Toolkit/v6/develop/global/src/dwf/whiptk/logical_point.cpp 1 9/12/04 8:54p Evansg $
|
||||
|
||||
#include "whiptk/pch.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Boolean WT_Logical_Point::operator== (WT_Logical_Point_16 const & lp) const
|
||||
{
|
||||
if (m_x == (WT_Integer32)lp.m_x &&
|
||||
m_y == (WT_Integer32)lp.m_y)
|
||||
return WD_True;
|
||||
else
|
||||
return WD_False;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Logical_Point const & WT_Logical_Point::operator= (WT_Logical_Point_16 const & in)
|
||||
{
|
||||
m_x = (WT_Integer32) in.m_x;
|
||||
m_y = (WT_Integer32) in.m_y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
const double myPI = 3.14159265358979323846;
|
||||
|
||||
/////////////////////////
|
||||
WT_Logical_Point const WT_Logical_Point::operator* (WT_Transform const & trans) const
|
||||
{
|
||||
WT_Logical_Point new_point;
|
||||
|
||||
// new_point.m_x = (WT_Integer32) ( ((double)m_x + trans.m_translate.m_x) * trans.m_x_scale );
|
||||
// new_point.m_y = (WT_Integer32) ( ((double)m_y + trans.m_translate.m_y) * trans.m_y_scale );
|
||||
|
||||
switch (trans.rotation())
|
||||
{
|
||||
case 0:
|
||||
new_point.m_x = (WT_Integer32) (((double)m_x * trans.m_x_scale) + trans.m_translate.m_x);
|
||||
new_point.m_y = (WT_Integer32) (((double)m_y * trans.m_y_scale) + trans.m_translate.m_y);
|
||||
break;
|
||||
case 90:
|
||||
new_point.m_x = 0x7FFFFFFF - ((WT_Integer32) (((double)m_y * trans.m_y_scale) + trans.m_translate.m_y));
|
||||
new_point.m_y = (WT_Integer32) (((double)m_x * trans.m_x_scale) + trans.m_translate.m_x);
|
||||
break;
|
||||
case 180:
|
||||
new_point.m_x = 0x7FFFFFFF - ((WT_Integer32) (((double)m_x * trans.m_x_scale) + trans.m_translate.m_x));
|
||||
new_point.m_y = 0x7FFFFFFF - ((WT_Integer32) (((double)m_y * trans.m_y_scale) + trans.m_translate.m_y));
|
||||
break;
|
||||
case 270:
|
||||
new_point.m_x = (WT_Integer32) (((double)m_y * trans.m_y_scale) + trans.m_translate.m_y);
|
||||
new_point.m_y = 0x7FFFFFFF - ((WT_Integer32) (((double)m_x * trans.m_x_scale) + trans.m_translate.m_x));
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// Merk op: de code hierboven roteert om (INT_MAX/2, INT_MAX/2)
|
||||
// Bij 90 graden rotaties heb je dan geen kans op overflow.
|
||||
// Bij andere hoeken kan het wel mis gaan. Wij roteren hieronder
|
||||
// daarom om 0,0. Dat blijkt in de praktijk goed te gaan?
|
||||
double sinAngle = sin((double)trans.rotation() / 180.0 * myPI);
|
||||
double cosAngle = cos((double)trans.rotation() / 180.0 * myPI);
|
||||
double transx = (double)m_x * trans.m_x_scale + trans.m_translate.m_x;
|
||||
double transy = (double)m_y * trans.m_y_scale + trans.m_translate.m_y;
|
||||
double newx = transx * cosAngle - transy * sinAngle;
|
||||
double newy = transy * cosAngle + transx * sinAngle;
|
||||
// if (newx>INT_MAX || newy>INT_MAX || newx<INT_MIN || newy<INT_MIN)
|
||||
// DebugBreak();
|
||||
new_point.m_x = (WT_Integer32)newx;
|
||||
new_point.m_y = (WT_Integer32)newy;
|
||||
//throw WT_Result::Internal_Error;
|
||||
}
|
||||
}
|
||||
|
||||
return new_point;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Logical_Point const WT_Logical_Point::operator*= (WT_Transform const & trans)
|
||||
{
|
||||
// Need a temp copy since with some rotations will be mucking with intermediate terms
|
||||
WT_Logical_Point orig_point(m_x, m_y);
|
||||
|
||||
*this = orig_point * trans;
|
||||
return *this;
|
||||
}
|
||||
855
Whiptk702/text.cpp
Normal file
855
Whiptk702/text.cpp
Normal file
@@ -0,0 +1,855 @@
|
||||
// Copyright (c) 1996-2001 by Autodesk, Inc.
|
||||
//
|
||||
// By using this code, you are agreeing to the terms and conditions of
|
||||
// the License Agreement included in the documentation for this code.
|
||||
//
|
||||
// AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AS TO THE CORRECTNESS
|
||||
// OF THIS CODE OR ANY DERIVATIVE WORKS WHICH INCORPORATE IT. AUTODESK
|
||||
// PROVIDES THE CODE ON AN "AS-IS" BASIS AND EXPLICITLY DISCLAIMS ANY
|
||||
// LIABILITY, INCLUDING CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
|
||||
// OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
|
||||
//
|
||||
// Use, duplication, or disclosure by the U.S. Government is subject to
|
||||
// restrictions set forth in FAR 52.227-19 (Commercial Computer Software
|
||||
// Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
|
||||
// Data and Computer Software), as applicable.
|
||||
//
|
||||
// $Header: /Components/Internal/DWF Toolkit/v7.0.1/develop/global/src/dwf/whiptk/text.cpp 5 5/09/05 12:39a Evansg $
|
||||
|
||||
|
||||
#include "whiptk/pch.h"
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Text::WT_Text (WT_Text const &in)
|
||||
: WT_Drawable()
|
||||
, m_position(in.m_position)
|
||||
, m_string(in.m_string)
|
||||
, m_option_bounds(in.m_option_bounds)
|
||||
, m_option_overscore(in.m_option_overscore)
|
||||
, m_option_underscore(in.m_option_underscore)
|
||||
, m_option_reserved(in.m_option_reserved)
|
||||
, m_stage(in.m_stage)
|
||||
, m_transformed(in.m_transformed)
|
||||
, m_relativized(in.m_relativized)
|
||||
, m_optioncode(in.m_optioncode)
|
||||
, m_obsolete_font_holder(in.m_obsolete_font_holder)
|
||||
, m_obsolete_length_holder(in.m_obsolete_length_holder)
|
||||
, m_obsolete_msg_holder(in.m_obsolete_msg_holder)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Text & WT_Text::operator= (WT_Text const & in)
|
||||
{
|
||||
m_position = in.m_position;
|
||||
m_string = in.m_string;
|
||||
m_option_bounds = in.m_option_bounds;
|
||||
m_option_overscore = in.m_option_overscore;
|
||||
m_option_underscore = in.m_option_underscore;
|
||||
m_option_reserved = in.m_option_reserved;
|
||||
m_stage = in.m_stage;
|
||||
m_transformed = in.m_transformed;
|
||||
m_relativized = in.m_relativized;
|
||||
m_optioncode = in.m_optioncode;
|
||||
m_obsolete_font_holder = in.m_obsolete_font_holder;
|
||||
m_obsolete_length_holder = in.m_obsolete_length_holder;
|
||||
m_obsolete_msg_holder = in.m_obsolete_msg_holder;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Text::WT_Text ()
|
||||
: m_position (WT_Logical_Point (0,0))
|
||||
, m_stage (Getting_Started)
|
||||
, m_transformed (WD_False)
|
||||
, m_relativized (WD_False)
|
||||
, m_obsolete_font_holder (WD_Null)
|
||||
{ }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Text::~WT_Text()
|
||||
{
|
||||
if (m_obsolete_font_holder)
|
||||
delete m_obsolete_font_holder;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Text::WT_Text (WT_Logical_Point const & position,
|
||||
WT_String const & string,
|
||||
WT_Logical_Point const * bounds,
|
||||
WT_Unsigned_Integer16 overscore_count,
|
||||
WT_Unsigned_Integer16 const * overscore_pos,
|
||||
WT_Unsigned_Integer16 underscore_count,
|
||||
WT_Unsigned_Integer16 const * underscore_pos)
|
||||
: m_position (position)
|
||||
, m_string(string)
|
||||
, m_stage (Getting_Started)
|
||||
, m_transformed (WD_False)
|
||||
, m_relativized (WD_False)
|
||||
, m_obsolete_font_holder (WD_Null)
|
||||
{
|
||||
m_option_bounds.set(bounds);
|
||||
if (overscore_count)
|
||||
m_option_overscore.set(overscore_count, overscore_pos);
|
||||
if (underscore_count)
|
||||
m_option_underscore.set(underscore_count, underscore_pos);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Text::WT_Text (WT_Logical_Point const & position,
|
||||
WT_String const & string)
|
||||
: m_position (position)
|
||||
, m_string(string)
|
||||
, m_stage (Getting_Started)
|
||||
, m_transformed (WD_False)
|
||||
, m_relativized (WD_False)
|
||||
, m_obsolete_font_holder (WD_Null)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Object::WT_ID WT_Text::object_id() const
|
||||
{
|
||||
return Text_ID;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#if DESIRED_CODE(WHIP_OUTPUT)
|
||||
WT_Result WT_Text::serialize(WT_File & file) const
|
||||
{
|
||||
WD_CHECK (file.dump_delayed_drawable());
|
||||
|
||||
// BPM: This is a hack, but is the best I can do for now.
|
||||
// Here's the issue: if Tahoe has set the heuristic to flip landscape into portrait,
|
||||
// then we actually need the Font attribute to have a different rotation.
|
||||
// The rotation code will do the adjustment, but we need to make sure that
|
||||
// the rendition sync code "thinks" the font attribute might need updating.
|
||||
file.desired_rendition().font().rotation() = file.desired_rendition().font().rotation();
|
||||
|
||||
|
||||
WT_Integer32 parts_to_sync = WT_Rendition::Color_Bit |
|
||||
// WT_Rendition::Color_Map_Bit |
|
||||
// WT_Rendition::Fill_Bit |
|
||||
// WT_Rendition::Fill_Pattern_Bit |
|
||||
// WT_Rendition::Merge_Control_Bit |
|
||||
WT_Rendition::BlockRef_Bit |
|
||||
WT_Rendition::Visibility_Bit |
|
||||
// WT_Rendition::Line_Weight_Bit |
|
||||
WT_Rendition::Pen_Pattern_Bit |
|
||||
// WT_Rendition::Line_Pattern_Bit |
|
||||
// WT_Rendition::Line_Caps_Bit |
|
||||
// WT_Rendition::Line_Join_Bit |
|
||||
// WT_Rendition::Marker_Size_Bit |
|
||||
// WT_Rendition::Marker_Symbol_Bit |
|
||||
WT_Rendition::URL_Bit |
|
||||
WT_Rendition::Layer_Bit |
|
||||
WT_Rendition::Viewport_Bit |
|
||||
WT_Rendition::Font_Extension_Bit |
|
||||
WT_Rendition::Font_Bit |
|
||||
WT_Rendition::Object_Node_Bit;
|
||||
|
||||
WD_CHECK (file.desired_rendition().sync(file, parts_to_sync));
|
||||
|
||||
if (file.heuristics().apply_transform())
|
||||
((WT_Text *)this)->transform (file.heuristics().transform());
|
||||
|
||||
|
||||
if (file.heuristics().allow_binary_data())
|
||||
{
|
||||
((WT_Text *)this)->relativize(file);
|
||||
|
||||
if (m_option_bounds.bounds() ||
|
||||
m_option_overscore.count() ||
|
||||
m_option_underscore.count())
|
||||
{
|
||||
// Advanced binary text
|
||||
|
||||
WD_CHECK (file.write((WT_Byte) 0x18)); // CTRL-X
|
||||
WD_CHECK (file.write(1, &m_position));
|
||||
WD_CHECK (m_string.serialize(file, WD_True));
|
||||
WD_CHECK (m_option_overscore.serialize(*this, file));
|
||||
WD_CHECK (m_option_underscore.serialize(*this, file));
|
||||
WD_CHECK (m_option_bounds.serialize(*this, file));
|
||||
if (file.heuristics().target_version() >= REVISION_WHEN_PACKAGE_FORMAT_BEGINS)
|
||||
WD_CHECK (m_option_reserved.serialize(*this, file));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Basic binary text
|
||||
WD_CHECK (file.write((WT_Byte) 'x'));
|
||||
WD_CHECK (file.write(1, &m_position));
|
||||
WD_CHECK (m_string.serialize(file, WD_True));
|
||||
}
|
||||
} // if (allow binary data)
|
||||
else
|
||||
{
|
||||
// Extended ASCII
|
||||
// Don't relativize ASCII objects
|
||||
WD_CHECK (file.write_geom_tab_level());
|
||||
WD_CHECK (file.write("(Text "));
|
||||
WD_CHECK (file.write_ascii(m_position));
|
||||
WD_CHECK (file.write((WT_Byte) ' '));
|
||||
WD_CHECK (m_string.serialize(file));
|
||||
WD_CHECK (m_option_overscore.serialize(*this, file));
|
||||
WD_CHECK (m_option_underscore.serialize(*this, file));
|
||||
WD_CHECK (m_option_bounds.serialize(*this, file));
|
||||
if (file.heuristics().target_version() >= REVISION_WHEN_PACKAGE_FORMAT_BEGINS)
|
||||
WD_CHECK (m_option_reserved.serialize(*this, file));
|
||||
WD_CHECK (file.write((WT_Byte) ')'));
|
||||
} // else (extended ASCII output)
|
||||
|
||||
return WT_Result::Success;
|
||||
}
|
||||
#else
|
||||
WT_Result WT_Text::serialize(WT_File &) const
|
||||
{
|
||||
return WT_Result::Success;
|
||||
}
|
||||
#endif // DESIRED_CODE()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Result WT_Text::materialize(WT_Opcode const & opcode, WT_File & file)
|
||||
{
|
||||
switch (opcode.type())
|
||||
{
|
||||
case WT_Opcode::Single_Byte:
|
||||
{
|
||||
if (file.rendition().drawing_info().decimal_revision() < REVISION_WHEN_DRAW_TEXT_ATTRIBUTES_REMOVED)
|
||||
return materialize_obsolete_form(opcode, file); // Old obsolete version of DrawText opcode
|
||||
else
|
||||
{
|
||||
// Current version of DrawText opcode
|
||||
switch (opcode.token()[0])
|
||||
{
|
||||
case 0x18: // Ctrl-X
|
||||
{
|
||||
switch (m_stage)
|
||||
{
|
||||
case Getting_Started:
|
||||
m_stage = Getting_Position;
|
||||
|
||||
// No break;
|
||||
case Getting_Position:
|
||||
WD_CHECK (file.read(1, &m_position));
|
||||
m_stage = Getting_String;
|
||||
|
||||
// No break
|
||||
case Getting_String:
|
||||
WD_CHECK (m_string.materialize(file));
|
||||
m_stage = Getting_Overscore;
|
||||
|
||||
// No break
|
||||
case Getting_Overscore:
|
||||
WD_CHECK (m_option_overscore.materialize(*this, m_optioncode, file));
|
||||
m_stage = Getting_Underscore;
|
||||
|
||||
// No break
|
||||
case Getting_Underscore:
|
||||
WD_CHECK (m_option_underscore.materialize(*this, m_optioncode, file));
|
||||
m_stage = Getting_Bounds;
|
||||
|
||||
// No break
|
||||
case Getting_Bounds:
|
||||
WD_CHECK (m_option_bounds.materialize(*this, m_optioncode, file));
|
||||
m_stage = Getting_Reserved;
|
||||
|
||||
// No break
|
||||
case Getting_Reserved:
|
||||
if (file.rendition().drawing_info().decimal_revision() >= REVISION_WHEN_PACKAGE_FORMAT_BEGINS)
|
||||
WD_CHECK (m_option_reserved.materialize(*this, m_optioncode, file));
|
||||
m_stage = Completed;
|
||||
break;
|
||||
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
}
|
||||
} // case Ctrl-X
|
||||
|
||||
break;
|
||||
case 'x':
|
||||
{
|
||||
switch (m_stage)
|
||||
{
|
||||
case Getting_Started:
|
||||
m_stage = Getting_Position;
|
||||
|
||||
// No break
|
||||
case Getting_Position:
|
||||
WD_CHECK (file.read(1, &m_position));
|
||||
m_stage = Getting_String;
|
||||
|
||||
// No break
|
||||
case Getting_String:
|
||||
WD_CHECK (m_string.materialize(file));
|
||||
m_stage = Completed;
|
||||
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
} // switch (m_stage)
|
||||
|
||||
} break; // case 'x'
|
||||
|
||||
default:
|
||||
return WT_Result::Opcode_Not_Valid_For_This_Object; // Illegal opcode token
|
||||
} // switch (opcode token)
|
||||
} // else (current version of DrawText)
|
||||
|
||||
m_relativized = WD_True;
|
||||
de_relativize(file);
|
||||
|
||||
} break;
|
||||
case WT_Opcode::Extended_ASCII:
|
||||
{
|
||||
switch (m_stage)
|
||||
{
|
||||
case Getting_Started:
|
||||
m_stage = Getting_Position;
|
||||
|
||||
// No break
|
||||
case Getting_Position:
|
||||
WD_CHECK (file.read_ascii(m_position));
|
||||
m_stage = Getting_String;
|
||||
|
||||
// No break
|
||||
case Getting_String:
|
||||
WD_CHECK (m_string.materialize(file));
|
||||
m_stage = Getting_Next_Optioncode;
|
||||
|
||||
// No break
|
||||
Getting_Next_Optioncode_Hop:
|
||||
case Getting_Next_Optioncode:
|
||||
|
||||
WD_CHECK(m_optioncode.get_optioncode(file));
|
||||
if (m_optioncode.type() == WT_Opcode::Null_Optioncode)
|
||||
{
|
||||
m_stage = Skipping_Last_Paren;
|
||||
goto Skipping_Last_Paren_Hop;
|
||||
}
|
||||
m_stage = Materializing_Option;
|
||||
|
||||
// No Break;
|
||||
case Materializing_Option:
|
||||
|
||||
switch (m_optioncode.option_id())
|
||||
{
|
||||
case WT_Text_Optioncode::Overscore_Option:
|
||||
WD_CHECK(m_option_overscore.materialize(*this, m_optioncode, file));
|
||||
break;
|
||||
case WT_Text_Optioncode::Underscore_Option:
|
||||
WD_CHECK(m_option_underscore.materialize(*this, m_optioncode, file));
|
||||
break;
|
||||
case WT_Text_Optioncode::Bounds_Option:
|
||||
WD_CHECK(m_option_bounds.materialize(*this, m_optioncode, file));
|
||||
break;
|
||||
case WT_Text_Optioncode::Reserved_Option:
|
||||
WD_CHECK(m_option_reserved.materialize(*this, m_optioncode, file));
|
||||
break;
|
||||
case WT_Text_Optioncode::Unknown_Option:
|
||||
WD_CHECK(m_optioncode.skip_past_matching_paren(file));
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
} // switch (m_sub_option.option_id())
|
||||
|
||||
m_stage = Getting_Next_Optioncode;
|
||||
goto Getting_Next_Optioncode_Hop;
|
||||
|
||||
Skipping_Last_Paren_Hop:
|
||||
case Skipping_Last_Paren:
|
||||
WD_CHECK (opcode.skip_past_matching_paren(file));
|
||||
m_stage = Completed;
|
||||
break;
|
||||
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
} // switch (m_stage)
|
||||
|
||||
} break; // ASCII
|
||||
case WT_Opcode::Extended_Binary:
|
||||
default:
|
||||
{
|
||||
return WT_Result::Opcode_Not_Valid_For_This_Object;
|
||||
} break;
|
||||
} // switch
|
||||
|
||||
if (file.heuristics().apply_transform())
|
||||
transform(file.heuristics().transform());
|
||||
|
||||
m_materialized = WD_True;
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Result WT_Text::materialize_obsolete_form(WT_Opcode const & opcode, WT_File & file)
|
||||
{
|
||||
WT_Integer16 tmp_int16;
|
||||
WT_Integer32 tmp_int32;
|
||||
|
||||
switch (opcode.token()[0])
|
||||
{
|
||||
case 'x':
|
||||
{
|
||||
switch (m_stage)
|
||||
{
|
||||
case Getting_Started:
|
||||
WD_Assert(!m_obsolete_font_holder);
|
||||
|
||||
m_obsolete_font_holder = new WT_Font;
|
||||
if (!m_obsolete_font_holder)
|
||||
return WT_Result::Out_Of_Memory_Error;
|
||||
|
||||
m_obsolete_font_holder->set_fields_defined( WT_Font::FONT_HEIGHT_BIT |
|
||||
WT_Font::FONT_ROTATION_BIT |
|
||||
WT_Font::FONT_OBLIQUE_BIT |
|
||||
WT_Font::FONT_WIDTH_SCALE_BIT |
|
||||
WT_Font::FONT_SPACING_BIT |
|
||||
WT_Font::FONT_FLAGS_BIT );
|
||||
m_stage = Getting_Width_Scale;
|
||||
|
||||
// No break
|
||||
case Getting_Width_Scale:
|
||||
|
||||
WD_CHECK (file.read(tmp_int16));
|
||||
m_obsolete_font_holder->width_scale().set(tmp_int16);
|
||||
m_stage = Getting_Spacing;
|
||||
|
||||
case Getting_Spacing:
|
||||
WD_CHECK (file.read(tmp_int16));
|
||||
m_obsolete_font_holder->spacing().set(tmp_int16);
|
||||
m_stage = Getting_Flags;
|
||||
|
||||
case Getting_Flags:
|
||||
WD_CHECK (file.read(tmp_int32));
|
||||
m_obsolete_font_holder->flags().set(tmp_int32);
|
||||
m_stage = Getting_Oblique_Angle;
|
||||
|
||||
// No break
|
||||
case Getting_Oblique_Angle:
|
||||
WD_CHECK (file.read(tmp_int16));
|
||||
m_obsolete_font_holder->oblique().set(tmp_int16);
|
||||
m_stage = Getting_Overscore;
|
||||
|
||||
// No break
|
||||
case Getting_Overscore:
|
||||
WD_CHECK (m_option_overscore.materialize(*this, m_optioncode, file));
|
||||
m_stage = Getting_Underscore;
|
||||
|
||||
// No break
|
||||
case Getting_Underscore:
|
||||
WD_CHECK (m_option_underscore.materialize(*this, m_optioncode, file));
|
||||
m_stage = Getting_Rotation;
|
||||
|
||||
// No break
|
||||
case Getting_Rotation:
|
||||
WD_CHECK (file.read(tmp_int16));
|
||||
m_obsolete_font_holder->rotation().set(tmp_int16);
|
||||
m_stage = Getting_Height;
|
||||
|
||||
// No break
|
||||
case Getting_Height:
|
||||
WD_CHECK (file.read(tmp_int32));
|
||||
if (file.heuristics().apply_transform())
|
||||
tmp_int32 = (WT_Integer32) (tmp_int32 * file.heuristics().transform().m_y_scale);
|
||||
m_obsolete_font_holder->height().set(tmp_int32);
|
||||
m_stage = Getting_Position;
|
||||
|
||||
// No break
|
||||
case Getting_Position:
|
||||
WD_CHECK (file.read(1, &m_position));
|
||||
m_stage = Getting_BBox_Deltas;
|
||||
|
||||
// No break
|
||||
case Getting_BBox_Deltas:
|
||||
{
|
||||
WT_Logical_Point tmp_bbox[4];
|
||||
|
||||
WD_CHECK (file.read(4, tmp_bbox));
|
||||
|
||||
// convert from relative to absolute
|
||||
m_position = file.de_update_current_point(m_position);
|
||||
m_relativized = WD_False;
|
||||
|
||||
WT_Integer32 delta[8];
|
||||
|
||||
delta[0] = tmp_bbox[0].m_x;
|
||||
delta[1] = tmp_bbox[0].m_y;
|
||||
delta[2] = tmp_bbox[1].m_x;
|
||||
delta[3] = tmp_bbox[1].m_y;
|
||||
delta[4] = tmp_bbox[2].m_x;
|
||||
delta[5] = tmp_bbox[2].m_y;
|
||||
delta[6] = tmp_bbox[3].m_x;
|
||||
delta[7] = tmp_bbox[3].m_y;
|
||||
|
||||
tmp_bbox[0].m_x = m_position.m_x + delta[4];
|
||||
tmp_bbox[0].m_y = m_position.m_y + delta[6];
|
||||
tmp_bbox[1].m_x = tmp_bbox[0].m_x + delta[7];
|
||||
tmp_bbox[1].m_y = tmp_bbox[0].m_y + delta[5];
|
||||
tmp_bbox[2].m_x = tmp_bbox[1].m_x + delta[2];
|
||||
tmp_bbox[2].m_y = tmp_bbox[1].m_y + delta[3];
|
||||
tmp_bbox[3].m_x = tmp_bbox[0].m_x + delta[0];
|
||||
tmp_bbox[3].m_y = tmp_bbox[0].m_y + delta[1];
|
||||
|
||||
m_option_bounds.set(tmp_bbox);
|
||||
m_stage = Getting_Str_Length;
|
||||
}
|
||||
|
||||
// No break
|
||||
case Getting_Str_Length:
|
||||
WD_CHECK (file.read_count(m_obsolete_length_holder));
|
||||
|
||||
m_obsolete_msg_holder = new unsigned short[m_obsolete_length_holder + 1];
|
||||
if (!m_obsolete_msg_holder)
|
||||
throw WT_Result::Out_Of_Memory_Error;
|
||||
|
||||
m_stage = Getting_Msg;
|
||||
|
||||
// No break
|
||||
case Getting_Msg:
|
||||
WD_CHECK (file.read( 2 * m_obsolete_length_holder, (WT_Byte *)m_obsolete_msg_holder));
|
||||
m_obsolete_msg_holder[m_obsolete_length_holder] = 0;
|
||||
m_string.set(m_obsolete_length_holder, m_obsolete_msg_holder);
|
||||
delete []m_obsolete_msg_holder;
|
||||
|
||||
m_stage = Completed;
|
||||
break;
|
||||
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
} // switch (m_stage)
|
||||
|
||||
if (file.heuristics().apply_transform())
|
||||
transform(file.heuristics().transform());
|
||||
|
||||
} break;
|
||||
|
||||
case 0x18:
|
||||
{
|
||||
WT_Integer32 tmp_int32;
|
||||
WT_Integer16 tmp_int16;
|
||||
|
||||
switch (m_stage)
|
||||
{
|
||||
case Getting_Started:
|
||||
WD_Assert(!m_obsolete_font_holder);
|
||||
|
||||
m_obsolete_font_holder = new WT_Font;
|
||||
if (!m_obsolete_font_holder)
|
||||
return WT_Result::Out_Of_Memory_Error;
|
||||
|
||||
m_obsolete_font_holder->set_fields_defined( WT_Font::FONT_HEIGHT_BIT |
|
||||
WT_Font::FONT_ROTATION_BIT );
|
||||
m_stage = Getting_Rotation;
|
||||
|
||||
case Getting_Rotation:
|
||||
WD_CHECK (file.read(tmp_int16));
|
||||
m_obsolete_font_holder->rotation().set(tmp_int16);
|
||||
m_stage = Getting_Height;
|
||||
|
||||
case Getting_Height:
|
||||
WD_CHECK (file.read(tmp_int32));
|
||||
if (file.heuristics().apply_transform())
|
||||
tmp_int32 = (WT_Integer32) (tmp_int32 * file.heuristics().transform().m_y_scale);
|
||||
|
||||
m_obsolete_font_holder->height().set(tmp_int32);
|
||||
m_stage = Getting_Position;
|
||||
|
||||
case Getting_Position:
|
||||
WD_CHECK (file.read(1, &m_position));
|
||||
m_relativized = WD_True;
|
||||
m_stage = Getting_Str_Length;
|
||||
|
||||
case Getting_Str_Length:
|
||||
WD_CHECK (file.read_count(m_obsolete_length_holder));
|
||||
|
||||
m_obsolete_msg_holder = new unsigned short[m_obsolete_length_holder + 1];
|
||||
if (!m_obsolete_msg_holder)
|
||||
throw WT_Result::Out_Of_Memory_Error;
|
||||
|
||||
m_stage = Getting_Msg;
|
||||
|
||||
// No break
|
||||
case Getting_Msg:
|
||||
WD_CHECK (file.read( 2 * m_obsolete_length_holder, (WT_Byte *)m_obsolete_msg_holder));
|
||||
m_obsolete_msg_holder[m_obsolete_length_holder] = 0;
|
||||
m_string.set(m_obsolete_length_holder, m_obsolete_msg_holder);
|
||||
delete []m_obsolete_msg_holder;
|
||||
m_stage = Completed;
|
||||
|
||||
break;
|
||||
default:
|
||||
return WT_Result::Internal_Error;
|
||||
} // switch (m_stage)
|
||||
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
return WT_Result::Opcode_Not_Valid_For_This_Object;
|
||||
} break;
|
||||
} // switch
|
||||
|
||||
de_relativize(file);
|
||||
|
||||
if (file.heuristics().apply_transform())
|
||||
transform(file.heuristics().transform());
|
||||
|
||||
m_materialized = WD_True;
|
||||
|
||||
// Now send these WT_Font attributes off for processing...
|
||||
if (m_obsolete_font_holder)
|
||||
{
|
||||
m_obsolete_font_holder->process(file);
|
||||
delete m_obsolete_font_holder;
|
||||
m_obsolete_font_holder = WD_Null;
|
||||
}
|
||||
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Result WT_Text::skip_operand(WT_Opcode const & opcode, WT_File & file)
|
||||
{
|
||||
switch (opcode.type())
|
||||
{
|
||||
case WT_Opcode::Single_Byte:
|
||||
{
|
||||
return materialize(opcode, file);
|
||||
} break;
|
||||
case WT_Opcode::Extended_ASCII:
|
||||
WD_CHECK (opcode.skip_past_matching_paren(file));
|
||||
break;
|
||||
case WT_Opcode::Extended_Binary:
|
||||
default:
|
||||
{
|
||||
return WT_Result::Opcode_Not_Valid_For_This_Object;
|
||||
} break;
|
||||
} // switch
|
||||
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void WT_Text::transform(WT_Transform const & transform)
|
||||
{
|
||||
if (!m_transformed)
|
||||
{
|
||||
WT_Logical_Point tmp_pt;
|
||||
|
||||
tmp_pt = m_position;
|
||||
m_position = tmp_pt * transform;
|
||||
|
||||
m_option_bounds.transform(transform);
|
||||
m_transformed = WD_True;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WT_Result WT_Text::process(WT_File & file)
|
||||
{
|
||||
WD_Assert (file.text_action());
|
||||
return (file.text_action())(*this, file);
|
||||
}
|
||||
|
||||
WT_Result WT_Text::default_process(WT_Text &, WT_File &)
|
||||
{
|
||||
return WT_Result::Success;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#if DESIRED_CODE(WHIP_OUTPUT)
|
||||
void WT_Text::relativize(WT_File & file)
|
||||
{
|
||||
if (!m_relativized)
|
||||
{
|
||||
m_position = file.update_current_point(m_position);
|
||||
m_option_bounds.relativize(file);
|
||||
m_relativized = WD_True;
|
||||
} // If (!relativized)
|
||||
}
|
||||
#else
|
||||
void WT_Text::relativize(WT_File &)
|
||||
{
|
||||
}
|
||||
#endif // DESIRED_CODE()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
void WT_Text::de_relativize(WT_File & file)
|
||||
{
|
||||
if (m_relativized)
|
||||
{
|
||||
m_position = file.de_update_current_point(m_position);
|
||||
m_option_bounds.de_relativize(file);
|
||||
m_relativized = WD_False;
|
||||
} // If (!relativized)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FIXME: WT_Text::update_bounds is completely Win32 specific, and must be ported.
|
||||
#ifdef WD_WIN32_SYSTEM
|
||||
|
||||
#include <tchar.h>
|
||||
#pragma comment (lib, "gdi32.lib") //for font bounds approximation
|
||||
|
||||
void WT_Text::update_bounds(WT_File * file)
|
||||
{
|
||||
if (m_option_bounds.bounds() != WD_Null)
|
||||
{
|
||||
WT_Drawable::update_bounds(m_option_bounds.bounds(), 2);
|
||||
return;
|
||||
}
|
||||
|
||||
WT_Drawable::update_bounds(m_position); //base point
|
||||
|
||||
if (m_string.length()==0)
|
||||
return;
|
||||
|
||||
WT_Integer32 height = file->rendition().font().height();
|
||||
int rotation = (int)((float)TWO_PI * (float)file->rendition().font().rotation() / 65536.0f);
|
||||
int oblique = (int)((float)TWO_PI * (float)file->rendition().font().oblique() / 65536.0f);
|
||||
BYTE charset = file->rendition().font().charset().charset();
|
||||
BYTE pitch_and_family = file->rendition().font().pitch().pitch() | file->rendition().font().family().family();
|
||||
UINT string_length = m_string.length();
|
||||
BYTE italic = file->rendition().font().style().italic();
|
||||
BYTE underline = file->rendition().font().style().underlined();
|
||||
BYTE bold = file->rendition().font().style().bold();
|
||||
//
|
||||
// this is dangerous since it assumes wchar_t is always 16-bit uchar
|
||||
//
|
||||
wchar_t* facename = new wchar_t[file->rendition().font().font_name().name().length()+1];
|
||||
const wchar_t* cwstr = (const wchar_t*)file->rendition().font().font_name().name().unicode();
|
||||
if (cwstr)
|
||||
{
|
||||
wcscpy(facename, cwstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
facename[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
wchar_t* wstr = new wchar_t[m_string.length()+1];
|
||||
wcscpy(wstr, (const wchar_t*)m_string.unicode());
|
||||
|
||||
HWND hwnd = NULL;
|
||||
HDC hdc = NULL;
|
||||
|
||||
do
|
||||
{
|
||||
hwnd = ::GetDesktopWindow();
|
||||
if (!hwnd || hwnd == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
hdc = ::GetDC(hwnd);
|
||||
if (!hdc || hdc == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
LOGFONTW logfont;
|
||||
logfont.lfHeight = 2048; //we'll get the right value down below
|
||||
logfont.lfWidth = 0; //force aspect ratio of font
|
||||
logfont.lfEscapement = oblique;
|
||||
logfont.lfOrientation = rotation;
|
||||
logfont.lfWeight = bold ? FW_BOLD : FW_DONTCARE;
|
||||
logfont.lfItalic = italic;
|
||||
logfont.lfUnderline = underline;
|
||||
//logfont.lfStrikeOut;
|
||||
logfont.lfCharSet = charset;
|
||||
logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
||||
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
logfont.lfQuality = DEFAULT_QUALITY;
|
||||
logfont.lfPitchAndFamily = pitch_and_family;
|
||||
memset(logfont.lfFaceName,0,LF_FACESIZE*sizeof(wchar_t));
|
||||
wcsncpy(logfont.lfFaceName,facename,LF_FACESIZE);
|
||||
|
||||
HFONT hfont = ::CreateFontIndirectW(&logfont);
|
||||
if (!hfont || hfont == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
//we want to get the width based on font design units, probably 2048, maybe 1024
|
||||
//query and figure that out. use that as the height
|
||||
|
||||
HGDIOBJ hobj = ::SelectObject(hdc, hfont);
|
||||
|
||||
int size = ::GetOutlineTextMetricsW(hdc, 0, NULL);
|
||||
if (size != 0)
|
||||
{
|
||||
OUTLINETEXTMETRICW *otm = (OUTLINETEXTMETRICW *)new char [size];
|
||||
WD_Assert(otm != NULL);
|
||||
|
||||
UINT status = GetOutlineTextMetricsW (hdc, size, otm);
|
||||
WD_Assert(status != 0);
|
||||
|
||||
if (status != 0)
|
||||
logfont.lfHeight = otm->otmEMSquare;
|
||||
|
||||
delete [] otm;
|
||||
}
|
||||
else
|
||||
{
|
||||
logfont.lfHeight = 1000;
|
||||
}
|
||||
|
||||
logfont.lfHeight *= -1; // Negative is more accurate
|
||||
::SelectObject(hdc, hobj);
|
||||
::DeleteObject(hfont);
|
||||
hfont = ::CreateFontIndirectW(&logfont);
|
||||
if (!hfont || hfont == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
hobj = ::SelectObject(hdc, hfont);
|
||||
|
||||
SIZE fontsize;
|
||||
::GetTextExtentPointW(hdc, wstr, string_length, &fontsize);
|
||||
::SelectObject(hdc, hobj);
|
||||
::DeleteObject(hfont);
|
||||
|
||||
//now we have the width in font design units. Now translate this based on font height.
|
||||
|
||||
int deltaX = -(int)((double)height * (double)fontsize.cx / (double)logfont.lfHeight);
|
||||
int deltaY = -(int)((double)height * (double)fontsize.cy / (double)logfont.lfHeight);
|
||||
|
||||
bool overflowX = (double)((m_position.m_x + deltaX) - (double)m_position.m_x) != deltaX;
|
||||
bool overflowY = (double)((m_position.m_y + deltaY) - (double)m_position.m_y) != deltaY;
|
||||
|
||||
int ptx = overflowX //exceeded intmax?
|
||||
? 0x7FFFFFFF
|
||||
: m_position.m_x + deltaX;
|
||||
|
||||
int pty = overflowY //exceeded intmax?
|
||||
? 0x7FFFFFFF
|
||||
: m_position.m_y + deltaY;
|
||||
|
||||
// GetTextExtentPointW ignores rotation. So rotate around our basepoint ourselves
|
||||
double drotation = ((float)TWO_PI * (float)file->rendition().font().rotation() / 65536.0f);
|
||||
#define ROT(x,y) WT_Logical_Point(m_position.m_x+(long)((x)*cos((double)drotation)-(y)*sin((double)drotation)),\
|
||||
m_position.m_y+(long)((y)*cos((double)drotation)+(x)*sin((double)drotation)))
|
||||
ptx,pty;
|
||||
WT_Logical_Point xx[] = { ROT(0,0),
|
||||
ROT(deltaX,0),
|
||||
ROT(deltaX,deltaY) ,
|
||||
ROT(0,deltaY)};
|
||||
|
||||
// if (xx[0].m_x < 0 ||xx[1].m_x < 0 ||xx[2].m_x < 0 ||xx[3].m_x < 0)
|
||||
// DebugBreak();
|
||||
m_option_bounds.set(xx);
|
||||
//m_option_bounds.transform(WT_Transform(m_position,1,1, 0));
|
||||
WT_Drawable::update_bounds(m_option_bounds.bounds(), 4);
|
||||
} while (false);
|
||||
|
||||
if (hdc && hdc != INVALID_HANDLE_VALUE && hwnd && hwnd != INVALID_HANDLE_VALUE)
|
||||
::ReleaseDC(hwnd, hdc);
|
||||
|
||||
delete [] facename;
|
||||
delete [] wstr;
|
||||
}
|
||||
|
||||
#else // WD_WIN32_SYSTEM
|
||||
|
||||
void WT_Text::update_bounds(WT_File *) {
|
||||
WD_Complain ("WT_Text::update_bounds is not implemented on this system");
|
||||
}
|
||||
|
||||
#endif // WD_WIN32_SYSTEM
|
||||
80
Whiptk702/transform.h
Normal file
80
Whiptk702/transform.h
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 1996-2002 by Autodesk, Inc.
|
||||
//
|
||||
// By using this code, you are agreeing to the terms and conditions of
|
||||
// the License Agreement included in the documentation for this code.
|
||||
//
|
||||
// AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED, AS TO THE CORRECTNESS
|
||||
// OF THIS CODE OR ANY DERIVATIVE WORKS WHICH INCORPORATE IT. AUTODESK
|
||||
// PROVIDES THE CODE ON AN "AS-IS" BASIS AND EXPLICITLY DISCLAIMS ANY
|
||||
// LIABILITY, INCLUDING CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
|
||||
// OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
|
||||
//
|
||||
// Use, duplication, or disclosure by the U.S. Government is subject to
|
||||
// restrictions set forth in FAR 52.227-19 (Commercial Computer Software
|
||||
// Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
|
||||
// Data and Computer Software), as applicable.
|
||||
//
|
||||
|
||||
#if !defined TRANSFORM_HEADER
|
||||
#define TRANSFORM_HEADER
|
||||
|
||||
/// A simple transform providing translation, scaling, and simple 90, 180, 270 degree rotations.
|
||||
/** \exception WT_Result::Toolkit_Usage_Error The rotation was not one of 0, 90, 180, 270.
|
||||
*/
|
||||
class WHIPTK_API WT_Transform
|
||||
{
|
||||
public:
|
||||
WT_Logical_Point m_translate; /**< \brief Translation vector. */
|
||||
double m_x_scale; /**< \brief X scale factor. */
|
||||
double m_y_scale; /**< \brief Y scale factor. */
|
||||
long m_rotation; /**< \brief Rotation (in degrees, one of 0, 90, 180, 270). */
|
||||
|
||||
/// Constructs a WT_Transform object.
|
||||
WT_Transform()
|
||||
: m_translate(0,0)
|
||||
, m_x_scale(1.0)
|
||||
, m_y_scale(1.0)
|
||||
, m_rotation(0)
|
||||
{ }
|
||||
|
||||
/// Constructs a WT_Transform object with the given data.
|
||||
WT_Transform (
|
||||
WT_Logical_Point trans, /**< Translation vector. */
|
||||
double xval, /**< X scale factor. */
|
||||
double yval, /**< Y scale factor. */
|
||||
double rotation = 0.0 /**< Optional rotation (in degrees, one of 0, 90, 180, 270). */
|
||||
)
|
||||
: m_translate(trans)
|
||||
, m_x_scale(xval)
|
||||
, m_y_scale(yval)
|
||||
{
|
||||
set_rotation(rotation);
|
||||
}
|
||||
|
||||
/// Sets the rotation value.
|
||||
/** \exception WT_Result::Toolkit_Usage_Error The rotation was not one of 0, 90, 180, 270.
|
||||
*/
|
||||
void set_rotation(
|
||||
double rotation /**< Rotation (in degrees, one of 0, 90, 180, 270). */
|
||||
)
|
||||
{
|
||||
switch ((long)rotation)
|
||||
{
|
||||
case 0:
|
||||
case 90:
|
||||
case 180:
|
||||
case 270:
|
||||
m_rotation = (long)rotation;
|
||||
break;
|
||||
default:
|
||||
m_rotation = (long)rotation;
|
||||
//throw WT_Result::Toolkit_Usage_Error;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the rotation value (in degrees, one of 0, 90, 180, 270).
|
||||
long rotation() const
|
||||
{ return m_rotation; }
|
||||
};
|
||||
|
||||
#endif // TRANSFORM_HEADER
|
||||
Reference in New Issue
Block a user