212 lines
6.2 KiB
C++
212 lines
6.2 KiB
C++
// WhipCleaner.cpp : Implementation of CWhipCleaner
|
|
|
|
#include "stdafx.h"
|
|
#include "WhipCleaner.h"
|
|
|
|
|
|
// CWhipCleaner
|
|
|
|
STDMETHODIMP CWhipCleaner::InterfaceSupportsErrorInfo(REFIID riid)
|
|
{
|
|
static const IID* arr[] =
|
|
{
|
|
&IID_IWhipCleaner
|
|
};
|
|
|
|
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
|
|
{
|
|
if (InlineIsEqualGUID(*arr[i],riid))
|
|
return S_OK;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CWhipCleaner::LoadStream(VARIANT EPlotStream)
|
|
{
|
|
myDoTRACE("\nCWhipCleaner::LoadStream()");
|
|
|
|
if (EPlotStream.vt!=VT_ERROR)
|
|
{
|
|
VARIANT *var2 = &EPlotStream;
|
|
if (var2->vt==(VT_VARIANT|VT_BYREF)) // ByRef
|
|
var2 = (VARIANT *)var2->pvarVal;
|
|
|
|
if (var2->vt==VT_DISPATCH)
|
|
{
|
|
CComQIPtr<IEPlotSection> EPlotSection;
|
|
EPlotSection = var2->pdispVal;
|
|
if (!EPlotSection)
|
|
return E_INVALIDARG;
|
|
else
|
|
{
|
|
m_iEPlotSection = EPlotSection;
|
|
CEPlotSectionImpl *epli;
|
|
m_iEPlotSection->get_EPlotSectionImpl((BYTE **)&epli);
|
|
m_W2DFile.set_eplotsection(epli);
|
|
}
|
|
}
|
|
else
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CWhipCleaner::SaveAs(BSTR WhipPath)
|
|
{
|
|
myWT_File my_file;
|
|
my_file.set_filename(WhipPath);
|
|
return GenerateClean(my_file);
|
|
}
|
|
|
|
// We hebben de contouren bepaald. Genereer daarvoor nu nieuwe DWF-primitieven
|
|
// In het bijzonder kennen we er een kleurtje aan toe en plaatsen wel de labels (opnieuw)
|
|
STDMETHODIMP CWhipCleaner::GenerateClean(myWT_File &my_file)
|
|
{
|
|
WT_Result result;
|
|
|
|
my_file.set_file_mode(WT_File::File_Write);
|
|
#ifdef _DEBUG
|
|
my_file.heuristics().set_allow_binary_data(WD_False);
|
|
#endif
|
|
// Zal niet zo snel meer gebeuren maar we willen het zeker niet
|
|
my_file.heuristics().set_allow_drawable_merging(WD_False);
|
|
// Let op: De viewer kan 60-file niet zo maar lezen, dat moet naar packed-DWF
|
|
// Later: viewer 6.5 kan gewoon een W2D file tonen
|
|
// Let op: bij versie 55 worden Node's niet weggeschreven
|
|
// my_file.heuristics().set_target_version(55);
|
|
if (my_file.open() != WT_Result::Success)
|
|
{
|
|
return myAtlReportError (GetObjectCLSID(), "ERROR: Unable to open file for writing: %s", my_file.filename().ascii());
|
|
ATLASSERT(false);
|
|
}
|
|
|
|
// Nu nog een keer door de DWF om de rest te kopieren naar de output
|
|
m_W2DFile.set_file_mode(WT_File::File_Read);
|
|
my_file.heuristics().set_apply_transform(WD_False);
|
|
myTRACE("\nAbout to open plan");
|
|
if (m_W2DFile.open() == WT_Result::Success)
|
|
{
|
|
#ifdef _DEBUG
|
|
WT_Comments cmt;
|
|
cmt.set("Cleaned up by SLNKDWF.Whipcleaner");
|
|
cmt.serialize(my_file);
|
|
#endif
|
|
int keep=my_file.heuristics().target_version();
|
|
// Even background ondersteunen
|
|
my_file.heuristics().set_target_version(55);
|
|
WT_Background bg(WT_Color(0,0,0));
|
|
bg.serialize(my_file);
|
|
my_file.heuristics().set_target_version(keep);
|
|
|
|
{
|
|
CmyTimer tm("Serializing plan");
|
|
SerializeClean(m_W2DFile, my_file); // Heeft eventueel een GenerateContouren in zich!
|
|
}
|
|
#ifdef _DEBUG
|
|
cmt.set("Plan is serialized");
|
|
cmt.serialize(my_file);
|
|
#endif
|
|
myTRACE("\nPlan is serialized");
|
|
m_W2DFile.close();
|
|
}
|
|
else
|
|
{
|
|
myTRACE("\nKon plan niet openen");
|
|
return myAtlReportError (GetObjectCLSID(), "ERROR: Unable to open plan file");
|
|
}
|
|
|
|
myTRACE("\nAbout to close");
|
|
//Restore the saved object node.
|
|
my_file.desired_rendition().fill() = WD_False;
|
|
my_file.close();
|
|
|
|
myTRACE("\nDone saving");
|
|
return S_OK;
|
|
}
|
|
|
|
// 'Herschrijf' de plan DWF naar de output
|
|
// Doe eerst de 'header' van de DWF (viewport en zo) en zodra
|
|
// we de eerste drawable tegenkomen doen we de contouren tussendoor
|
|
// zodat die (als ze ingekleurd worden) altijd onderaan liggen
|
|
HRESULT CWhipCleaner::SerializeClean(WT_File & my_plan_file, myWT_File & my_file)
|
|
{
|
|
WT_Result result;
|
|
|
|
WT_Integer32 last_num = -1;
|
|
CString last_name("");
|
|
// Do the actual reading.
|
|
|
|
while ((result = my_plan_file.process_next_object()) == WT_Result::Success)
|
|
{
|
|
switch(my_plan_file.current_object()->object_type())
|
|
{
|
|
case WT_Object::Drawable:
|
|
#ifdef _DEBUG
|
|
if (my_plan_file.current_object()->object_id() == WT_Object::Origin_ID
|
|
&& !my_file.heuristics().allow_binary_data()
|
|
)
|
|
{ // I do not understand why but it will assert otherwise
|
|
break;
|
|
}
|
|
#endif
|
|
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())
|
|
{
|
|
case WT_Object::Layer_ID:
|
|
{ // Sla de oorspronkelijke contour lagen over
|
|
// En ook de lagen die we niet willen
|
|
WT_Layer *layer = (WT_Layer *)obj;
|
|
WT_Integer32 layer_num = layer->layer_num();
|
|
CString layer_name(layer->layer_name().ascii());
|
|
|
|
if (layer_num==0)
|
|
{ // ARKEY heeft lagen met nummer 0. Dat mag niet volgens de
|
|
// Whip-spec en gaat ook mis (alleen) bij binaire DWF's
|
|
if (my_file.heuristics().allow_binary_data())
|
|
{
|
|
myDoTRACE("\nSkipping layer with invalid number 0");
|
|
break;
|
|
}
|
|
}
|
|
WT_Layer *ll = my_plan_file.layer_list().find_layer_from_index(layer_num);
|
|
// hier gaat het om:
|
|
if (last_num != layer_num && layer_name != last_name)
|
|
layer->serialize(my_file);
|
|
last_num = layer_num;
|
|
last_name = layer_name;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
#ifdef _DEBUG
|
|
CString s(my_plan_file.file_stats()->descriptions());
|
|
// myTRACE("Attribute '%s'\n", s);
|
|
#endif
|
|
// Hoewel een Attibute gaat hij toch niet via desired_rendition
|
|
// Omdat we weten dat we net uit uit een DWF komen kunnen we best
|
|
// wel rechtstreeks serializen
|
|
// Let wel: desired_rendition is dan niet meer te vertrouwen. Zie @@@
|
|
obj->serialize(my_file);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
#ifdef _DEBUG
|
|
CString s(my_plan_file.file_stats()->descriptions());
|
|
//myTRACE("Skipping '%s'\n", s);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|