From f07aea9ec7771e7037b9ff41053b8480cc04c747 Mon Sep 17 00:00:00 2001 From: Jos Groot Lipman Date: Mon, 21 Jan 2008 13:34:06 +0000 Subject: [PATCH] v2.10 Symbool rotatie svn path=/Slnkdwf/trunk/; revision=12485 --- RemoveAbout/RemoveAbout.vcproj | 7 +- SlnkDWFCom/DWFFile.cpp | 3 + SlnkDWFCom/Options.cpp | 9 +- SlnkDWFCom/Options.h | 3 +- SlnkDWFCom/SLNKDWF.idl | 4 + SlnkDWFCom/SLNKDWF.vcproj | 12 ++ SlnkDWFCom/SLNKEvent.cpp | 24 ++++ SlnkDWFCom/SLNKEvent.h | 6 + SlnkDWFCom/SLNKSymbol.cpp | 5 +- SlnkDWFCom/SLNKSymbolDefImpl.cpp | 35 ++++-- SlnkDWFCom/SLNKSymbolDefImpl.h | 3 +- SlnkDWFCom/SLNKSymbolImpl.cpp | 61 +++++----- SlnkDWFCom/SLNKdwf.rc | 2 +- SlnkDWFCom/Whip2PNG.cpp | 21 +++- SlnkDWFCom/WhipFile.cpp | 31 ++++- SlnkDWFImpl/DWFFileImpl.cpp | 2 +- SlnkDWFImpl/SLNKContourImpl.cpp | 189 ++++++++++++++++++++++++++++- SlnkDWFImpl/SLNKContourImpl.h | 5 +- SlnkDWFImpl/SLNKDWFStaticRW.vcproj | 4 + SlnkDWFImpl/Whip2DCImpl.cpp | 137 +++++++++++++++++---- SlnkDWFImpl/Whip2DCImpl.h | 5 +- SlnkDWFImpl/Whip2DCState.cpp | 7 +- SlnkDWFImpl/Whip2DCState.h | 5 +- 23 files changed, 491 insertions(+), 89 deletions(-) diff --git a/RemoveAbout/RemoveAbout.vcproj b/RemoveAbout/RemoveAbout.vcproj index 52c304c..cb7e609 100644 --- a/RemoveAbout/RemoveAbout.vcproj +++ b/RemoveAbout/RemoveAbout.vcproj @@ -5,6 +5,10 @@ Name="RemoveAbout" ProjectGUID="{89BE476D-6C02-4514-BFCE-256106D98713}" RootNamespace="RemoveAbout" + + + + > @@ -480,6 +484,10 @@ RelativePath="DWFFile.rgs" > + + @@ -492,6 +500,10 @@ RelativePath="SLNKdwf.rc" > + + diff --git a/SlnkDWFCom/SLNKEvent.cpp b/SlnkDWFCom/SLNKEvent.cpp index 737e00a..7186a4c 100644 --- a/SlnkDWFCom/SLNKEvent.cpp +++ b/SlnkDWFCom/SLNKEvent.cpp @@ -93,3 +93,27 @@ STDMETHODIMP CSLNKEvent::get_viewExtents(IBoundingBox** pVal) { return m_viewBounding->QueryInterface(IID_IBoundingBox, (void**)pVal); } + +STDMETHODIMP CSLNKEvent::get_EdgeAngle(DOUBLE* pVal) +{ + (*pVal) = m_EdgeAngle; + return S_OK; +}; + +STDMETHODIMP CSLNKEvent::put_EdgeAngle(DOUBLE newVal) +{ + m_EdgeAngle = newVal; + return S_OK; +}; + +STDMETHODIMP CSLNKEvent::get_EdgeDistance(DOUBLE* pVal) +{ + (*pVal) = m_EdgeDistance; + return S_OK; +}; + +STDMETHODIMP CSLNKEvent::put_EdgeDistance(DOUBLE newVal) +{ + m_EdgeDistance = newVal; + return S_OK; +}; diff --git a/SlnkDWFCom/SLNKEvent.h b/SlnkDWFCom/SLNKEvent.h index 3e5e7df..d54a659 100644 --- a/SlnkDWFCom/SLNKEvent.h +++ b/SlnkDWFCom/SLNKEvent.h @@ -67,6 +67,8 @@ private: CComQIPtr m_viewBounding; double m_DwgX, m_DwgY; + double m_EdgeAngle; + double m_EdgeDistance; double m_minDwgX, m_maxDwgY; double m_maxDwgX, m_minDwgY; CString m_ContourLabel, m_ContourLayer; @@ -88,6 +90,10 @@ public: STDMETHOD(get_found)(IDWGPoint** pVal); STDMETHOD(get_dwgExtents)(IBoundingBox** pVal); STDMETHOD(get_viewExtents)(IBoundingBox** pVal); + STDMETHOD(get_EdgeAngle)(DOUBLE* pVal); + STDMETHOD(put_EdgeAngle)(DOUBLE newVal); + STDMETHOD(get_EdgeDistance)(DOUBLE* pVal); + STDMETHOD(put_EdgeDistance)(DOUBLE newVal); }; //REMOVED OBJECT_ENTRY_AUTO(__uuidof(SLNKEvent), CSLNKEvent) diff --git a/SlnkDWFCom/SLNKSymbol.cpp b/SlnkDWFCom/SLNKSymbol.cpp index e0edfe2..5dd2e8e 100644 --- a/SlnkDWFCom/SLNKSymbol.cpp +++ b/SlnkDWFCom/SLNKSymbol.cpp @@ -48,8 +48,9 @@ STDMETHODIMP CSLNKSymbol::get_Rotation(LONG* pVal) STDMETHODIMP CSLNKSymbol::put_Rotation(LONG newVal) { long rotation = (newVal%360+360)%360; // Normaliseren - if (rotation%90 != 0) - return myAtlReportError (GetObjectCLSID(), "ERROR Symbol rotation must be 0/90/180/270."); + +// if (rotation%90 != 0) +// return myAtlReportError (GetObjectCLSID(), "ERROR Symbol rotation must be 0/90/180/270."); m_SLNKSymbol->m_Rotation = newVal; return S_OK; diff --git a/SlnkDWFCom/SLNKSymbolDefImpl.cpp b/SlnkDWFCom/SLNKSymbolDefImpl.cpp index 6a61566..d0ff0a5 100644 --- a/SlnkDWFCom/SLNKSymbolDefImpl.cpp +++ b/SlnkDWFCom/SLNKSymbolDefImpl.cpp @@ -16,7 +16,9 @@ CSLNKSymbolDefinition::CSLNKSymbolDefinition(CComQIPtr EPlotSecti m_wtFile.set_eplotsection(epli); m_AsBitmap = NULL; m_BuiltIn = false; - calculateBoundary(); + calculateBoundary(m_BoundingContour); + //m_Origin = m_Center; + m_Origin = CSLNKContourImpl::Centroid(m_BoundingContour); }; // Bij Contour list (builtin symbol) @@ -89,15 +91,26 @@ CSLNKSymbolDefinition::~CSLNKSymbolDefinition(void) // http://geometryalgorithms.com/Archive/algorithm_0107/algorithm_0107.htm // (v2: bounding convex hull waarschijnlijk overkill) #include -WT_Result CSLNKSymbolDefinition::calculateBoundary () +WT_Result CSLNKSymbolDefinition::calculateBoundary (WT_Polygon &BoundingContour, WT_Transform *tm/*=null*/) { WT_Result result; + if (m_BuiltIn || m_AsBitmap != NULL) + { + return WT_Result::Success; + } + m_wtFile.set_file_mode(WT_File::File_Read); result = m_wtFile.open(); if (result != WT_Result::Success) return result; + if (tm != NULL) + { + m_wtFile.heuristics().set_transform(*tm); + m_wtFile.heuristics().set_apply_transform(true); + } + // Door de enorm grote dwf-coordinaten lopen we een integer overflow risico tijdens // onze bepaling van Pmin en Pmax (die min en max van x+y bepalen) en in theorie // ook van Qmin en Qmax (die over het verschil x-y gaan) hoewel dat in de praktijk rond 0 zal liggen @@ -118,6 +131,9 @@ WT_Result CSLNKSymbolDefinition::calculateBoundary () while ((result = m_wtFile.process_next_object()) == WT_Result::Success) { //myTRACE("Attribute '%s'\n", wtFile->file_stats()->descriptions()); + if (!m_wtFile.rendition().visibility().visible()) + continue; + switch(m_wtFile.current_object()->object_type()) { case WT_Object::Attribute: @@ -141,7 +157,8 @@ WT_Result CSLNKSymbolDefinition::calculateBoundary () case WT_Object::Drawable: { WT_Drawable *obj = (WT_Drawable *)m_wtFile.current_object(); - if (obj->object_id() != WT_Object::Origin_ID)// Belachelijk dat die Drawable is? + + if (obj->object_id() != WT_Object::Origin_ID) // Belachelijk dat die Drawable is? { WT_Logical_Box bx = obj->bounds(&m_wtFile); Xmin = min(Xmin, bx.minpt().m_x); @@ -151,7 +168,7 @@ WT_Result CSLNKSymbolDefinition::calculateBoundary () // Voor echte (deel)cirkels gaan we de diagonaal bounding box scherper berekenen if (obj->object_id() == WT_Object::Outline_Ellipse_ID || obj->object_id() == WT_Object::Filled_Ellipse_ID) - { + {//continue; WT_Ellipse *elp = (WT_Ellipse *)obj; if (elp->minor() == elp->major()) // Anders te ingewikkeld { // Bepaal het ingeschreven vierkant van de cirkel @@ -210,6 +227,7 @@ WT_Result CSLNKSymbolDefinition::calculateBoundary () // if (result == WT_Result::End_Of_DWF_Opcode_Found) // dwfresult = DwfResult::Success; + m_wtFile.heuristics().set_apply_transform(false); m_wtFile.close(); // Rechthoek @@ -217,7 +235,7 @@ WT_Result CSLNKSymbolDefinition::calculateBoundary () // WT_Logical_Point(Xmax, Ymin), // WT_Logical_Point(Xmax, Ymax), // WT_Logical_Point(Xmin, Ymax)}; - m_BoundingBox = WT_Logical_Box(Xmin, Ymin, Xmax, Ymax); + //m_BoundingBox = WT_Logical_Box(Xmin, Ymin, Xmax, Ymax); // Diamant heeft overflow risico // WT_Logical_Point pts2[4] = { WT_Logical_Point(Pmin2+Qmin2, Pmin2-Qmin2), @@ -235,9 +253,9 @@ WT_Result CSLNKSymbolDefinition::calculateBoundary () WT_Logical_Point(Qmin2+Ymax+Qmin2, Ymax), WT_Logical_Point(Xmin, Xmin-Qmin2-Qmin2), WT_Logical_Point(Xmin, Pmin2-Xmin+Pmin2)}; + m_Center = WT_Logical_Point(Xmin/2+Xmax/2,Ymin/2+Ymax/2); - m_BoundingContour.set(sizeof(pts3)/sizeof(pts3[0]), pts3, true); - m_Origin = CSLNKContourImpl::Centroid(m_BoundingContour); + BoundingContour.set(sizeof(pts3)/sizeof(pts3[0]), pts3, true); return result; } @@ -347,7 +365,8 @@ WT_Result CSLNKSymbolDefinition::serialize(WT_File & file) WD_False).serialize(file); return WT_Result::Success; } - if (m_BuiltIn) + + if (m_BuiltIn) // Die hebben alleen een bounding contour return WT_Result::Success; WT_Result result; diff --git a/SlnkDWFCom/SLNKSymbolDefImpl.h b/SlnkDWFCom/SLNKSymbolDefImpl.h index a6584f0..4a02864 100644 --- a/SlnkDWFCom/SLNKSymbolDefImpl.h +++ b/SlnkDWFCom/SLNKSymbolDefImpl.h @@ -16,12 +16,13 @@ public: WT_Logical_Box m_BoundingBox; WT_Polygon m_BoundingContour; WT_Logical_Point m_Origin; + 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 calculateBoundary(WT_Polygon &m_BoundingContour, WT_Transform *tm=NULL); private: bool m_BuiltIn; - WT_Result calculateBoundary(); WT_PNG_Group4_Image *m_AsBitmap; }; diff --git a/SlnkDWFCom/SLNKSymbolImpl.cpp b/SlnkDWFCom/SLNKSymbolImpl.cpp index 8fed14f..9b0b61f 100644 --- a/SlnkDWFCom/SLNKSymbolImpl.cpp +++ b/SlnkDWFCom/SLNKSymbolImpl.cpp @@ -45,7 +45,7 @@ WT_Result CSLNKSymbolImpl::serialize (WT_File & file, WT_Units & units, { LPInsertion *= wasTransform; } - // WT_Transform ondersteunt wel rotaties 0,90,180 en 270. Dat gaat echter altijd om DWF 0,0 + // WT_Transform ondersteunt wel rotaties 0,90,180 en 270. Dat gaat echter altijd om DWF 0,0 (oops: die om MAX_INT/2) // terwijl wij toch echt om ons insertionpoint willen. // Het (b)lijkt oplosbaar door ons punt te tegenroteren WT_Transform tr0; @@ -93,10 +93,10 @@ WT_Result CSLNKSymbolImpl::serialize (WT_File & file, WT_Units & units, // niet over verschaalde symbolen). if (dx*symbdef->m_Origin.m_x > INT_MAX || dy*symbdef->m_Origin.m_y > INT_MAX) { - throw myCString("\nSLNKDWF symbol coordinate overflow. Possible solutions:" + throw myCString("\nSLNKDWF symbol (%s)coordinate overflow. Possible solutions:" "\nDecrease drawing dwf resolution (%.6f)" "\nIncrease symbool dwf resolution (%.6f)" - "\nDecrease symbol scale (%.6f)",dScale, symbdef->m_dwgScale, m_Scale + "\nDecrease symbol scale (%.6f)",m_symbolName, dScale, symbdef->m_dwgScale, m_Scale ); } //myDoTRACE("\nSymbool m_Scale = %.6f, dScale = %.6f, symbdef->m_dwgScale = %.6f==>dx=%.6g", m_Scale, dScale, symbdef->m_dwgScale, dx); @@ -105,7 +105,8 @@ WT_Result CSLNKSymbolImpl::serialize (WT_File & file, WT_Units & units, WT_Logical_Point lshift(LPInsertion.m_x - myRound(dx*symbdef->m_Origin.m_x), LPInsertion.m_y - myRound(dy*symbdef->m_Origin.m_y)); - file.heuristics().set_transform(WT_Transform (lshift, dx, dy, m_Rotation)); + WT_Transform SymbolTrans (lshift, dx, dy, m_Rotation); + file.heuristics().set_transform(SymbolTrans); file.heuristics().set_apply_transform(true); #ifdef NO_BITMAPPEREN @@ -146,43 +147,35 @@ WT_Result CSLNKSymbolImpl::serialize (WT_File & file, WT_Units & units, //file.desired_rendition().color() = WT_Color(255, 0, 0, 0); //WT_Filled_Ellipse(symbdef->m_Center, 50, 50).serialize(file); -#ifdef _DEBUG - m_SLNKContour.m_outlineAlpha = 255; // Zichtbaar maken -#else - m_SLNKContour.m_outlineAlpha = 0; // Onzichtbaar maken -#endif // En vervolgens nog een mooi bounding contourtje er om heen. // Die is essentieel voor het aanwijzen. Doordat hierboven de alpha op 0 is gezet wordt hij wel transparant + // Om later clientside bij draggen verschuifproblemen te voorkomen bepalen we eventueel een nieuwe + // bounding contour alsof het symbool altijd al geroteerd gedefinieerd was op zijn definitieve positie. + // Contour is ook handig voor later teksten bijplaatsen maar pas wel op dat + // de contour al getransformeerd is naar de definitieve coordinaten ruimte (anders kregen we soms bij + // geroteerde symbolen overflow problemen) + // + + WT_Polygon pl; + symbdef->calculateBoundary(pl, &SymbolTrans); + if (pl.count()>0) + { + m_SLNKContour.set(pl.count(), pl.points(), true); + } + else // Builtin of bitmap + { + m_SLNKContour.transform(SymbolTrans); // Pas op: de bounds zijn nu misschien nog verkeerd + } + WT_Color().serialize(file); // Op de default zetten. file.desired_rendition().color() = file.rendition().color() = WT_Color(); + + file.heuristics().set_apply_transform(WD_False); // Hebben we al rechtstreeks op de contour gedaan m_SLNKContour.serialize(file, true); - - // Nu contour aanpassen. Is handig voor later teksten bijplaatsen - // Echter: die willen we exclusief 'wasTranform' hebben. Daarvoor tegencorrigeren we - // - LPInsertion = units.transform(insertion); - WT_Transform tr1; - tr1.set_rotation((360-m_Rotation)%360); - LPInsertion *= tr1; - lshift = WT_Logical_Point(LPInsertion.m_x - myRound(dx*symbdef->m_Origin.m_x), - LPInsertion.m_y - myRound(dy*symbdef->m_Origin.m_y)); - WT_Transform tm(lshift, dx, dy, m_Rotation); - m_SLNKContour.transform(tm); // Pas op: de bounds zijn nu misschien nog verkeerd -#if 0 - // Tegencorrectie werkte niet goed met rotatie. Daarom maar zoals hierboven - WT_Transform tm(file.heuristics().transform()); - WT_Logical_Point wasT(wasTransform.m_translate); - WT_Transform tr1; - tr1.set_rotation((360-m_Rotation)%360); - wasT *= tr1; - tm.m_translate.m_x -= wasT.m_x; - tm.m_translate.m_y -= wasT.m_y; - m_SLNKContour.transform(tm); // Pas op: de bounds zijn nu misschien nog verkeerd -#endif - + // En transform weer terug file.heuristics().set_transform(wasTransform); file.heuristics().set_apply_transform(wasApplyTransform); - // ASSERT: Deze werkt nu ook m_SLNKContour.serialize(file, true, true); + return result; }; diff --git a/SlnkDWFCom/SLNKdwf.rc b/SlnkDWFCom/SLNKdwf.rc index e52ad05..557a5bf 100644 --- a/SlnkDWFCom/SLNKdwf.rc +++ b/SlnkDWFCom/SLNKdwf.rc @@ -75,7 +75,7 @@ BEGIN VALUE "FileDescription", "Superlink DWF " VALUE "FileVersion", SLNK_BUILDVERSION "\0" VALUE "InternalName", "SLNKDWF.dll" - VALUE "LegalCopyright", "(c) Dijkoraad IT 2005-2007. All rights reserved." + VALUE "LegalCopyright", "(c) Dijkoraad IT 2005-2008. All rights reserved." VALUE "OriginalFilename", "SLNKDWF.dll" VALUE "ProductName", "Superlink" VALUE "ProductVersion", SLNK_BUILDVERSION "\0" diff --git a/SlnkDWFCom/Whip2PNG.cpp b/SlnkDWFCom/Whip2PNG.cpp index dc48ca9..de1e03b 100644 --- a/SlnkDWFCom/Whip2PNG.cpp +++ b/SlnkDWFCom/Whip2PNG.cpp @@ -151,6 +151,7 @@ bool CWhip2PNG::CreateCxImage(CxImage *img) myDoTRACE("CreateFromHBITMAP faalt??"); return false; } +#ifdef BITMAPROTATOR if (m_lRotation%360 == 90 || m_lRotation%360 == -270) img->RotateLeft(); @@ -160,6 +161,8 @@ bool CWhip2PNG::CreateCxImage(CxImage *img) if (m_lRotation == -180 || m_lRotation == 180) // Voor te draggen symbolen img->Rotate180(); + img->Rotate(m_lRotation); +#endif putDWGInfo(); // Generieke info naar het event DeleteObject(TmpBmp); @@ -292,9 +295,11 @@ STDMETHODIMP CWhip2PNG::Find(LONG findX, LONG findY, BSTR* foundLabel) InitDC(myDC); CString ContourLabel, ContourLayer, TextLabel, TextLayer; + double EdgeAngle, EdgeDistance; HRESULT res = m_iWhip2DC.Find(findX, findY, FALSE, - ContourLabel, ContourLayer, TextLabel, TextLayer); + ContourLabel, ContourLayer, TextLabel, TextLayer, + EdgeAngle, EdgeDistance); if (TextLabel != "") (*foundLabel) = TextLabel.AllocSysString(); @@ -310,6 +315,8 @@ STDMETHODIMP CWhip2PNG::Find(LONG findX, LONG findY, BSTR* foundLabel) m_SLNKEvent->put_ContourLayer(CComBSTR(ContourLayer)); m_SLNKEvent->put_TextLabel(CComBSTR(TextLabel)); m_SLNKEvent->put_TextLayer(CComBSTR(TextLayer)); + m_SLNKEvent->put_EdgeAngle(EdgeAngle); + m_SLNKEvent->put_EdgeDistance(EdgeDistance); putDWGInfo(); // Generieke info naar het event @@ -351,12 +358,20 @@ STDMETHODIMP CWhip2PNG::GetAsMap(BSTR* AsMap) // Er hoeft geen bitmap naar myDC omdat we toch niet painten // Let wel: daardoor kunnen we niet optimaliseren met RectVisible? InitDC(myDC); +#if 0 + // Werkt nog steeds niet voor CWhip2DCImpl::PolyToMap + HRGN hrgn = CreateRectRgn(0, 0, m_sizeX, m_sizeY); + ATLASSERT(hrgn); + SelectClipRgn(myDC, hrgn); +// ::SetViewportExtEx(myDC, m_sizeX, m_sizeY, NULL); +#endif //ReleaseDC(pDC); CString result, dummy; + double dDummy; HRESULT res = m_iWhip2DC.Find(0, 0, TRUE, /*AsMap*/ - result, dummy, dummy, dummy); + result, dummy, dummy, dummy, dDummy, dDummy); // Als we dan toch door de tekening zijn gegaan is dit wel handig om te hebben putDWGInfo(); // Generieke info naar het event @@ -510,7 +525,7 @@ void CWhip2PNG::InitDC(HDC &myDC) m_iWhip2DC.Load(myDC, epli, m_WhipPath, m_RegExp, myRound(m_sizeX*m_dScale), myRound(m_sizeY*m_dScale), - VARIANT_TRUE /*center*/, m_Maximize, m_dwgScale); + VARIANT_TRUE /*center*/, m_Maximize, m_dwgScale, m_lRotation); // Als m_dwgScale was gespecificeerd moeten we wel een goede bitmapgrootte kiezen if (m_dwgScale > 0.0) diff --git a/SlnkDWFCom/WhipFile.cpp b/SlnkDWFCom/WhipFile.cpp index aedcfe3..ae99193 100644 --- a/SlnkDWFCom/WhipFile.cpp +++ b/SlnkDWFCom/WhipFile.cpp @@ -44,7 +44,7 @@ CWhipFile::CWhipFile() m_FontName.set("Arial"); m_FontHeight = 400.0; m_FontHeightSymbols = 200.0; - + // Predefine fixed symbols CSLNKSymbolDefinition * symb = new CSLNKSymbolDefinition(sizeof(star)/sizeof(star[0]), star); m_State.m_SLNKSymbolDefinitions.SetAt("*STAR", symb); @@ -444,8 +444,10 @@ HRESULT CWhipFile::SerializePlan(WT_File & my_plan_file, myWT_File & my_file, do { case WT_Object::Drawable: if (firstDrawable) + { GenerateContouren(my_plan_file, my_file, scale, true); // Alle 'solid' kleuren - firstDrawable = false; + firstDrawable = false; + } #ifdef _DEBUG if (my_plan_file.current_object()->object_id() == WT_Object::Origin_ID && !my_file.heuristics().allow_binary_data() @@ -458,7 +460,9 @@ HRESULT CWhipFile::SerializePlan(WT_File & my_plan_file, myWT_File & my_file, do my_plan_file.current_object()->serialize(my_file); break; case WT_Object::Attribute: - { + { // TODO: Als !CurrentLayerOn dan zouden we ook nog fors kunnen schrappen in de WT_Attributes + // die vaak niet meer van toepassing zijn. Dan moeten we echter met desireded rendition gaan werken + // en dat is me nog even te veel werk. const WT_Attribute *obj = (WT_Attribute *)my_plan_file.current_object(); switch(obj->object_id()) { @@ -480,6 +484,7 @@ HRESULT CWhipFile::SerializePlan(WT_File & my_plan_file, myWT_File & my_file, do } } WT_Layer *ll = my_plan_file.layer_list().find_layer_from_index(layer_num); + // Noot: gooi de originele contour-lagen er altijd uit if (ll&& ll->layer_name().ascii()&& (m_State.labelMatch(ll->layer_name().ascii()) || @@ -489,6 +494,7 @@ HRESULT CWhipFile::SerializePlan(WT_File & my_plan_file, myWT_File & my_file, do CurrentLayerOn = FALSE; // Layer object hoeft ook niet meer geserialized else layer->serialize(my_file); + break; } default: { @@ -642,7 +648,14 @@ bool CWhipFile::GenerateSymbolLabels(myWT_File &my_file) // Tegenwoordig: CSLNKSymbolImpl::serialize heeft de contour al getransformeerd WT_Logical_Point center = m_State.m_contunits.transform(WT_Point3D(symbol->m_dwgX, symbol->m_dwgY)); symbol->m_SLNKContour.m_ptLabel = center; + + 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); + // En transform weer terug + my_file.heuristics().set_transform(wasTransform); + my_file.heuristics().set_apply_transform(wasApplyTransform); } return true; } @@ -673,6 +686,8 @@ bool CWhipFile::GenerateContouren(WT_File &my_planfile, myWT_File &my_file, { CSLNKContourImpl *contour= m_State.m_SLNKContouren[i]; my_file.desired_rendition().line_weight() = myRound(10 * scale); + if (!m_State.layerMatch("SLNK Contours")) + contour->m_outlineAlpha=0; // Onzichtbaar maken contour->serialize(my_file, solidOnly); } my_file.desired_rendition().object_node() = current_node; @@ -756,7 +771,7 @@ STDMETHODIMP CWhipFile::Generate(myWT_File &my_file) // Symbolen worden mogelijk geplaatst net buiten onze coordinatenruimte (met name X) // Dat gaf clipping problemen. // Daarom verplaatsen we alles in onze coordinatenruimte naar links/onder (0,0) - WT_Logical_Point lshift(-(max(0,this->m_view.view().m_min.m_x)), + WT_Logical_Point lshift(-(max(0,this->m_view.view().m_min.m_x)), -(max(0,this->m_view.view().m_min.m_y))); // Iets minder clipping van INT_MAX // Contouren hebben we ondertussen al wel/ // Nu nog een keer door de DWF om de rest te kopieren naar de output @@ -952,6 +967,14 @@ STDMETHODIMP CWhipFile::get_AddSymbol(DOUBLE dwgX, DOUBLE dwgY, BSTR symbolName, mySymbol->m_SLNKContour.m_Color = WT_Color(255,0,0,255); mySymbol->m_SLNKContour.m_outlineAlpha = 255; // Anders wordtie helemaal niet getekend? } + else + { +#ifdef _DEBUG + mySymbol->m_SLNKContour.m_outlineAlpha = 255; // Altijd Zichtbaar maken +#else + mySymbol->m_SLNKContour.m_outlineAlpha = g_SLNKOptions.m_SymbolOutlineAlpha; // default Onzichtbaar maken +#endif + } return S_OK; } diff --git a/SlnkDWFImpl/DWFFileImpl.cpp b/SlnkDWFImpl/DWFFileImpl.cpp index 716e19b..1e37ec0 100644 --- a/SlnkDWFImpl/DWFFileImpl.cpp +++ b/SlnkDWFImpl/DWFFileImpl.cpp @@ -188,6 +188,7 @@ bool CDWFFileImpl::Save() } return true; } +#endif bool CDWFFileImpl::Open(const CString &DWFPath) { @@ -247,7 +248,6 @@ bool CDWFFileImpl::Open(const CString &DWFPath) throw myCString ("\nCDWFFileImpl::Open('%s')\n%s", DWFPath, err); } } -#endif #if DESIRED_CODE(WHIP_OUTPUT) bool CDWFFileImpl::get_PropertiesXML(CString & pVal) diff --git a/SlnkDWFImpl/SLNKContourImpl.cpp b/SlnkDWFImpl/SLNKContourImpl.cpp index eb2b1c6..f8bc15b 100644 --- a/SlnkDWFImpl/SLNKContourImpl.cpp +++ b/SlnkDWFImpl/SLNKContourImpl.cpp @@ -2,6 +2,10 @@ #include "slnkcontourImpl.h" #include +#ifndef PI + #define PI 3.14159265358979323846 +#endif + #define PALETTE_RED 1 // Color in the default colormap is red. /*static*/ WT_Integer32 CSLNKContourImpl::m_next_node_num = 0; // Eigenlijk initialiseren op laatste van planfile @@ -61,9 +65,187 @@ BOOL CSLNKContourImpl::PointInPolygon(const CPoint pt, const CPoint *ps, int siz return c; } +// http://www.codeguru.com/forum/printthread.php?t=194400 +void DistanceFromLine(double cx, double cy, double ax, double ay , + double bx, double by, double &distanceSegment, + double &distanceLine) +{ + + // + // find the distance from the point (cx,cy) to the line + // determined by the points (ax,ay) and (bx,by) + // + // distanceSegment = distance from the point to the line segment + // distanceLine = distance from the point to the line (assuming + // infinite extent in both directions + // + +/* + +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 + of AC and AB divided by the square of the length of AB: + + (1) AC dot AB + 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 + 00 C is right of AB + s=0 C is on AB + + Compute s as follows: + + (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) + s = ----------------------------- + L^2 + + + Then the distance from C to P = |s|*L. + +*/ + + + double r_numerator = (cx-ax)*(bx-ax) + (cy-ay)*(by-ay); + double r_denomenator = (bx-ax)*(bx-ax) + (by-ay)*(by-ay); + double r = r_numerator / r_denomenator; +// + 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); + +// +// (xx,yy) is the point on the lineSegment closest to (cx,cy) +// + double xx = px; + double yy = py; + + if ( (r >= 0) && (r <= 1) ) + { + distanceSegment = distanceLine; + } + else + { + + double dist1 = (cx-ax)*(cx-ax) + (cy-ay)*(cy-ay); + double dist2 = (cx-bx)*(cx-bx) + (cy-by)*(cy-by); + if (dist1 < dist2) + { + xx = ax; + yy = ay; + distanceSegment = sqrt(dist1); + } + else + { + xx = bx ; + yy = by; + distanceSegment = sqrt(dist2); + } + + + } + + return; +} + +// 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)) +/*static*/ void CSLNKContourImpl::EdgeAngle(const WT_Logical_Point pt, const WT_Point_Set &ps, double &EdgeAngle, double &EdgeDistance) +{ + double ptx = pt.m_x; + double pty = pt.m_y; + int i, j, c = 0; + double minDistSeg = 0x7FFFFFFF; // Max WT_Integer32 + double minDistLine; + double angle = 0.0; + myTRACE("\npt = %d,%d", pt.m_x, pt.m_y); + for (i = 0, j = ps.count()-1; i < ps.count(); j = i++) { + WT_Logical_Point pt1 = ps.points()[i]; + WT_Logical_Point pt2 = ps.points()[j]; + double DistSeg, DistLine; + DistanceFromLine(pt.m_x, pt.m_y, + 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; + + //ASSERT(!(dx == 0 && dy == 0)); + + angle = atan2((double)dy, (double)dx) * (180 / PI); // Tussen -180 en +180 + if (dy==0) if (dx<0) angle=-180; else angle=0; + + myTRACE("\nDist %.1f angle set to: %.3f", DistSeg, angle); + minDistSeg = DistSeg; + minDistLine = DistLine; + } + } + if (DWFArea(ps) < 0) + EdgeAngle = angle; + else + EdgeAngle = 180+angle; + if (EdgeAngle < 0) EdgeAngle += 360; + EdgeDistance = minDistLine; //We rekenen met Seg maar projecteren uiteindelijk op Line +} + // Signed Area needed for centroid! // Negative is clockwise, Positve counterclockwise -/*static*/double CSLNKContourImpl::DWFArea(const WT_Polygon &pg) +/*static*/double CSLNKContourImpl::DWFArea(const WT_Point_Set &pg) { int i; double area = 0; @@ -121,7 +303,7 @@ WT_Logical_Point CSLNKContourImpl::LabelPosition(LABELPOS pos /*= LABEL_DEFAULT* } } -/*static*/WT_Logical_Point CSLNKContourImpl::Centroid(const WT_Polygon &pg) +/*static*/WT_Logical_Point CSLNKContourImpl::Centroid(const WT_Point_Set &pg) { double ptx = 0; double pty = 0; @@ -393,11 +575,14 @@ WT_Result CSLNKContourImpl::serialize(WT_File & file, BOOL solidOnly) { if (!m_fromSymbol && m_contLabel == "" && !solidOnly) // Alleen bij tweede slag { // May very well be a textobject itself, just emit it +#ifdef _DEBUG + // niet meer in release-mode file.desired_rendition().color() = WT_Color(PALETTE_RED, file.desired_rendition().color_map()); file.desired_rendition().line_weight() = 0; WT_Polyline my_line( count(), points(), WD_False); my_line.serialize(file); +#endif } else { // We have got a proper label/contour diff --git a/SlnkDWFImpl/SLNKContourImpl.h b/SlnkDWFImpl/SLNKContourImpl.h index b644e4a..4293b69 100644 --- a/SlnkDWFImpl/SLNKContourImpl.h +++ b/SlnkDWFImpl/SLNKContourImpl.h @@ -48,8 +48,9 @@ public: WT_Result serialize(WT_File & file, BOOL solidOnly); static BOOL PointInPolygon(const WT_Logical_Point pt, const WT_Point_Set &ps); static BOOL PointInPolygon(const CPoint pt, const CPoint *ps, int size); - static double DWFArea(const WT_Polygon &pg); - static WT_Logical_Point Centroid(const WT_Polygon &pg); + static void EdgeAngle(const WT_Logical_Point pt, const WT_Point_Set &ps, double &EdgeAngle, double &EdgeDistance); + static double DWFArea(const WT_Point_Set &pg); + static WT_Logical_Point Centroid(const WT_Point_Set &pg); WT_Logical_Point LabelPosition(LABELPOS pos = LABEL_DEFAULT); void SerializeLabel(WT_File &my_file, LABELPOS pos, int fontheight, diff --git a/SlnkDWFImpl/SLNKDWFStaticRW.vcproj b/SlnkDWFImpl/SLNKDWFStaticRW.vcproj index 0d4916d..fc839ea 100644 --- a/SlnkDWFImpl/SLNKDWFStaticRW.vcproj +++ b/SlnkDWFImpl/SLNKDWFStaticRW.vcproj @@ -5,6 +5,10 @@ Name="SLNKDWFStaticRW" ProjectGUID="{6EA5FCEC-1DB0-4542-8E41-9423021BD460}" RootNamespace="SLNKDWF" + + + + Keyword="AtlProj" > diff --git a/SlnkDWFImpl/Whip2DCImpl.cpp b/SlnkDWFImpl/Whip2DCImpl.cpp index 1484595..42f9eca 100644 --- a/SlnkDWFImpl/Whip2DCImpl.cpp +++ b/SlnkDWFImpl/Whip2DCImpl.cpp @@ -20,7 +20,7 @@ STDMETHODIMP CWhip2DCImpl::Load(HDC hDC, CEPlotSectionImpl *EPlotStream, const CString &WhipPath, const CString & RegExp, long sizeX, long sizeY, VARIANT_BOOL centerImage, VARIANT_BOOL maximize,/*=FALSE*/ - double dwgScale/*=0.0*/) + double dwgScale/*=0.0*/, long lRotation /*=0*/) { m_State.Reset(); @@ -29,6 +29,7 @@ STDMETHODIMP CWhip2DCImpl::Load(HDC hDC, CEPlotSectionImpl *EPlotStream, m_State.m_Layernames.RemoveAll(); m_State.m_centerImage = centerImage; m_State.m_Maximize = maximize; + m_State.m_lRotation = lRotation; m_iEPlotSection = EPlotStream; @@ -47,6 +48,8 @@ STDMETHODIMP CWhip2DCImpl::Load(HDC hDC, CEPlotSectionImpl *EPlotStream, // tussen DWF units en device units // maximize: Voor (draggable) symbolen moeten we de exacte extents/bounds weten // van de drawable entiteiten en doorzoeken we gegarandeerd de hele tekening + // TODO: Om helemaal bij client-side aan te sluiten moeten we de + // de extents van ((de extents van de boudingbox rechtop) geroteerd) gebruiken myWT_File my_input_file; // input file. if (m_iEPlotSection) { @@ -58,6 +61,16 @@ STDMETHODIMP CWhip2DCImpl::Load(HDC hDC, CEPlotSectionImpl *EPlotStream, my_input_file.set_filename(m_WhipPath.ascii()); m_State.m_mul=0; my_input_file.set_file_mode(WT_File::File_Read); + + 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); + 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()); @@ -100,10 +113,16 @@ STDMETHODIMP CWhip2DCImpl::Load(HDC hDC, CEPlotSectionImpl *EPlotStream, } case WT_Object::Drawable: { + if (!my_input_file.rendition().visibility().visible()) + break; WT_Drawable *obj = (WT_Drawable *)my_input_file.current_object(); - if (obj->object_id() != WT_Object::Origin_ID)// Belachelijk dat die Drawable is? + if (obj->object_id() != WT_Object::Origin_ID // Belachelijk dat die Drawable is? +// && obj->object_id() != WT_Object::Text_ID // Text roteert nog niet goed + ) { WT_Logical_Box bx = obj->bounds(&my_input_file); + ATLASSERT(bx.minpt().m_x<=bx.maxpt().m_x); + ATLASSERT(bx.minpt().m_y<=bx.maxpt().m_y); m_State.m_MinMax.minpt().m_x = min(m_State.m_MinMax.minpt().m_x, bx.minpt().m_x); m_State.m_MinMax.minpt().m_y = min(m_State.m_MinMax.minpt().m_y, bx.minpt().m_y); m_State.m_MinMax.maxpt().m_x = max(m_State.m_MinMax.maxpt().m_x, bx.minpt().m_x); @@ -202,6 +221,14 @@ STDMETHODIMP CWhip2DCImpl::Paint(VARIANT_BOOL forceBW) // m_State niet benaderen. Daarom maar via set_user_data my_input_file.heuristics().set_user_data((void *)&m_State); + 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_apply_transform(true); + } + my_input_file.set_file_mode(WT_File::File_Read); if (my_input_file.open() == WT_Result::Success) @@ -214,15 +241,12 @@ STDMETHODIMP CWhip2DCImpl::Paint(VARIANT_BOOL forceBW) SetTextColor(m_State.myDC, RGB(0, 0, 0)); // Standaard zit onze m_pen in de DC - // Alleen als echt nodig (w>1) stoppen we tijdelijk m_penExt erin. - // Die is wel trager namelijk m_State.m_pen = CreatePen(PS_INSIDEFRAME, 0, GetTextColor(m_State.myDC)); m_State.m_brush = CreateSolidBrush(GetTextColor(m_State.myDC)); LOGBRUSH b; b.lbColor = GetTextColor(m_State.myDC); //b.lbHatch = hatchCode; b.lbStyle = BS_SOLID; - m_State.m_penExt = ExtCreatePen(PS_GEOMETRIC, 0, &b, 0, NULL); HBRUSH oldbrush=(HBRUSH) SelectObject(m_State.myDC, m_State.m_pen); HPEN oldpen=(HPEN)SelectObject(m_State.myDC, m_State.m_brush); @@ -242,7 +266,6 @@ STDMETHODIMP CWhip2DCImpl::Paint(VARIANT_BOOL forceBW) SelectObject(m_State.myDC, oldpen); DeleteObject(m_State.m_brush); DeleteObject(m_State.m_pen); - DeleteObject(m_State.m_penExt); if (result != WT_Result::Success) throw myCString("\nCWhip2DCImpl::Paint: unable to read file '%s'", m_WhipPath.ascii()); @@ -333,6 +356,7 @@ STDMETHODIMP CWhip2DCImpl::Paint(VARIANT_BOOL forceBW) return S_OK; } +// Zoek alle teksten in de tekening op en lever ze op als array STDMETHODIMP CWhip2DCImpl::FindTexts(const CString &findText) { CmyTimer Timer("CWhip2DCImpl::FindText"); @@ -403,7 +427,8 @@ STDMETHODIMP CWhip2DCImpl::FindTexts(const CString &findText) STDMETHODIMP CWhip2DCImpl::Find(LONG findX, LONG findY, BYTE AsMap, CString & pContourLabel,CString & pContourLayer, - CString & pTextLabel, CString & pTextLayer) + CString & pTextLabel, CString & pTextLayer, + double &pEdgeAngle, double &pEdgeDistance) { CmyTimer Timer("CWhip2DCImpl::Find (includes AsMap)"); @@ -484,6 +509,8 @@ STDMETHODIMP CWhip2DCImpl::Find(LONG findX, LONG findY, { pContourLabel = CString(m_State.foundNode.object_node_name().ascii()); pContourLayer = m_State.foundNodeLayer; + pEdgeAngle = m_State.foundEdgeAngle; + pEdgeDistance = m_State.foundEdgeDistance; } } @@ -885,6 +912,7 @@ WT_Result CWhip2DCImpl::my_process_outlineEllipse (WT_Outline_Ellipse & outlineE return my_process_Ellipse(outlineEllipse, file, FALSE); } +// Genereer een een html fragment CString CWhip2DCImpl::PolyToMap(WT_Polygon & polygon, WT_Object_Node node, WT_URL URL, CWhip2DCState *m_State) @@ -899,18 +927,64 @@ CString CWhip2DCImpl::PolyToMap(WT_Polygon & polygon, return ""; } - for (int i = 0; i < polygon.count(); i++) +#if 0 +// het werkt niet:PtVisible levert altijd false op (omdat we geen bitmap selecteren in CWhip2PNG::GetAsMap? + BOOL anyVisible = false; // als de boundingcontour geheel buiten beeld valt is hij niet nodig + // Uit priaktische overwegingen implementeren we dat als: een + // hoekpunt van de bounding contour moet in beeld zijn +#endif + CString shape; + if (polygon.count() == 5 && // Linksom of rechtsom rechthoekig + ((polygon.points()[0].m_x == polygon.points()[1].m_x && + polygon.points()[1].m_y == polygon.points()[2].m_y && + polygon.points()[2].m_x == polygon.points()[3].m_x && + polygon.points()[3].m_y == polygon.points()[4].m_y + ) || + (polygon.points()[0].m_y == polygon.points()[1].m_y && + polygon.points()[1].m_x == polygon.points()[2].m_x && + polygon.points()[2].m_y == polygon.points()[3].m_y && + polygon.points()[3].m_x == polygon.points()[4].m_x + ) + ) + ) { - CPoint pt = m_State->DWFToLP(polygon.points()[i]); - LPtoDP(m_State->myDC, &pt, 1); - CString s; - s.Format("%s,%d,%d", ptList, pt.x, pt.y); - ptList = s; + shape = "rect"; + CPoint pt1 = m_State->DWFToLP(polygon.points()[0]); + CPoint pt2 = m_State->DWFToLP(polygon.points()[2]); +#if 0 + anyVisible|=PtVisible(m_State->myDC, pt1.x,pt1.y); + anyVisible|=PtVisible(m_State->myDC, pt2.x,pt1.y); + anyVisible|=PtVisible(m_State->myDC, pt2.x,pt2.y); + anyVisible|=PtVisible(m_State->myDC, pt1.x,pt2.y); +#endif + LPtoDP(m_State->myDC, &pt1, 1); + LPtoDP(m_State->myDC, &pt2, 1); + ptList.Format("%d,%d,%d,%d", min(pt1.x, pt2.x), min(pt1.y, pt2.y), + max(pt1.x, pt2.x), max(pt1.y, pt2.y)); + } + else + { + shape = "poly"; + for (int i = 0; i < polygon.count(); i++) + { + CPoint pt = m_State->DWFToLP(polygon.points()[i]); +#if 0 + anyVisible|=PtVisible(m_State->myDC, pt.x,pt.y); +#endif + LPtoDP(m_State->myDC, &pt, 1); + CString s; + s.Format("%s,%d,%d", ptList, pt.x, pt.y); + ptList = s; + } + ptList = ptList.Mid(1); // Eerste komma er af } - ptList = ptList.Mid(1); // Eerste komma er af +#if 0 + if (!anyVisible) + return ""; // Toch niet in beeld +#endif CString Coords, Title, Href; - Coords.Format("COORDS=\"%s\"", ptList); + Coords.Format("coords=\"%s\"", ptList); WT_URL_List lUrl = URL.url(); @@ -921,7 +995,7 @@ CString CWhip2DCImpl::PolyToMap(WT_Polygon & polygon, if (firstURL->address().length() == 0) Href = ""; else - Href.Format("HREF=\"%s\"", CString(firstURL->address().ascii())); + Href.Format("href=\"%s\"", CString(firstURL->address().ascii())); if (firstURL->friendly_name().is_ascii()) ttl = firstURL->friendly_name().ascii(); else @@ -931,18 +1005,19 @@ CString CWhip2DCImpl::PolyToMap(WT_Polygon & polygon, ttl = objKey; // Is dit wel zo logisch/wenselijk? ttl.Replace("\\n", "\n"); - Title.Format("TITLE=\"%s\"", ttl); + Title.Format("title=\"%s\"", ttl); CString smbl = ""; if (m_State->bIsSymbolLayer && objKey != "") - smbl.Format("SLNKSymbolKey=\"%s\"", objKey); + smbl.Format("\nSLNKSymbolKey=\"%s\"", objKey); CString Builder; - Builder.Format("\n", - Coords, Title, Href, smbl); + Builder.Format("\n", + shape, Coords, Title, Href, smbl); return Builder; }; +// Binnen DWF is een polygon altijd 'gevuld' WT_Result CWhip2DCImpl::my_process_polygon (WT_Polygon & polygon, WT_File & file) { CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data(); @@ -953,15 +1028,25 @@ WT_Result CWhip2DCImpl::my_process_polygon (WT_Polygon & polygon, WT_File & file { // Zo weinig mogelijk onze penExt gebruiken want die is trager. // Voor de arcering is hij mogelijk wel nodig - HPEN pOld = (HPEN)SelectObject(m_State->myDC, m_State->m_penExt); CPoint *vertexList = m_State->new_DWFToLP(polygon); - if (m_State->m_forceBW) // Dan nooit vullen + if (m_State->m_forceBW) // Dan nooit vullen, wel outline + { + HPEN pen = CreatePen(PS_SOLID, 0, RGB(0,0,0)); // Alleen outline tekenen + HPEN pOld = (HPEN)SelectObject(m_State->myDC, pen); Polyline(m_State->myDC, vertexList, polygon.count()); + SelectObject(m_State->myDC, pOld); + DeleteObject(pen); + } else if (m_State->m_alpha==255) // Normal polygon + { + HPEN pen = CreatePen(PS_NULL, 0, RGB(0,0,0)); // Geen outline tekenen + HPEN pOld = (HPEN)SelectObject(m_State->myDC, pen); Polygon(m_State->myDC, vertexList, polygon.count()); + SelectObject(m_State->myDC, pOld); + DeleteObject(pen); + } else m_State->AlphaPolygon(vertexList, polygon.count()); - SelectObject(m_State->myDC, pOld); } return WT_Result::Success; } @@ -972,10 +1057,14 @@ WT_Result CWhip2DCImpl::my_process_polygon_find (WT_Polygon & polygon, WT_File & if (!m_State->bLayerVisible) return WT_Result::Success; - // Kijk if we het punt gevonden hebben + // Kijk of we het punt gevonden hebben if (CSLNKContourImpl::PointInPolygon(m_State->DWFfindXY, polygon)) { m_State->foundNode = file.rendition().object_node(); + CSLNKContourImpl::EdgeAngle(m_State->DWFfindXY, polygon, m_State->foundEdgeAngle, m_State->foundEdgeDistance); + double scale = file.rendition().viewport().viewport_units().application_to_dwf_transform()(0,0); + m_State->foundEdgeDistance /= scale; + WT_Integer32 layer_num = file.rendition().layer().layer_num(); WT_Layer *ll = file.layer_list().find_layer_from_index(layer_num); if (ll&&ll->layer_name().ascii()) diff --git a/SlnkDWFImpl/Whip2DCImpl.h b/SlnkDWFImpl/Whip2DCImpl.h index de72a59..bf5ed6e 100644 --- a/SlnkDWFImpl/Whip2DCImpl.h +++ b/SlnkDWFImpl/Whip2DCImpl.h @@ -125,11 +125,12 @@ public: STDMETHOD(Load)(HDC hDC, CEPlotSectionImpl *EPlotSection, const CString &WhipPath, const CString &RegExp, long sizeX, long sizeY, VARIANT_BOOL centerImage, VARIANT_BOOL maximize=FALSE, - double dwgScale=0.0); + double dwgScale=0.0, long lRotation=0); STDMETHOD(Paint)(VARIANT_BOOL forceBW); STDMETHOD(Find)(LONG findX, LONG findY, BYTE AsMap, CString &pContourLabel, CString &pContourLayer, - CString &pTextLabel, CString &pTextLayer); + CString &pTextLabel, CString &pTextLayer, + double &EdgeAngle, double &EdgeDistance); STDMETHOD(FindTexts) (const CString &findText); STDMETHOD(DPtoDWG)(LONG findX, LONG findY, DOUBLE* resX, DOUBLE* resY); STDMETHOD(DWGExtents)(DOUBLE* resminX, DOUBLE* resminY, DOUBLE* resmaxX, DOUBLE* resmaxY); diff --git a/SlnkDWFImpl/Whip2DCState.cpp b/SlnkDWFImpl/Whip2DCState.cpp index 36b69ca..cbe96ea 100644 --- a/SlnkDWFImpl/Whip2DCState.cpp +++ b/SlnkDWFImpl/Whip2DCState.cpp @@ -4,7 +4,7 @@ #include #ifndef PI - #define PI 3.141592653589793f + #define PI 3.14159265358979323846 #endif CWhip2DCState::CWhip2DCState() @@ -31,6 +31,7 @@ void CWhip2DCState::Reset() m_font = NULL; m_forcePaper = false; m_Maximize = false; + m_lRotation = 0; } CWhip2DCState::~CWhip2DCState() @@ -537,8 +538,12 @@ void CWhip2DCState::AlphaPolygon(LPPOINT lpPoints, int nCount ) const myTRACE("\nHmmm, BitBlt failed?"); HBRUSH oldbrush = (HBRUSH) SelectObject(hMemDC,m_brush); + HPEN pen = CreatePen(PS_NULL, 0, RGB(0,0,0)); // Geen outline tekenen + HPEN pOld = (HPEN)SelectObject(hMemDC, pen); Polygon(hMemDC, lpPoints, nCount); + SelectObject(hMemDC, pOld); + DeleteObject(pen); SelectObject(hMemDC,oldbrush); diff --git a/SlnkDWFImpl/Whip2DCState.h b/SlnkDWFImpl/Whip2DCState.h index 0e18ece..2518355 100644 --- a/SlnkDWFImpl/Whip2DCState.h +++ b/SlnkDWFImpl/Whip2DCState.h @@ -40,7 +40,7 @@ public: LOGFONT m_logfont; WT_Integer32 m_spacing; WT_Integer32 m_height; // Niet afgeronde waarde voor SetupPixel - HPEN m_pen, m_penExt; + HPEN m_pen; HFONT m_font; HRGN m_hrgn; @@ -66,6 +66,7 @@ public: BOOL m_forceBW; BOOL m_Maximize; BOOL m_centerImage; + long m_lRotation; double m_mul; // schaal onze DWF-coordinaten naar bitmap coordinaten CSize m_Size; @@ -76,6 +77,8 @@ public: CString foundNodeLayer; CString foundTextLabel; CString foundTextLayer; + double foundEdgeAngle; + double foundEdgeDistance; WT_Logical_Point DWFfindXY; int geekFontSize;