1835 lines
59 KiB
C++
1835 lines
59 KiB
C++
// Whip2DCImpl.cpp : Implementation of CWhip2DCImpl
|
||
|
||
#include "stdafx.h"
|
||
|
||
#undef USE_CIMAGE
|
||
|
||
#include "Whip2DCImpl.h"
|
||
|
||
#ifndef USE_CIMAGE
|
||
#include "CxImage\CxImage\ximage.h"
|
||
#else
|
||
#include "atlimage.h"
|
||
#endif
|
||
|
||
#include "SLNKContourImpl.h"
|
||
|
||
// CWhip2DC
|
||
|
||
int 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*/)
|
||
{
|
||
m_State.Reset();
|
||
|
||
m_WhipPath = WhipPath;
|
||
m_State.myDC = hDC;
|
||
m_State.m_Layernames.RemoveAll();
|
||
m_State.m_centerImage = centerImage;
|
||
m_State.m_Maximize = maximize;
|
||
|
||
m_iEPlotSection = EPlotStream;
|
||
|
||
REParseError status = m_State.reLayers.Parse( CString(RegExp), false );
|
||
if (REPARSE_ERROR_OK != status)
|
||
{
|
||
myTRACE("\nSorry, kan reguliere expressie layersOn niet parsen");
|
||
// return E_FAIL;
|
||
}
|
||
|
||
m_State.m_Size = CSize(sizeX, sizeY);
|
||
|
||
// Om iets zinvols te kunnen doen moeten we altijd wel schaalinformatie hebben
|
||
// In het eenvoudigste geval komen we al heel rap een view of viewport tegen
|
||
// Die 'geloven' en gebruiken we. Daarmee kunnen we o.a. m_mul bepalen, de verhouding
|
||
// 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)
|
||
{
|
||
my_input_file.set_eplotsection(m_iEPlotSection);
|
||
m_State.m_ClipWidth = m_iEPlotSection->get_PaperClipWidth();
|
||
m_State.m_ClipHeight = m_iEPlotSection->get_PaperClipHeight();
|
||
}
|
||
else
|
||
my_input_file.set_filename(m_WhipPath.ascii());
|
||
m_State.m_mul=0;
|
||
my_input_file.set_file_mode(WT_File::File_Read);
|
||
|
||
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 = 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
|
||
&& (m_State.m_mul == 0 || maximize))
|
||
{
|
||
switch(my_input_file.current_object()->object_type())
|
||
{
|
||
case WT_Object::Attribute:
|
||
{
|
||
const WT_Attribute *obj = (WT_Attribute *)my_input_file.current_object();
|
||
if (obj->object_id() == WT_Object::View_ID)
|
||
{
|
||
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
|
||
break;
|
||
}
|
||
if (obj->object_id() == WT_Object::Viewport_ID)
|
||
{
|
||
if (m_State.m_mul == 0)
|
||
{
|
||
WT_Viewport *viewport = (WT_Viewport *)my_input_file.current_object();
|
||
dScale = viewport->viewport_units().application_to_dwf_transform()(0,0); // Symbol's dScale
|
||
if (!maximize)
|
||
{
|
||
WT_Logical_Point dwfPtmin = viewport->contour()->points()[0];
|
||
WT_Logical_Point dwfPtmax = viewport->contour()->points()[2];
|
||
m_State.SetExtents(WT_Logical_Box(dwfPtmin, dwfPtmax)); // m_mul wordt gezet en de loop eindigt
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
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?
|
||
// && 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);
|
||
m_State.m_MinMax.maxpt().m_y = max(m_State.m_MinMax.maxpt().m_y, bx.minpt().m_y);
|
||
m_State.m_MinMax.minpt().m_x = min(m_State.m_MinMax.minpt().m_x, bx.maxpt().m_x);
|
||
m_State.m_MinMax.minpt().m_y = min(m_State.m_MinMax.minpt().m_y, bx.maxpt().m_y);
|
||
m_State.m_MinMax.maxpt().m_x = max(m_State.m_MinMax.maxpt().m_x, bx.maxpt().m_x);
|
||
m_State.m_MinMax.maxpt().m_y = max(m_State.m_MinMax.maxpt().m_y, bx.maxpt().m_y);
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
//myTRACE("Skipping '%s'\n", wtFile->file_stats()->descriptions());
|
||
break;
|
||
}
|
||
}
|
||
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
|
||
}
|
||
result = my_input_file.close(); // closing Input file.
|
||
|
||
if (dwgScale > 0.0) // dwgSchaal geforceerd!
|
||
{ // Vooralsnog alleen getest met m_Maximize aan
|
||
double old_mul = m_State.m_mul;
|
||
CSize old_size = m_State.m_Size;
|
||
m_State.m_mul = 1.0/dwgScale/dScale;
|
||
|
||
if (m_State.m_Maximize) // Eventueel centreren ongedaan maken
|
||
m_State.m_MinMax = m_State.m_orgMinMax;
|
||
|
||
WT_Integer32 dwfDx = m_State.m_MinMax.maxpt().m_x - m_State.m_MinMax.minpt().m_x;
|
||
WT_Integer32 dwfDy = m_State.m_MinMax.maxpt().m_y - m_State.m_MinMax.minpt().m_y;
|
||
m_State.m_Size = CPoint(myRound(m_State.m_mul*dwfDx)+1, myRound(m_State.m_mul*dwfDy+1)+1);
|
||
m_State.m_Size.cx = max(m_State.m_Size.cx, 1);
|
||
m_State.m_Size.cy = max(m_State.m_Size.cy, 1);
|
||
|
||
myDoTRACE("\nm_mul forced from %.8f to %.8f and size from (%d, %d) to (%d, %d)",
|
||
old_mul, m_State.m_mul, old_size.cx,old_size.cy,m_State.m_Size.cx,m_State.m_Size.cy);
|
||
}
|
||
|
||
ATLASSERT(m_State.m_mul!=0);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
// Om onze definitieve bitmap grootte te kunnen bepalen
|
||
CSize &CWhip2DCImpl::get_Size()
|
||
{
|
||
return m_State.m_Size;
|
||
}
|
||
|
||
int CWhip2DCImpl::Paint(VARIANT_BOOL forceBW, VARIANT_BOOL markers /* = VARIANT_FALSE */)
|
||
{
|
||
#ifdef _DEBUG
|
||
/// CneutralGDI neutralGDI("CWhip2DCImpl::Paint");
|
||
#endif
|
||
|
||
//#define EXPERIMENT
|
||
// Helaas: bij sterk inzoomen (lijkt: m_mul > 1) komen er af en toe zwarte
|
||
// randen in de viewer te voorschijn
|
||
#ifdef EXPERIMENT
|
||
SetMapMode(m_State.myDC, MM_ANISOTROPIC);
|
||
SIZE wsz, vsz;
|
||
if (m_State.m_mul < 1.0)
|
||
{
|
||
SetWindowExtEx(m_State.myDC, myRound(m_State.m_Size.cx / m_State.m_mul), myRound(m_State.m_Size.cy / m_State.m_mul), &wsz);
|
||
SetViewportExtEx(m_State.myDC, m_State.m_Size.cx, m_State.m_Size.cy, &vsz);
|
||
}
|
||
else
|
||
{
|
||
SetWindowExtEx(m_State.myDC, m_State.m_Size.cx, m_State.m_Size.cy, &wsz);
|
||
SetViewportExtEx(m_State.myDC, myRound(m_State.m_Size.cx * m_State.m_mul), myRound(m_State.m_Size.cy * m_State.m_mul), &vsz);
|
||
}
|
||
m_State.m_mul = 1.0;
|
||
int mm = GetMapMode(m_State.myDC);
|
||
#endif
|
||
|
||
CmyTimer Timer("CWhip2DCImpl::Paint");
|
||
|
||
m_State.m_forceBW = forceBW;
|
||
m_State.findIt = FALSE;
|
||
|
||
SetBkMode(m_State.myDC, TRANSPARENT);
|
||
|
||
m_State.geekFontSize = 4; // 4pt en lager is toch niet leesbaar
|
||
// Overigens tikt dit vooral hard aan omdat we de
|
||
// rotatie van die kleine teksten niet meer zetten
|
||
|
||
myWT_File my_input_file; // input file.
|
||
|
||
if (m_iEPlotSection)
|
||
{
|
||
my_input_file.set_eplotsection(m_iEPlotSection);
|
||
if (!m_State.m_forcePaper)
|
||
{
|
||
m_State.m_paperColor = m_iEPlotSection->get_PaperColor();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!m_State.m_forcePaper)
|
||
{
|
||
m_State.m_paperColor = RGB(255,255,255); // Gok maar op wit. Echte kleur komt misschien wel
|
||
}
|
||
my_input_file.set_filename(m_WhipPath.ascii());
|
||
}
|
||
|
||
// Setup our default font
|
||
WT_Font myFont;
|
||
myFont.font_name().set("Arial");
|
||
myFont.height() = 100;
|
||
|
||
my_input_file.rendition().font() = myFont;
|
||
|
||
// Alle callback functies zijn static. Die kunnen de variabele
|
||
// m_State niet benaderen. Daarom maar via set_user_data
|
||
// Voortschrijdend inzicht: doorgeven van (void *)this was eigenlijk
|
||
// veel praktischer geweest. Bij whipfile.cpp doen we dat al sinds
|
||
// 2.80 maar hier is me dat nog even te veel werk.
|
||
my_input_file.heuristics().set_user_data((void *)&m_State);
|
||
|
||
my_input_file.set_file_mode(WT_File::File_Read);
|
||
|
||
if (my_input_file.open() == WT_Result::Success)
|
||
{
|
||
SetTextAlign(m_State.myDC,TA_LEFT|TA_BASELINE);
|
||
// Setup our default pen and brush
|
||
if (isDarkRGB(m_State.m_paperColor))
|
||
SetTextColor(m_State.myDC, RGB(255,255,255));
|
||
else
|
||
SetTextColor(m_State.myDC, RGB(0, 0, 0));
|
||
|
||
// Standaard zit onze m_pen in de DC
|
||
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;
|
||
|
||
HBRUSH oldbrush=(HBRUSH) SelectObject(m_State.myDC, m_State.m_pen);
|
||
HPEN oldpen=(HPEN)SelectObject(m_State.myDC, m_State.m_brush);
|
||
|
||
// Wis myDC met wit. Wordt mogelijk overruled in WT_Background
|
||
m_State.erasePaper(my_input_file);
|
||
WT_Result result = read_dwf_for_extracting_Objects(my_input_file, FALSE);
|
||
my_input_file.close(); // closing Input file.
|
||
|
||
// Alles opruimen
|
||
if (m_State.m_hrgn)
|
||
DeleteObject(m_State.m_hrgn);
|
||
if (m_State.m_font)
|
||
DeleteObject(m_State.m_font);
|
||
|
||
SelectObject(m_State.myDC, oldbrush);
|
||
SelectObject(m_State.myDC, oldpen);
|
||
DeleteObject(m_State.m_brush);
|
||
DeleteObject(m_State.m_pen);
|
||
|
||
if (result != WT_Result::Success)
|
||
throw myCString("\nCWhip2DCImpl::Paint: unable to read file '%s'", m_WhipPath.ascii());
|
||
}
|
||
else // TODO: Fatsoenlijke error terug
|
||
{
|
||
throw myCString("\nCWhip2DCImpl::Paint: unable to open file '%s'", m_WhipPath.ascii());
|
||
}
|
||
// For when user wants to use DPtoDWF
|
||
m_State.m_Units = my_input_file.rendition().viewport().viewport_units();
|
||
|
||
#if 0
|
||
{
|
||
// Raster er overheen
|
||
CRect clip;
|
||
GetClipBox(m_State.myDC,&clip); // Zichtbaar deel op scherm
|
||
SetBkMode(m_State.myDC, TRANSPARENT);
|
||
HBRUSH tempBrush = ::CreateHatchBrush(HS_DIAGCROSS, RGB(32,0,0));
|
||
HBRUSH tempBrush2 = ::CreateHatchBrush(HS_CROSS, RGB(0,64,0));
|
||
HBRUSH oldbrush = (HBRUSH) SelectObject(m_State.myDC,tempBrush);
|
||
CRect rc;
|
||
GetClipBox(m_State.myDC,&rc);
|
||
SetBrushOrgEx(m_State.myDC, 0, 0, NULL);
|
||
//Rectangle(m_State.myDC, clip.left,clip.top,clip.right,clip.bottom);
|
||
HBRUSH oldbrush2 = (HBRUSH) SelectObject(m_State.myDC,tempBrush2);
|
||
Rectangle(m_State.myDC, clip.left,clip.top,clip.right,clip.bottom);
|
||
SetBrushOrgEx(m_State.myDC, 2, 2, NULL);
|
||
Rectangle(m_State.myDC, clip.left,clip.top,clip.right,clip.bottom);
|
||
SetBrushOrgEx(m_State.myDC, 4, 4, NULL);
|
||
Rectangle(m_State.myDC, clip.left,clip.top,clip.right,clip.bottom);
|
||
SetBrushOrgEx(m_State.myDC, 6, 6, NULL);
|
||
Rectangle(m_State.myDC, clip.left,clip.top,clip.right,clip.bottom);
|
||
SelectObject(m_State.myDC,oldbrush2);
|
||
|
||
SelectObject(m_State.myDC,oldbrush);
|
||
DeleteObject(tempBrush);
|
||
DeleteObject(tempBrush2);
|
||
}
|
||
#endif
|
||
|
||
#ifdef _DEBUG
|
||
markers = VARIANT_TRUE;
|
||
#endif
|
||
|
||
if (markers)
|
||
{
|
||
// Toon bij sterk inzoomen een raster van DWF-punten ter referentie
|
||
LOGFONT lf;
|
||
memset(&lf, 0, sizeof(LOGFONT)); // clear out structure.
|
||
strncpy(lf.lfFaceName, "Tahoma", LF_FACESIZE);
|
||
lf.lfHeight = -10;
|
||
HFONT fnt = CreateFontIndirect(&lf);
|
||
HGDIOBJ oldfont = SelectObject(m_State.myDC, fnt);
|
||
|
||
if (m_State.m_mul > 10.0)
|
||
{
|
||
CRect clip;
|
||
GetClipBox(m_State.myDC,&clip); // Zichtbaar deel op scherm
|
||
|
||
WT_Logical_Point topleft(m_State.LPToDWF(clip.TopLeft()));
|
||
WT_Logical_Point botright(m_State.LPToDWF(clip.BottomRight()));
|
||
for (int x = topleft.m_x; x <= botright.m_x; x++)
|
||
for (int y = topleft.m_y; y >= botright.m_y; y--)
|
||
{
|
||
CPoint pt = m_State.DWFToLP(WT_Logical_Point(x, y));
|
||
SetPixel(m_State.myDC, pt.x, pt.y, RGB(128,128,128));
|
||
// Bij nog sterker inzoomen tonen we DWF-coordinaten
|
||
if (m_State.m_mul > 80.0)
|
||
{
|
||
CString txt;
|
||
txt.Format("%d", x);
|
||
TextOut(m_State.myDC, pt.x+5, pt.y, txt, txt.GetLength());
|
||
txt.Format("%d", y);
|
||
TextOut(m_State.myDC, pt.x+5, pt.y+10, txt, txt.GetLength());
|
||
}
|
||
}
|
||
}
|
||
SelectObject(m_State.myDC, oldfont);
|
||
DeleteObject(fnt);
|
||
|
||
// Pas op: geeft ASSERT's op te grote myRound binnen DWFToLP bij ver inzoomen
|
||
#if 0
|
||
//CPoint pt0 = m_State.DWFToLP(WT_Logical_Point(INT_MAX, 100000000));
|
||
//CPoint pt1 = m_State.DWFToLP(WT_Logical_Point(INT_MAX, -100000000));
|
||
HPEN m_pen = CreatePen(PS_SOLID, 3, RGB(255,255,0));
|
||
HPEN oldpen = (HPEN) SelectObject(m_State.myDC, m_pen);
|
||
MoveToEx(m_State.myDC, pt0.x, pt0.y, NULL);
|
||
|
||
LineTo(m_State.myDC, pt1.x, pt1.y);
|
||
#endif
|
||
}
|
||
return S_OK;
|
||
}
|
||
|
||
// Zoek alle teksten in de tekening op en lever ze op als array
|
||
int CWhip2DCImpl::FindTexts(const CString &findText)
|
||
{
|
||
CmyTimer Timer("CWhip2DCImpl::FindText");
|
||
|
||
m_State.bLayerVisible = TRUE; // When no layers at all
|
||
m_State.findIt = TRUE;
|
||
m_State.m_FoundTexts.RemoveAll();
|
||
|
||
m_State.foundTextLabel = "";
|
||
|
||
myWT_File my_input_file; // input file.
|
||
|
||
if (m_iEPlotSection)
|
||
my_input_file.set_eplotsection(m_iEPlotSection);
|
||
else
|
||
my_input_file.set_filename(m_WhipPath.ascii());
|
||
|
||
my_input_file.heuristics().set_user_data((void *)&m_State);
|
||
|
||
my_input_file.set_file_mode(WT_File::File_Read);
|
||
if (my_input_file.open() == WT_Result::Success)
|
||
{
|
||
WT_Result result;
|
||
my_input_file.set_polygon_action(my_process_polygon_find); // Requires polyline and fill too!
|
||
my_input_file.set_text_action(my_process_text_scan);
|
||
my_input_file.set_layer_action(my_process_layer);
|
||
|
||
// Do the actual reading.
|
||
do {
|
||
result = my_input_file.process_next_object();
|
||
} while (result == WT_Result::Success);
|
||
|
||
if (result == WT_Result::End_Of_DWF_Opcode_Found || result == WT_Result::User_Requested_Abort)
|
||
return WT_Result::Success;
|
||
else
|
||
return result;
|
||
}
|
||
else
|
||
myTRACE("\nSorry, kan file niet openen: %s", m_WhipPath);
|
||
|
||
// For when user wants to use DPtoDWF
|
||
m_State.m_Units = my_input_file.rendition().viewport().viewport_units();
|
||
|
||
my_input_file.close(); // closing Input file.
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
/*****************************************************************************\
|
||
* Name CWhip2DCImpl::Find()
|
||
* Input HDC dc
|
||
* LONG sizeX,
|
||
* LONG sizeY,
|
||
* LONG offsetX,
|
||
* LONG offsetY,
|
||
* DOUBLE dScale
|
||
* ....
|
||
* Action Zoek een in de tekening aangeklikt punt op
|
||
* of bepaal de clientside imagemap (voor tooltips)
|
||
* Deze laatste heeft als neveneffect dat SLNKEvent clientside
|
||
* gezet wordt waar we een heleboel info uit halen
|
||
* Return S_OK
|
||
*
|
||
* Called
|
||
* TODO: AsMap wordt voor steeds meer doeleinden gebruikt. Oppassen dat
|
||
* bijvoorbeeld extents wel correct worden bepaald
|
||
*****************************************************************************/
|
||
int CWhip2DCImpl::Find(LONG findX, LONG findY,
|
||
BYTE AsMap,
|
||
CString & pContourKey, CString & pContourLayer,
|
||
CString & pTextLabel, CString & pTextLayer,
|
||
double &pEdgeAngle, double &pEdgeDistance)
|
||
{
|
||
CmyTimer Timer("CWhip2DCImpl::Find (includes AsMap)");
|
||
|
||
m_State.bLayerVisible = TRUE; // When no layers at all
|
||
m_State.findIt = TRUE;
|
||
|
||
m_State.foundTextLabel = "";
|
||
|
||
// Note: At the first View we find we will fill
|
||
// DWFfindXY with the actual WT_logical coordinates
|
||
|
||
m_State.LPfindXY = CPoint(findX, findY);
|
||
DPtoLP(m_State.myDC, &m_State.LPfindXY, 1);
|
||
// Extents zijn in Load al bepaald, we kunnen ons zoekpunt in DWF-coordinaten bepalen
|
||
m_State.DWFfindXY = m_State.LPToDWF(m_State.LPfindXY);
|
||
myTRACE("\nZoeken naar : (%d, %d)-->(%d, %d)", m_State.LPfindXY.x, m_State.LPfindXY.y, m_State.DWFfindXY.m_x, m_State.DWFfindXY.m_y);
|
||
#ifdef _DEBUG
|
||
CPoint ptback = m_State.DWFToLP(m_State.DWFfindXY);
|
||
myTRACE("\nTerugvertaling: (%d, %d)\n", ptback.x, ptback.y);
|
||
#endif
|
||
|
||
myWT_File my_input_file; // input file.
|
||
|
||
// For TextExtent32
|
||
SetTextAlign(m_State.myDC,TA_LEFT|TA_BASELINE);
|
||
WT_Font myFont;
|
||
myFont.font_name().set("Arial"); // Real font will follow later
|
||
myFont.height() = 100;
|
||
my_input_file.rendition().font() = myFont;
|
||
|
||
// Papierkleur zetten voor Find lijkt onzinnig maar we willen
|
||
// de kleur na afloop kunnen opvragen als oMap.paperColor
|
||
if (m_iEPlotSection)
|
||
{
|
||
my_input_file.set_eplotsection(m_iEPlotSection);
|
||
if (!m_State.m_forcePaper)
|
||
{
|
||
m_State.m_paperColor = m_iEPlotSection->get_PaperColor();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
my_input_file.set_filename(m_WhipPath.ascii());
|
||
if (!m_State.m_forcePaper)
|
||
{
|
||
m_State.m_paperColor = RGB(255,255,255); // Gok maar op wit. Echte kleur komt misschien wel
|
||
}
|
||
}
|
||
|
||
// Alle callback functies zijn static. Die kunnen de variabele
|
||
// m_State niet benaderen. Daarom maar via set_user_data
|
||
my_input_file.heuristics().set_user_data((void *)&m_State);
|
||
|
||
my_input_file.set_file_mode(WT_File::File_Read);
|
||
if (my_input_file.open() == WT_Result::Success)
|
||
{
|
||
WT_Result result = read_dwf_for_extracting_Objects(my_input_file, TRUE);
|
||
}
|
||
else
|
||
myTRACE("\nSorry, kan file niet openen: %s", m_WhipPath);
|
||
|
||
// For when user wants to use DPtoDWF
|
||
m_State.m_Units = my_input_file.rendition().viewport().viewport_units();
|
||
|
||
my_input_file.close(); // closing Input file.
|
||
|
||
if (AsMap)
|
||
pContourKey = m_State.MapBuilder;
|
||
else
|
||
{
|
||
if (m_State.foundTextLabel != "")
|
||
{
|
||
pTextLabel = m_State.foundTextLabel;
|
||
pTextLayer = m_State.foundTextLayer;
|
||
}
|
||
|
||
if (m_State.foundNode.object_node_name())
|
||
{
|
||
pContourKey = CString(m_State.foundNode.object_node_name().ascii());
|
||
pContourLayer = m_State.foundNodeLayer;
|
||
pEdgeAngle = m_State.foundEdgeAngle;
|
||
pEdgeDistance = m_State.foundEdgeDistance;
|
||
}
|
||
}
|
||
|
||
// Alles opruimen
|
||
if (m_State.m_hrgn)
|
||
DeleteObject(m_State.m_hrgn);
|
||
if (m_State.m_font)
|
||
DeleteObject(m_State.m_font);
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
// Call Find() or Paint() first!!
|
||
int CWhip2DCImpl::DPtoDWG(LONG findX, LONG findY,
|
||
DOUBLE* resX, DOUBLE* resY)
|
||
{
|
||
m_State.LPfindXY = CPoint(findX, findY);
|
||
DPtoLP(m_State.myDC, &m_State.LPfindXY, 1);
|
||
|
||
if ((resX != NULL) && (resY != NULL))
|
||
{
|
||
if (m_State.m_mul==0) // Geen extents, vast ook geen transform
|
||
{
|
||
(*resX) = 0; // Zoek het maar lekker zelf uit
|
||
(*resY) = 0;
|
||
}
|
||
else
|
||
{
|
||
// Zoek de DWG coordinaten op
|
||
m_State.LPToDWG(m_State.LPfindXY, *resX, *resY);
|
||
}
|
||
}
|
||
return S_OK;
|
||
}
|
||
|
||
// Call Find() or Paint() first!!
|
||
int CWhip2DCImpl::DWGExtents(DOUBLE* resminX, DOUBLE* resminY,
|
||
DOUBLE* resmaxX, DOUBLE* resmaxY)
|
||
{
|
||
if (resminX && resminY && resmaxX && resmaxY)
|
||
{
|
||
if (m_State.m_mul==0) // Geen extents, vast ook geen transform
|
||
{
|
||
(*resminX) = (*resminY) = 0; // Zoek het maar lekker zelf uit
|
||
(*resmaxX) = (*resmaxY) = 0;
|
||
}
|
||
else
|
||
{
|
||
// Zoek de DWG coordinaten op
|
||
m_State.DWGExtents(*resminX, *resminY, *resmaxX, *resmaxY);
|
||
}
|
||
}
|
||
return S_OK;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::read_dwf_for_extracting_Objects(myWT_File &my_input_file, BOOL findIt)
|
||
{
|
||
WT_Result result;
|
||
// Defined actions.
|
||
|
||
if (!findIt) // When finding we don't need most handlers in the first place
|
||
{
|
||
my_input_file.set_color_action(my_process_color);
|
||
my_input_file.set_fill_pattern_action(my_process_fillPattern);
|
||
my_input_file.set_line_weight_action(my_process_lineWeight);
|
||
my_input_file.set_line_style_action(my_process_lineStyle);
|
||
my_input_file.set_line_pattern_action(my_process_linePattern);
|
||
my_input_file.set_filled_ellipse_action(my_process_filledEllipse);
|
||
my_input_file.set_outline_ellipse_action(my_process_outlineEllipse);
|
||
my_input_file.set_polytriangle_action(my_process_polytriangle);
|
||
my_input_file.set_polymarker_action(my_process_polymarker);
|
||
my_input_file.set_contour_set_action(my_process_contourSet);
|
||
my_input_file.set_png_group4_image_action(my_process_pngGroup4Image);
|
||
my_input_file.set_image_action(my_process_image);
|
||
my_input_file.set_gouraud_polyline_action(my_process_gouraudPolyline);
|
||
my_input_file.set_gouraud_polytriangle_action(my_process_gouraudPolytriangle);
|
||
my_input_file.set_polygon_action(my_process_polygon); // Requires polyline and fill too!
|
||
my_input_file.set_text_action(my_process_text);
|
||
my_input_file.set_polyline_action(my_process_polyline);
|
||
}
|
||
else // Use find-version
|
||
{
|
||
my_input_file.set_polygon_action(my_process_polygon_find); // Requires polyline and fill too!
|
||
my_input_file.set_text_action(my_process_text_find);
|
||
}
|
||
|
||
// The following are also necessary when finding
|
||
my_input_file.set_background_action(my_process_background); // setting m_paperColor
|
||
my_input_file.set_font_extension_action(my_process_font_extension);
|
||
my_input_file.set_font_action(my_process_font);
|
||
my_input_file.set_layer_action(my_process_layer);
|
||
my_input_file.set_viewport_action(my_process_viewport);
|
||
my_input_file.set_view_action(my_process_view);
|
||
|
||
// Do the actual reading.
|
||
do {
|
||
//CneutralGDI neutralGDI("read_dwf_for_extracting_Objects");
|
||
#ifdef _DEBUG
|
||
CString s(my_input_file.file_stats()->descriptions());
|
||
//myTRACE("Attribute '%s'\n", s);
|
||
#endif
|
||
if (m_progress_action)
|
||
{
|
||
int pos = my_input_file.file_pos();
|
||
size_t sz = my_input_file.size();
|
||
if (!m_progress_action(m_progress_param, (sz==0)?0:double(pos)/sz))
|
||
return WT_Result::User_Requested_Abort;
|
||
}
|
||
|
||
result = my_input_file.process_next_object();
|
||
} while (result == WT_Result::Success);
|
||
|
||
if (result == WT_Result::End_Of_DWF_Opcode_Found || result == WT_Result::User_Requested_Abort)
|
||
return WT_Result::Success;
|
||
else
|
||
return result;
|
||
}
|
||
|
||
// We gebruiken deze view als initial display
|
||
// Sinds we het scannen al in de load doen is deze obsolete
|
||
WT_Result CWhip2DCImpl::my_process_view (WT_View & view, WT_File & file)
|
||
{
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
// (Alleen) als we nog geen View hebben gehad gebruiken we de 1e Viewport
|
||
// als alternatief. Je moet toch wat. DWFPrinter doet dat
|
||
WT_Result CWhip2DCImpl::my_process_viewport (WT_Viewport & viewport, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
BOOL firstTime = (!file.rendition().viewport().contour());
|
||
file.rendition().viewport() = viewport;
|
||
|
||
// Voor de zekerheid opnieuw. ADT3_MTextFormattingCodesinScheduleTags.dwf had
|
||
// (waarschijnlijk door de DWFPrinter) de eerste (Font) voor de eerste (Viewport)
|
||
// en dan was de hoogte niet goed gezet
|
||
m_State->my_process_font(file.rendition().font());
|
||
|
||
double dScale = viewport.viewport_units().application_to_dwf_transform()(0,0);
|
||
myDoTRACE("\nThis viewport: 1 pixel = %.8f drawing units.", 1.0/(dScale*m_State->m_mul));
|
||
|
||
if (m_State->findIt) // When finding no need (or actually: support) for clipping
|
||
return WT_Result::Success;
|
||
|
||
if (!viewport.contour()) // dwftest_bc.dwf
|
||
{
|
||
SelectClipRgn(m_State->myDC, NULL);
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
// Viewports-ANSI A.dwf heeft diverse viewports
|
||
myTRACE("\nViewport met %d punten", viewport.contour()->total_points());
|
||
|
||
// TODO: Door afronding kan het gebeuren dat de clipregion ene pixel
|
||
// te ver naar binnen valt waardoor meest rechtse lijntjes wegvallen
|
||
// Daarom viewport ter grootte van minmax niet aanzetten
|
||
// NOOT: Ook riskant als later symbolen net buiten de extents geplaatst zijn?
|
||
if (firstTime)
|
||
{
|
||
myTRACE("\nSkipping 'region-all'");
|
||
SelectClipRgn(m_State->myDC, NULL); // Eventueel uitzetten
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
CPoint *vertexList =
|
||
m_State->new_DWFToLP(WT_Point_Set(viewport.contour()->total_points(),
|
||
viewport.contour()->points(), false));
|
||
|
||
// LET OP: CreatePolyPolygonRgn verwacht Device Units!
|
||
LPtoDP(m_State->myDC, vertexList, viewport.contour()->total_points());
|
||
if (m_State->m_hrgn)
|
||
DeleteObject(m_State->m_hrgn);
|
||
m_State->m_hrgn = CreatePolyPolygonRgn(vertexList, (int *)viewport.contour()->counts(),
|
||
viewport.contour()->contours(),
|
||
ALTERNATE);
|
||
ATLASSERT(m_State->m_hrgn);
|
||
|
||
int res = SelectClipRgn(m_State->myDC, m_State->m_hrgn);
|
||
ATLASSERT(res != ERROR);
|
||
#ifdef _DEBUG
|
||
{
|
||
CString s;
|
||
switch(res) {
|
||
case NULLREGION : s = "NULLREGION Region is empty."; break;
|
||
case SIMPLEREGION: s = "SIMPLEREGION Region is a single rectangle."; break;
|
||
case COMPLEXREGION: s = "COMPLEXREGION Region is more than one rectangle."; break;
|
||
case ERROR: s.Format("SelectClipRgn failed (%d): %s", GetLastError(), myGetLastErrorMsg()); break;
|
||
}
|
||
myTRACE("\nRegion aangemaakt: %s", s);
|
||
}
|
||
#endif
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_color (WT_Color & color, WT_File & file)
|
||
{
|
||
WT_Color::default_process(color, file);
|
||
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
|
||
m_State->ColorPenAndBrush(file);
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_lineWeight (WT_Line_Weight & lineWeight, WT_File & file)
|
||
{
|
||
WT_Line_Weight::default_process(lineWeight, file);
|
||
my_process_color(file.rendition().color(),file);
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_lineStyle (WT_Line_Style & lineStyle, WT_File & file)
|
||
{
|
||
WT_Line_Style::default_process(lineStyle, file);
|
||
my_process_color(file.rendition().color(),file);
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_linePattern (WT_Line_Pattern & linePattern, WT_File & file)
|
||
{
|
||
WT_Line_Pattern::default_process(linePattern, file);
|
||
my_process_color(file.rendition().color(),file);
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_layer (WT_Layer & layer, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
CString layer_name(layer.layer_name().ascii());
|
||
|
||
file.rendition().layer() = layer;
|
||
WT_Layer *ll;
|
||
|
||
if (layer_name != "") // Anders zittie alleen maar in de weg
|
||
{ // Dat doet de default_process 'fout'
|
||
// Overbodige lagen negeren we:
|
||
if (layer_name == m_State->m_activeLayerName)
|
||
return WT_Result::Success;
|
||
|
||
file.layer_list().add_layer(layer);
|
||
ll = &layer;
|
||
if (m_State->m_Layernames.Find(layer.layer_name().ascii()) < 0)
|
||
m_State->m_Layernames.Add(layer.layer_name().ascii());
|
||
}
|
||
else
|
||
{
|
||
WT_Integer32 layer_num = layer.layer_num();
|
||
ll = file.layer_list().find_layer_from_index(layer_num);
|
||
}
|
||
|
||
if (ll)
|
||
{
|
||
// Overbodige lagen negeren we:
|
||
if (ll->layer_name().ascii() == m_State->m_activeLayerName)
|
||
return WT_Result::Success;
|
||
|
||
m_State->m_activeLayerName = ll->layer_name().ascii();
|
||
|
||
//myTRACE("\n my_output_file.desired_rendition().layer() = layer %s;", layer.layer_name().ascii());
|
||
CAtlREMatchContext<> mcUrl;
|
||
if ( m_State->reLayers.Match(m_State->m_activeLayerName, &mcUrl))
|
||
{
|
||
//myTRACE(".. does match!");
|
||
m_State->bLayerVisible = TRUE;
|
||
}
|
||
else
|
||
{
|
||
m_State->bLayerVisible = FALSE;
|
||
// myTRACE("\nLayer %s .. does not match", ll->layer_name().ascii());
|
||
}
|
||
|
||
// myTRACE("\nLayer %s .. does not match", ll->layer_name().ascii());
|
||
m_State->bIsSymbolLayer = (m_State->m_activeLayerName == "SLNK Symbols");
|
||
//myDoTRACE("\nLayer %s %d", ll->layer_name().ascii(), m_State->bIsSymbolLayer);
|
||
}
|
||
else
|
||
{
|
||
myTRACE("\nNo layer name for contour. Assuming match");
|
||
m_State->bLayerVisible = TRUE;
|
||
m_State->bIsSymbolLayer = FALSE;
|
||
}
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_font_extension (WT_Font_Extension & font_extension, WT_File & file)
|
||
{
|
||
// myTRACE("\n !! Don't know how to handle font_extension yet!! (%s/%s)",
|
||
// font_extension.logfont_name().ascii(), font_extension.cannonical_name().ascii());
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_font (WT_Font & font, WT_File & file)
|
||
{
|
||
WT_Font::default_process ( font, file);
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
|
||
m_State->my_process_font(file.rendition().font());
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
// Merk op: gewone cirkels komen ook hier binnen met Ellipse.start()+65536==Ellipse.end()
|
||
WT_Result CWhip2DCImpl::my_process_Ellipse (WT_Ellipse & Ellipse, WT_File & file, WT_Boolean fill)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
//TODO: De tilt correct meenemen als hij niet orthogonaal is
|
||
// Overigens nog nooit gezien
|
||
WT_Integer32 minor=Ellipse.minor();
|
||
WT_Integer32 major=Ellipse.major();
|
||
WT_Logical_Point pos = Ellipse.position();
|
||
|
||
if (minor<0||major<0)
|
||
{ // Gebeurde bij "Inventor_Engine _2D.dwf".
|
||
return WT_Result::Success; // Negeren
|
||
}
|
||
|
||
switch (Ellipse.tilt())
|
||
{
|
||
case 0: break;
|
||
case 32768: break;
|
||
case 16384:
|
||
case 49152:
|
||
{
|
||
int tmp=major;major=minor;minor=tmp;
|
||
break;
|
||
}
|
||
default:
|
||
if (major != minor)
|
||
myTRACE("\nNiet-ortho tilt (%d) nog niet ondersteund (%d,%d)", Ellipse.tilt(), pos.m_x, pos.m_y);
|
||
}
|
||
|
||
double start = Ellipse.start_radian();
|
||
double end = Ellipse.end_radian();
|
||
double tilt = Ellipse.tilt_radian();
|
||
|
||
#define SC 5
|
||
// Bij GDI hoeven de referentiepunten niet op de ellipse te liggen
|
||
// En door SC hebben we betere resolutie
|
||
WT_Logical_Point ls(pos.m_x+myRound(cos(start+tilt)*SC*major),
|
||
pos.m_y+myRound(sin(start+tilt)*SC*minor));
|
||
WT_Logical_Point le(pos.m_x+myRound(cos(end +tilt)*SC*major),
|
||
pos.m_y+myRound(sin(end +tilt)*SC*minor));
|
||
|
||
CPoint s = m_State->DWFToLP(ls);
|
||
CPoint e = m_State->DWFToLP(le);
|
||
|
||
#ifdef _DEBUG
|
||
// Toon aanhaallijnen
|
||
if (m_State->m_mul>10)
|
||
{
|
||
HPEN p2 = CreatePen (PS_DOT, 0, RGB(128,128,128));
|
||
HPEN oldpen = (HPEN) SelectObject(m_State->myDC, p2);
|
||
|
||
CPoint acPt = m_State->DWFToLP(pos);
|
||
m_State->Marker(acPt);
|
||
MoveToEx(m_State->myDC, s.x, s.y, (LPPOINT) NULL);
|
||
LineTo (m_State->myDC, acPt.x, acPt.y);
|
||
LineTo (m_State->myDC, e.x, e.y);
|
||
|
||
SelectObject(m_State->myDC, oldpen);
|
||
DeleteObject(p2);
|
||
}
|
||
#endif
|
||
if ( Ellipse.start()+65536!=Ellipse.end()
|
||
&& _hypot(e.x-s.x, e.y-s.y)<2.0)
|
||
{ // Voorkom onbedoelde volledige cirkels als s==e door afronding
|
||
// Wel de niet-uitvergrootte versies
|
||
WT_Logical_Point ls(pos.m_x+myRound(cos(start+tilt)*major),
|
||
pos.m_y+myRound(sin(start+tilt)*minor));
|
||
WT_Logical_Point le(pos.m_x+myRound(cos(end +tilt)*major),
|
||
pos.m_y+myRound(sin(end +tilt)*minor));
|
||
CPoint s = m_State->DWFToLP(ls);
|
||
CPoint e = m_State->DWFToLP(le);
|
||
MoveToEx(m_State->myDC, s.x, s.y, NULL);
|
||
LineTo(m_State->myDC, e.x, e.y);
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
CPoint topleft = m_State->DWFToLP(WT_Logical_Point(pos.m_x-major, pos.m_y-minor));
|
||
CPoint bottomright = m_State->DWFToLP(WT_Logical_Point(pos.m_x+major, pos.m_y+minor));
|
||
if (fill)
|
||
{
|
||
SetPolyFillMode(m_State->myDC, ALTERNATE);
|
||
::Ellipse(m_State->myDC, topleft.x, topleft.y,
|
||
bottomright.x, bottomright.y);
|
||
}
|
||
else
|
||
{
|
||
if (Ellipse.start() + 65536 == Ellipse.end())
|
||
{
|
||
// Voorkom afrondfouten. ::Ellipse zou gaan vullen
|
||
e=s;
|
||
}
|
||
SetArcDirection(m_State->myDC, AD_COUNTERCLOCKWISE);
|
||
Arc(m_State->myDC, topleft.x, topleft.y,
|
||
bottomright.x, bottomright.y,
|
||
s.x, s.y, e.x, e.y);
|
||
}
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_filledEllipse (WT_Filled_Ellipse & filledEllipse, WT_File & file)
|
||
{
|
||
return my_process_Ellipse(filledEllipse, file, TRUE);
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_outlineEllipse (WT_Outline_Ellipse & outlineEllipse, WT_File & file)
|
||
{
|
||
return my_process_Ellipse(outlineEllipse, file, FALSE);
|
||
}
|
||
|
||
// Genereer een een html <area> fragment
|
||
CString CWhip2DCImpl::PolyToMap(WT_Polygon & polygon,
|
||
WT_Object_Node node, WT_URL URL,
|
||
CWhip2DCState *m_State)
|
||
{
|
||
CString objKey = node.object_node_name().ascii(); // Zo doen wij dat namelijk
|
||
|
||
CString ptList;
|
||
double opp = CSLNKContourImpl::DWFArea(polygon)*m_State->m_mul*m_State->m_mul;
|
||
if (abs(opp) < 10) // Clientside minder dan 10 pixels
|
||
{
|
||
myTRACE("\nSkipping oppervlakte %.6f", opp);
|
||
return "";
|
||
}
|
||
|
||
#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
|
||
)
|
||
)
|
||
)
|
||
{
|
||
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
|
||
}
|
||
|
||
#if 0
|
||
if (!anyVisible)
|
||
return ""; // Toch niet in beeld
|
||
#endif
|
||
CString Coords, Title, Href;
|
||
Coords.Format("coords=\"%s\"", ptList);
|
||
|
||
WT_URL_List lUrl = URL.url();
|
||
|
||
CString ttl;
|
||
if (lUrl.count()>0)
|
||
{
|
||
WT_URL_Item *firstURL = (WT_URL_Item *)lUrl.get_head();
|
||
if (firstURL->address().length() == 0)
|
||
Href = "";
|
||
else
|
||
Href.Format(" href=\"%s\"", CString(firstURL->address().ascii()));
|
||
if (firstURL->friendly_name().is_ascii())
|
||
ttl = firstURL->friendly_name().ascii();
|
||
else
|
||
ttl = CStringW(firstURL->friendly_name().unicode());
|
||
}
|
||
//else
|
||
// ttl = objKey; // Is dit wel zo logisch/wenselijk?
|
||
|
||
ttl.Replace("\\n", "\n");
|
||
Title.Format("title=\"%s\"", ttl);
|
||
|
||
CString smbl = "";
|
||
if (objKey != "")
|
||
{
|
||
// SLNKSymbolKey voor FACILITOR 5.3.1 backward compatible
|
||
if (m_State->bIsSymbolLayer)
|
||
smbl.Format(" SLNKSymbolKey=\"%s\" SLNKKey=\"%s\"", objKey, objKey);
|
||
else
|
||
smbl.Format(" SLNKKey=\"%s\"", objKey);
|
||
}
|
||
|
||
CString Builder;
|
||
Builder.Format("\n<area%s %s shape=\"%s\" %s%s>",
|
||
smbl, Title, shape, Coords, Href);
|
||
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();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
if (m_State->m_alpha>0) // Niet geheel doorzichtig
|
||
{
|
||
// Zo weinig mogelijk onze penExt gebruiken want die is trager.
|
||
// Voor de arcering is hij mogelijk wel nodig
|
||
CPoint *vertexList = m_State->new_DWFToLP(polygon);
|
||
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());
|
||
}
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_polygon_find (WT_Polygon & polygon, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
// 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())
|
||
{
|
||
myTRACE("op laag '%s'", ll->layer_name().ascii());
|
||
m_State->foundNodeLayer = ll->layer_name().ascii();
|
||
}
|
||
}
|
||
|
||
#if 0
|
||
Werkt niet goed: het (b)lijkt dat bij clipbox altijd leeg is (omdat we geen bitmap in de DC hebben?)
|
||
// Imagemap opbouwen. Alleen voor die entiteiten die (deels) in beeld zijn
|
||
WT_Logical_Box bx = polygon.bounds(&file);
|
||
CRect rc(m_State->DWFToLP(bx.minpt()), m_State->DWFToLP(bx.maxpt()));
|
||
CRect clip;
|
||
GetClipBox(m_State->myDC,&clip);
|
||
CRect res;
|
||
if (!res.IntersectRect(clip, rc)) // Niet geheel erbuiten
|
||
return WT_Result::Success; // Toch niet zichtbaar
|
||
#endif
|
||
// Achterwaarts opbouwen. Laatste getekende staat dan vooraan de Map
|
||
// en wordt als eerste gevonden
|
||
m_State->MapBuilder = PolyToMap(polygon,
|
||
file.rendition().object_node(),
|
||
file.rendition().url(),
|
||
m_State ) + m_State->MapBuilder;
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_polymarker (WT_Polymarker & polymarker, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
// TODO: Dit moet nog beter. Kleur en zo en de goede markers
|
||
//if (file.rendition().m_marker_symbol()
|
||
for (int i = 0; i < polymarker.count(); i++)
|
||
{
|
||
CPoint acPt = m_State->DWFToLP(polymarker.points()[i]);
|
||
SetPixel(m_State->myDC, acPt.x, acPt.y, RGB(128,128,128));
|
||
#ifdef _DEBUG
|
||
m_State->Marker(acPt);
|
||
#endif
|
||
}
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
// Wordt bijvoorbeeld gegenereerd voor ScalaSans truetype teksten die gerenderd worden
|
||
WT_Result CWhip2DCImpl::my_process_contourSet (WT_Contour_Set & contourSet, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
CPoint *vertexList = m_State->new_DWFToLP(WT_Point_Set(contourSet.total_points(), contourSet.points(), false));
|
||
|
||
PolyPolygon(m_State->myDC, vertexList, (int *)contourSet.counts(), contourSet.contours()); // No Alpha support
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
// Gesignaleerd: locatie.dwf kleine roze solid cirkels
|
||
// en H_BRNDMLDR.dwf (overshoots na verkleining?)
|
||
WT_Result CWhip2DCImpl::my_process_polytriangle (WT_Polytriangle & polytriangle, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
SetPolyFillMode(m_State->myDC, ALTERNATE);
|
||
CPoint *vertexList = m_State->new_DWFToLP(WT_Point_Set(polytriangle.count(), polytriangle.points(), false));
|
||
|
||
// Het volgende is wel iets efficienter maar werkt niet goed omdat
|
||
// de volgorde van de punten van de triangles niet netjes een polygon vormt
|
||
// Eigenlijk moet het echter wel: wij krijgen nu een outline om iedere triangle
|
||
// wat niet de boeling is
|
||
// Polygon(m_State->myDC, vertexList, polytriangle.count());
|
||
// return WT_Result::Success;
|
||
|
||
// Die is veel sneller en dunner en heeft geen last van Miter/overshooting spikes
|
||
HPEN ThinPen = CreatePen(PS_SOLID, 0, GetTextColor(m_State->myDC));
|
||
HPEN pOld = (HPEN)SelectObject(m_State->myDC, ThinPen);
|
||
|
||
//Het volgende is een alternatief voor ThinPen
|
||
//FLOAT oldMiter;
|
||
//SetMiterLimit(m_State->myDC, 1.0, &oldMiter);
|
||
for (int i = 0; i < polytriangle.count()-2; i++)
|
||
{
|
||
Polygon(m_State->myDC, vertexList+i, 3);
|
||
}
|
||
//SetMiterLimit(m_State->myDC, oldMiter, NULL);
|
||
SelectObject(m_State->myDC, pOld);
|
||
DeleteObject(ThinPen);
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_pngGroup4Image (WT_PNG_Group4_Image & pngGroup4Image, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
CPoint Pt1 = m_State->DWFToLP(pngGroup4Image.min_corner());
|
||
CPoint Pt2 = m_State->DWFToLP(pngGroup4Image.max_corner());
|
||
int dx = Pt2.x - Pt1.x;
|
||
int dy = Pt1.y - Pt2.y;
|
||
if (dx==0 || dy==0)
|
||
return WT_Result::Success;
|
||
|
||
// Is de tekst uberhaubt zichtbaar? Laat anders maar
|
||
if (GetDeviceCaps(m_State->myDC, TECHNOLOGY) != DT_METAFILE &&
|
||
GetObjectType(m_State->myDC) != OBJ_ENHMETADC)
|
||
{
|
||
CRect textRect(Pt1, Pt2); // Tikkie grof voor diagonale teksten. Better safe than sorry
|
||
|
||
if (!RectVisible(m_State->myDC, textRect))
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
//CString s;
|
||
//s.Format("CWhip2DCImpl::my_process_pngGroup4Image sz=%d dx=%d dy=%d",
|
||
// pngGroup4Image.data_size(), dx, dy);
|
||
//CmyTimer p(s);
|
||
|
||
#ifdef USE_CIMAGE
|
||
HGLOBAL m_hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, pngGroup4Image.data_size());
|
||
if (m_hBuffer)
|
||
{
|
||
void* pBuffer = ::GlobalLock(m_hBuffer);
|
||
if (pBuffer)
|
||
{
|
||
CopyMemory(pBuffer, pngGroup4Image.data(), pngGroup4Image.data_size());
|
||
|
||
IStream* pStream = NULL;
|
||
if (::CreateStreamOnHGlobal(m_hBuffer, FALSE, &pStream) == S_OK)
|
||
{
|
||
CImage m_pBitmap;
|
||
HRESULT res = m_pBitmap.Load(pStream);
|
||
pStream->Release();
|
||
if (SUCCEEDED(res))
|
||
{
|
||
::SetStretchBltMode(m_State->myDC, HALFTONE) ;
|
||
m_pBitmap.Draw(m_State->myDC, Pt1.x, Pt2.y, dx, dy);
|
||
}
|
||
}
|
||
::GlobalUnlock(m_hBuffer);
|
||
}
|
||
::GlobalFree(m_hBuffer);
|
||
m_hBuffer = NULL;
|
||
}
|
||
|
||
#else
|
||
CxImage img;
|
||
|
||
DWORD fmt = CXIMAGE_FORMAT_UNKNOWN;
|
||
switch (pngGroup4Image.format())
|
||
{
|
||
case WD_IMAGE_GROUP4X_MAPPED_EXT_OPCODE:
|
||
{
|
||
fmt = CXIMAGE_FORMAT_UNKNOWN;
|
||
break;
|
||
}
|
||
case WD_IMAGE_GROUP4_BITONAL_EXT_OPCODE:
|
||
{
|
||
fmt = CXIMAGE_FORMAT_TIF;
|
||
break;
|
||
}
|
||
case WD_IMAGE_PNG_EXT_OPCODE:
|
||
{
|
||
fmt = CXIMAGE_FORMAT_PNG;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (img.Decode((BYTE *) pngGroup4Image.data(),
|
||
pngGroup4Image.data_size(),
|
||
fmt))
|
||
{
|
||
if (m_State->m_ClipWidth > 0)
|
||
{
|
||
double inchWidth = m_State->m_ClipWidth
|
||
*(pngGroup4Image.max_corner().m_x - pngGroup4Image.min_corner().m_x)
|
||
/(m_State->m_MinMax.maxpt().m_x-m_State->m_MinMax.minpt().m_x);
|
||
double dpi=double(img.GetWidth()) / inchWidth;
|
||
myDoTRACE("\nGuessing raster dpi: %d", myRound(dpi));
|
||
}
|
||
// Forceert *niet* transparant
|
||
// Telecommunications.dwf heeft iets van transparante PNG's wat niet niets toonde
|
||
// (GDI+ deed dat wel goed)
|
||
//img.SetTransIndex(-1);
|
||
//Draw2 (b)lijkt transparantie (op zwarte achtergrond) alleen goed te doen al we achtergrond/voorgrond zetten
|
||
COLORREF keepBk = SetBkColor(m_State->myDC, RGB(255, 255, 255));
|
||
COLORREF keepText = SetTextColor(m_State->myDC, RGB(0, 0, 0));
|
||
|
||
img.Draw2(m_State->myDC, Pt1.x, Pt2.y, dx, dy);
|
||
|
||
SetBkColor(m_State->myDC, keepBk);
|
||
SetTextColor(m_State->myDC, keepText);
|
||
}
|
||
else
|
||
myDoTRACE("\nimg.Decode failed: %s", img.GetLastError());
|
||
#endif
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
// Wordt gebruikt voor JPG's
|
||
WT_Result CWhip2DCImpl::my_process_image (WT_Image & image, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
DWORD fmt = CXIMAGE_FORMAT_UNKNOWN;
|
||
switch (image.format())
|
||
{
|
||
case WD_IMAGE_JPEG_EXT_OPCODE:
|
||
{
|
||
fmt = CXIMAGE_FORMAT_JPG;
|
||
break;
|
||
}
|
||
}
|
||
if (image.format() != WD_IMAGE_JPEG_EXT_OPCODE)
|
||
{
|
||
myTRACE("\nWT_Image format %d not supported", image.format());
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
CPoint Pt1 = m_State->DWFToLP(image.min_corner());
|
||
CPoint Pt2 = m_State->DWFToLP(image.max_corner());
|
||
|
||
#ifdef USE_CIMAGE
|
||
HGLOBAL m_hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, image.data_size());
|
||
if (m_hBuffer)
|
||
{
|
||
void* pBuffer = ::GlobalLock(m_hBuffer);
|
||
if (pBuffer)
|
||
{
|
||
CopyMemory(pBuffer, image.data(), image.data_size());
|
||
|
||
IStream* pStream = NULL;
|
||
if (::CreateStreamOnHGlobal(m_hBuffer, FALSE, &pStream) == S_OK)
|
||
{
|
||
CImage m_pBitmap;
|
||
HRESULT res = m_pBitmap.Load(pStream);
|
||
pStream->Release();
|
||
if (SUCCEEDED(res))
|
||
{
|
||
::SetStretchBltMode(m_State->myDC, HALFTONE) ;
|
||
m_pBitmap.Draw(m_State->myDC, Pt1.x, Pt2.y, Pt2.x - Pt1.x, Pt1.y - Pt2.y);
|
||
}
|
||
}
|
||
//m_pBitmap = NULL;
|
||
::GlobalUnlock(m_hBuffer);
|
||
}
|
||
::GlobalFree(m_hBuffer);
|
||
m_hBuffer = NULL;
|
||
}
|
||
|
||
#else
|
||
CxImage img;
|
||
|
||
if (img.Decode((BYTE *) image.data(),
|
||
image.data_size(),
|
||
fmt))
|
||
{
|
||
if (m_State->m_ClipWidth > 0)
|
||
{
|
||
double inchWidth = m_State->m_ClipWidth
|
||
*(image.max_corner().m_x - image.min_corner().m_x)
|
||
/(m_State->m_MinMax.maxpt().m_x-m_State->m_MinMax.minpt().m_x);
|
||
double dpi=double(img.GetWidth()) / inchWidth;
|
||
myDoTRACE("\nGuessing raster dpi: %d", myRound(dpi));
|
||
}
|
||
|
||
img.Draw2(m_State->myDC, Pt1.x, Pt2.y, Pt2.x - Pt1.x, Pt1.y - Pt2.y);
|
||
}
|
||
else
|
||
myTRACE("\nimg.Decode failed: %s", img.GetLastError());
|
||
#endif
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_polyline (WT_Polyline & polyline, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
CPoint *vertexList = m_State->new_DWFToLP(polyline);
|
||
Polyline(m_State->myDC, vertexList, polyline.count());
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
// Merk op dat alleen TrueType teksten hier getekend worden.
|
||
// De SHX fonts worden als losse lijnstukjes gedaan
|
||
WT_Result CWhip2DCImpl::my_process_text (WT_Text & text, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
// Van Pseudo-teksten weten we de hoogte niet. Zoeken kunnen we er ook niet mee
|
||
if (!file.rendition().visibility().visible())
|
||
return WT_Result::Success;
|
||
|
||
CPoint acPt = m_State->DWFToLP(text.position());
|
||
if (m_State->m_mul==0)
|
||
{ // Heel grof hoogte bepalen voor extents
|
||
WT_Logical_Point pt(text.position());
|
||
CPoint dummy = m_State->DWFToLP(pt);
|
||
pt.m_x += file.rendition().font().height(); // Gok op <20><>n vierkante letter
|
||
pt.m_y += file.rendition().font().height();
|
||
dummy = m_State->DWFToLP(pt);
|
||
}
|
||
|
||
if (text.string().is_ascii())
|
||
{
|
||
// myTRACE("\nTekst: %s", text.string().ascii());
|
||
#ifdef _DEBUG
|
||
//if (!strcmp(text.string().ascii(),"Width scale=1024 (1x)"))
|
||
if (!strcmp(text.string().ascii(),"TP036"))
|
||
{
|
||
int x = 1;
|
||
}
|
||
#endif
|
||
CString txt(text.string().ascii());
|
||
if (txt.Trim().GetLength() == 0) // Komt voor bij outlets van AC_C2_0
|
||
return WT_Result::Success; // voorkom geeking
|
||
|
||
if (text.bounds().bounds() != NULL)
|
||
{
|
||
return m_State->drawBoundText(text, file);
|
||
}
|
||
|
||
// Vervang heel kleine teksten door een simpel gekleurd vlakje als het kan.
|
||
// Is een stuk sneller
|
||
// Helaas lijkt schuine true-type tekst (bemating) niet altijd bounds te hebben?
|
||
// ==>Maar vertikale wel
|
||
if (file.rendition().font().height()*m_State->m_mul < m_State->geekFontSize)
|
||
{
|
||
m_State->DrawGeekText(text);
|
||
return WT_Result::Success;
|
||
}
|
||
else
|
||
m_State->m_kfm.TextOutSpacing(m_State->myDC, acPt.x, acPt.y,
|
||
text.string().ascii(), text.string().length(),
|
||
(m_State->m_spacing/1024.0));
|
||
//TextOut(m_State->myDC, acPt.x, acPt.y, text.string().ascii(), text.string().length());
|
||
}
|
||
else
|
||
{
|
||
if (file.rendition().font().height()*m_State->m_mul >= 0.5)
|
||
TextOutW(m_State->myDC, acPt.x, acPt.y, text.string().unicode(), text.string().length());
|
||
}
|
||
|
||
#ifdef _DEBUG
|
||
if (m_State->m_mul > 0.1)
|
||
m_State->Marker(acPt);
|
||
#endif
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_text_scan (WT_Text & text, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
CString txt(text.string().ascii());
|
||
if (txt.Trim().GetLength() == 0) // Komt voor bij outlets van AC_C2_0
|
||
return WT_Result::Success;
|
||
|
||
CFoundText tFound;
|
||
tFound.m_FoundText = text;
|
||
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())
|
||
tFound.m_FoundLayer = ll->layer_name().ascii();
|
||
tFound.m_FoundAt = text.position();
|
||
|
||
m_State->m_FoundTexts.Add(tFound);
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
#pragma optimize( "p", on )
|
||
WT_Result CWhip2DCImpl::my_process_text_find (WT_Text & text, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
if (!file.rendition().visibility().visible())
|
||
return WT_Result::Success;
|
||
|
||
CPoint acPt = m_State->DWFToLP(text.position());
|
||
|
||
if (!text.string().is_ascii()) // Die kunnen we nog niet aan
|
||
return WT_Result::Success;
|
||
|
||
BOOL found = FALSE;
|
||
CPoint LPbounds[4]; // Het echte testen gaan we in LP-coordinaten doen
|
||
// (Mooie tussenweg tussen DP en DWF)
|
||
|
||
double radian = 0.0; // Graden rotatie
|
||
// Echte boundingbox heeft voorkeur
|
||
if (text.bounds().bounds() != NULL)
|
||
{
|
||
CPoint pts[]=
|
||
{
|
||
m_State->DWFToLP(text.bounds().bounds()[0]),
|
||
m_State->DWFToLP(text.bounds().bounds()[1]),
|
||
m_State->DWFToLP(text.bounds().bounds()[2]),
|
||
m_State->DWFToLP(text.bounds().bounds()[3])
|
||
};
|
||
memcpy(LPbounds, pts, 4*sizeof(CPoint));
|
||
//myTRACE("\nZoeken met behulp van text bounds %s", text.string().ascii());
|
||
}
|
||
else
|
||
{
|
||
CSize LPSize(0,0);
|
||
|
||
if (text.string().is_ascii())
|
||
{
|
||
double w,h;
|
||
m_State->m_kfm.GetTextExtent(m_State->myDC, text.string().ascii(), text.string().length(), w, h);
|
||
// TODO: De .6 snap ik nog niet maar anders is de box te groot
|
||
LPSize = CPoint((int)w, (int)(h*0.6));
|
||
//GetTextExtentPoint32(m_State->myDC, text.string().ascii(), text.string().length(), &LPSize);
|
||
}
|
||
// else
|
||
// GetTextExtentPoint32W(m_State->myDC, text.string().unicode(), text.string().length(), &Size);
|
||
|
||
CPoint pts[]=
|
||
{
|
||
acPt,
|
||
CPoint(acPt.x+LPSize.cx, acPt.y),
|
||
CPoint(acPt.x+LPSize.cx, acPt.y-LPSize.cy),
|
||
CPoint(acPt.x , acPt.y-LPSize.cy)
|
||
};
|
||
radian = m_State->m_logfont.lfOrientation * TWO_PI / 3600;
|
||
memcpy(LPbounds, pts, 4*sizeof(CPoint));
|
||
}
|
||
|
||
// In plaats van onze box 'goed' draaien gaan we ons testpunt 'fout' draaien. Is simpeler
|
||
CPoint dist(m_State->LPfindXY - acPt);
|
||
CPoint fnd(acPt);
|
||
|
||
// Compiler bug? De volgende regels deden het niet goed in release mode:
|
||
// fnd.y werd gewoon niet aangepast
|
||
// Opgelost door voor deze functie #pragma optimize( "p", on ) te zetten
|
||
fnd.x += int(cos(radian) * dist.x - sin(radian) * dist.y);
|
||
fnd.y += int(sin(radian) * dist.x + cos(radian) * dist.y);
|
||
|
||
if (CSLNKContourImpl::PointInPolygon(fnd, LPbounds, 4))
|
||
{
|
||
m_State->foundTextLabel = text.string().ascii();
|
||
// myTRACE("\nVolgens mij geklikt binnen (%d-%d,%d-%d) op '%s'", acPt.x, acPt.y, acPt.x+Size.cx, acPt.y+Size.cy, text.string().ascii());
|
||
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())
|
||
{
|
||
myTRACE("op laag '%s'", ll->layer_name().ascii());
|
||
m_State->foundTextLayer = ll->layer_name().ascii();
|
||
}
|
||
}
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_background (WT_Background & background, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (m_State->m_forcePaper) // Wissen is al wel gedaan
|
||
return WT_Result::Success;
|
||
|
||
WT_RGBA32 clr;
|
||
if (background.color().index() == WD_NO_COLOR_INDEX)
|
||
clr = background.color().rgba();
|
||
else
|
||
clr = file.rendition().color_map().map(background.color().index());
|
||
|
||
COLORREF DCclr = RGB(clr.m_rgb.r, clr.m_rgb.g, clr.m_rgb.b);
|
||
|
||
m_State->m_paperColor = DCclr; // Wordt later misschien opgevraagd.
|
||
|
||
if (m_State->findIt) // When finding no need for actuel painting
|
||
return WT_Result::Success;
|
||
|
||
m_State->erasePaper(file);
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
// poor mans Gouraud shading
|
||
#if 0
|
||
COLORREF avgColor (WT_Gouraud_Point_Set & gouraudPointSet)
|
||
{
|
||
int r=0,g=0,b=0;
|
||
for (int i = 0; i < gouraudPointSet.count(); i++)
|
||
{
|
||
WT_RGBA32 clr = gouraudPointSet.colors()[i];
|
||
r+=clr.m_rgb.r;
|
||
g+=clr.m_rgb.g;
|
||
b+=clr.m_rgb.b;
|
||
}
|
||
COLORREF DCclr;
|
||
DCclr = RGB(r/gouraudPointSet.count(),
|
||
g/gouraudPointSet.count(),
|
||
b/gouraudPointSet.count());
|
||
return DCclr;
|
||
}
|
||
|
||
void shadedline (int x1, int firstcolor, int x2, int lastcolor, int y)
|
||
{
|
||
int length;
|
||
int numcolors;
|
||
int colorvalue;
|
||
int step;
|
||
int x;
|
||
|
||
length = x2 - x1 + 1;
|
||
if (length > 0)
|
||
{
|
||
numcolors = lastcolor - firstcolor + 1;
|
||
|
||
colorvalue = firstcolor << 8;
|
||
step = ((long)numcolors << 8) / (long)length;
|
||
for (x = x1; x <= x2; x++)
|
||
{
|
||
drawpixel (x, y, colorvalue >> 8);
|
||
colorvalue += step;
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
WT_Result CWhip2DCImpl::my_process_gouraudPolyline (WT_Gouraud_Polyline & gouraudPolyline, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
//myTRACE("\n !! Don't know how to handle gouraudPolyline very well yet!! (%d points)", gouraudPolyline.count());
|
||
|
||
#if 1
|
||
int w=myRound(file.rendition().line_weight().weight_value()*m_State->m_mul);
|
||
|
||
WT_RGBA32 prev_clr;
|
||
CPoint prev_pt;
|
||
for (int i = 0; i < gouraudPolyline.count(); i++)
|
||
{
|
||
WT_RGBA32 clr = gouraudPolyline.colors()[i];
|
||
CPoint pt = m_State->DWFToLP(gouraudPolyline.points()[i]);
|
||
if (i > 0)
|
||
{
|
||
//int dv = myRound(_hypot(pt.x-prev_pt.x,pt.y-prev_pt.y) / 10); // Om de 10 pixels is goed zat
|
||
int dv = 10; // Toch maar altijd 10 stuks
|
||
|
||
int j;
|
||
for (j = 0; j < dv; j++)
|
||
{
|
||
COLORREF DCclr = RGB((clr.m_rgb.r*j + prev_clr.m_rgb.r*(dv-j))/dv,
|
||
(clr.m_rgb.g*j + prev_clr.m_rgb.g*(dv-j))/dv,
|
||
(clr.m_rgb.b*j + prev_clr.m_rgb.b*(dv-j))/dv);
|
||
m_State->m_pen = CreatePen (PS_SOLID, w, DCclr);
|
||
HPEN oldpen = (HPEN) SelectObject(m_State->myDC, m_State->m_pen);
|
||
DeleteObject(oldpen);
|
||
LineTo(m_State->myDC, myRound(((double)pt.x*j+prev_pt.x*(dv-j))/dv),
|
||
myRound(((double)pt.y*j+prev_pt.y*(dv-j))/dv));
|
||
}
|
||
}
|
||
else
|
||
MoveToEx(m_State->myDC, pt.x, pt.y, NULL);
|
||
prev_pt = pt;
|
||
prev_clr = clr;
|
||
}
|
||
|
||
return WT_Result::Success;
|
||
#endif
|
||
|
||
#if 0
|
||
COLORREF DCclr = RGB(0,0,0);
|
||
DCclr = avgColor(gouraudPolyline);
|
||
|
||
int w=myRound(file.rendition().line_weight().weight_value()*m_State->m_mul);
|
||
m_State->m_pen = CreatePen (PS_SOLID, w, DCclr);
|
||
HPEN oldpen = (HPEN) SelectObject(m_State->myDC, m_State->m_pen);
|
||
DeleteObject(oldpen);
|
||
|
||
CPoint *vertexList = m_State->new_DWFToLP(gouraudPolyline);
|
||
Polyline(m_State->myDC, vertexList, gouraudPolyline.count());
|
||
return WT_Result::Success;
|
||
#endif
|
||
|
||
#if 0
|
||
// TODO: Dit is natuurlijk gewoon een gedegenereerde gouraudPolytriangle!
|
||
// maar die lijkt GradientFill niet te tekenen?
|
||
// Waarschijnlijk: "Triangle drawing is lower-right exclusive"
|
||
TRIVERTEX *vert = new TRIVERTEX[2*gouraudPolyline.count()];
|
||
GRADIENT_TRIANGLE *gTri = new GRADIENT_TRIANGLE[gouraudPolyline.count()];
|
||
for (int i = 0; i < gouraudPolyline.count(); i++)
|
||
{
|
||
WT_RGBA32 clr = gouraudPolyline.colors()[i];
|
||
vert[2*i].x = m_State->DWFToLP(gouraudPolyline.points()[i]).x;
|
||
vert[2*i].y = m_State->DWFToLP(gouraudPolyline.points()[i]).y;
|
||
// Pas op: TRIVERTEX verwacht 16 bit RGB!
|
||
vert[2*i].Red = clr.m_rgb.r<<8;
|
||
vert[2*i].Green = clr.m_rgb.g<<8;
|
||
vert[2*i].Blue = clr.m_rgb.b<<8;
|
||
vert[2*i+1].x = m_State->DWFToLP(gouraudPolyline.points()[i]).x;
|
||
vert[2*i+1].y = m_State->DWFToLP(gouraudPolyline.points()[i]).y+1;
|
||
// Pas op: TRIVERTEX verwacht 16 bit RGB!
|
||
vert[2*i+1].Red = clr.m_rgb.r<<8;
|
||
vert[2*i+1].Green = clr.m_rgb.g<<8;
|
||
vert[2*i+1].Blue = clr.m_rgb.b<<8;
|
||
vert[i].Alpha = clr.m_rgb.a<<8;
|
||
gTri[i].Vertex1 = 2*i;
|
||
gTri[i].Vertex2 = 2*(i+1);
|
||
gTri[i].Vertex3 = 2*(i+1)+1;
|
||
}
|
||
GradientFill(m_State->myDC,vert,2*gouraudPolyline.count(),
|
||
gTri,gouraudPolyline.count()-2,GRADIENT_FILL_TRIANGLE);
|
||
delete [] vert;
|
||
delete [] gTri;
|
||
#endif
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
WT_Result CWhip2DCImpl::my_process_gouraudPolytriangle (WT_Gouraud_Polytriangle & gouraudPolytriangle, WT_File & file)
|
||
{
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
if (!m_State->bLayerVisible)
|
||
return WT_Result::Success;
|
||
|
||
TRIVERTEX *vert = new TRIVERTEX[gouraudPolytriangle.count()];
|
||
GRADIENT_TRIANGLE *gTri = new GRADIENT_TRIANGLE[gouraudPolytriangle.count()];
|
||
for (int i = 0; i < gouraudPolytriangle.count(); i++)
|
||
{
|
||
WT_RGBA32 clr = gouraudPolytriangle.colors()[i];
|
||
vert[i].x = m_State->DWFToLP(gouraudPolytriangle.points()[i]).x;
|
||
vert[i].y = m_State->DWFToLP(gouraudPolytriangle.points()[i]).y;
|
||
// Pas op: TRIVERTEX verwacht 16 bit RGB!
|
||
vert[i].Red = clr.m_rgb.r<<8;
|
||
vert[i].Green = clr.m_rgb.g<<8;
|
||
vert[i].Blue = clr.m_rgb.b<<8;
|
||
vert[i].Alpha = clr.m_rgb.a<<8;
|
||
gTri[i].Vertex1 = i;
|
||
gTri[i].Vertex2 = i+1;
|
||
gTri[i].Vertex3 = i+2;
|
||
}
|
||
// Zal geloof ik niet werken op Windows 95...
|
||
GradientFill(m_State->myDC,vert,gouraudPolytriangle.count(),
|
||
gTri,gouraudPolytriangle.count()-2,GRADIENT_FILL_TRIANGLE);
|
||
delete [] vert;
|
||
delete [] gTri;
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
|
||
WT_Result CWhip2DCImpl::my_process_fillPattern (WT_Fill_Pattern & fillPattern, WT_File & file)
|
||
{
|
||
WT_Fill_Pattern::default_process(fillPattern, file);
|
||
file.rendition().fill_pattern() = fillPattern; // Dit doet de default niet (goed)!!
|
||
|
||
CWhip2DCState *m_State = (CWhip2DCState *)file.heuristics().user_data();
|
||
|
||
m_State->ColorPenAndBrush(file);
|
||
|
||
return WT_Result::Success;
|
||
}
|
||
|
||
int CWhip2DCImpl::get_LayerCount(LONG* pVal)
|
||
{
|
||
(*pVal) = (LONG)m_State.m_Layernames.GetSize();
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
int CWhip2DCImpl::get_TextCount(LONG* pVal)
|
||
{
|
||
(*pVal) = (LONG)m_State.m_FoundTexts.GetCount();
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
|
||
int CWhip2DCImpl::get_TextItem(LONG i, CFoundText &pVal)
|
||
{
|
||
if (i<0 || i>=(LONG)m_State.m_FoundTexts.GetCount())
|
||
return E_INVALIDARG;
|
||
|
||
pVal = m_State.m_FoundTexts.GetAt(i);
|
||
return S_OK;
|
||
}
|
||
|
||
int CWhip2DCImpl::get_LayerItem(LONG i, CString* pVal)
|
||
{
|
||
if (i<0 || i>=(LONG)m_State.m_Layernames.GetSize())
|
||
return E_INVALIDARG;
|
||
|
||
(*pVal) = m_State.m_Layernames[i];
|
||
return S_OK;
|
||
}
|
||
|
||
int CWhip2DCImpl::get_paperColor(LONG* pVal)
|
||
{
|
||
(*pVal) = m_State.m_paperColor;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
int CWhip2DCImpl::put_paperColor(LONG newVal)
|
||
{
|
||
m_State.m_forcePaper = true;
|
||
m_State.m_paperColor = newVal;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
int CWhip2DCImpl::ReplaceColor(LONG paperColor, LONG oldColor, LONG newColor)
|
||
{
|
||
m_State.m_replaceColors[paperColor] = CFromTo(oldColor, newColor);
|
||
|
||
return S_OK;
|
||
}
|