[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]
[XaraXtreme-commits] Commit Complete
Commit by : gerry
Repository : xara
Revision : 1708
Date : Thu Aug 17 18:13:43 BST 2006
Changed paths:
M /Trunk/XaraLX/Kernel/bitmap.cpp
M /Trunk/XaraLX/Kernel/bitmap.h
M /Trunk/XaraLX/Kernel/bmpcomp.cpp
M /Trunk/XaraLX/Kernel/camfiltr.cpp
M /Trunk/XaraLX/Kernel/cxfile.cpp
M /Trunk/XaraLX/Kernel/exjpeg.cpp
M /Trunk/XaraLX/Kernel/fillattr.cpp
M /Trunk/XaraLX/Kernel/fillattr2.h
M /Trunk/XaraLX/Kernel/imjpeg.cpp
M /Trunk/XaraLX/Kernel/node.h
M /Trunk/XaraLX/Kernel/nodebmp.cpp
M /Trunk/XaraLX/Kernel/nodebmp.h
M /Trunk/XaraLX/Kernel/xpfcaps.h
M /Trunk/XaraLX/Kernel/xpfilter.cpp
M /Trunk/XaraLX/Kernel/xpfilter.h
M /Trunk/XaraLX/Kernel/xpfrgn.cpp
M /Trunk/XaraLX/wxOil/xpoilflt.cpp
Implementation of compression and resample conversion options
Diff:
Index: Trunk/XaraLX/Kernel/nodebmp.h
===================================================================
--- Trunk/XaraLX/Kernel/nodebmp.h (revision 1707)
+++ Trunk/XaraLX/Kernel/nodebmp.h (revision 1708)
@@ -142,6 +142,8 @@
virtual String Describe(BOOL Plural, BOOL Verbose);
virtual KernelBitmap *EnumerateBitmaps(UINT32 Count);
+ virtual double GetEffectiveBitmapMinDPI(KernelBitmap* pBitmap);
+ virtual BOOL ReplaceBitmap(KernelBitmap* pOrigBitmap, KernelBitmap* pNewBitmap);
// Function for interrogation by clipboard to determine exportable data types
virtual BOOL SupportsClipboardFormat(InternalClipboardFormat *Format) const;
Index: Trunk/XaraLX/Kernel/fillattr2.h
===================================================================
--- Trunk/XaraLX/Kernel/fillattr2.h (revision 1707)
+++ Trunk/XaraLX/Kernel/fillattr2.h (revision 1708)
@@ -1845,6 +1845,8 @@
virtual BOOL IsAGradFill() const { return TRUE; }
virtual KernelBitmap *EnumerateBitmaps(UINT32 Count);
+ virtual double GetEffectiveBitmapMinDPI(KernelBitmap* pBitmap);
+ virtual BOOL ReplaceBitmap(KernelBitmap* pOrigBitmap, KernelBitmap* pNewBitmap);
virtual BOOL NeedsForceToSimpleMapping() { return(FALSE); }
Index: Trunk/XaraLX/Kernel/xpfilter.h
===================================================================
--- Trunk/XaraLX/Kernel/xpfilter.h (revision 1707)
+++ Trunk/XaraLX/Kernel/xpfilter.h (revision 1708)
@@ -202,6 +202,7 @@
BOOL GenerateExportData(CapabilityTree* pPlugCaps);
BOOL DoConversionPassN(CapabilityTree* pPlugCaps, INT32 ConvertPass);
+ BOOL DoBitmapResamplePass(CapabilityTree* pPlugCaps);
virtual Node* GetExportNode();
virtual BOOL BeginDocumentExport();
virtual BOOL EndDocumentExport();
Index: Trunk/XaraLX/Kernel/xpfcaps.h
===================================================================
--- Trunk/XaraLX/Kernel/xpfcaps.h (revision 1707)
+++ Trunk/XaraLX/Kernel/xpfcaps.h (revision 1708)
@@ -1033,6 +1033,7 @@
m_RasteriseDPI = 96.0;
m_bRasteriseAlpha = TRUE;
m_BitmapCompression = 200;
+ m_bResample = FALSE;
m_SpreadType = XPFCONVTYPE_NATIVE;
m_pObjects = NULL;
m_ObjectsType = XPFCONVTYPE_NATIVE;
@@ -1082,12 +1083,13 @@
void SetSpreadType(XPFConvertType Type) { m_SpreadType = Type; }
- void SetRasterise(double DPI, BOOL bAlpha, INT32 Compression, const String_256& CommonTrans)
+ void SetRasterise(double DPI, BOOL bAlpha, INT32 Compression, const String_256& CommonTrans, BOOL bResample)
{
m_RasteriseDPI = DPI;
m_bRasteriseAlpha = bAlpha;
m_BitmapCompression = Compression;
m_CommonTrans = CommonTrans;
+ m_bResample = bResample;
}
void SetObjectsTree(XPFCapability* pObjects, XPFConvertType ObjectsType)
@@ -1121,6 +1123,7 @@
BOOL HasRasteriseCommonTrans() { return(!m_CommonTrans.IsEmpty()); }
// Move this into cpp file when implemented
BOOL IsRasteriseCommonTrans(UINT32 Type);
+ BOOL GetBitmapResample() { return(m_bResample); }
XPFCapability* GetObjects(void) const { return(m_pObjects); }
XPFCapability* GetAttributes(void) const { return(m_pAttributes); }
@@ -1140,6 +1143,7 @@
BOOL m_bRasteriseAlpha;
INT32 m_BitmapCompression;
String_256 m_CommonTrans;
+ BOOL m_bResample;
XPFConvertType m_SpreadType;
Index: Trunk/XaraLX/Kernel/cxfile.cpp
===================================================================
--- Trunk/XaraLX/Kernel/cxfile.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/cxfile.cpp (revision 1708)
@@ -2014,7 +2014,7 @@
if (ReadNextRecordHeader())
{
- TRACEUSER("Gerry", _T("HandleRecord %d - %d [%d]"), RecordNumber, ReadTag, ReadSize);
+// TRACEUSER("Gerry", _T("HandleRecord %d - %d [%d]"), RecordNumber, ReadTag, ReadSize);
CXaraFileRecordHandler* pCXaraFileRecordHandler = FindHandler(ReadTag);
if (pCXaraFileRecordHandler != NULL)
Index: Trunk/XaraLX/Kernel/fillattr.cpp
===================================================================
--- Trunk/XaraLX/Kernel/fillattr.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/fillattr.cpp (revision 1708)
@@ -5607,6 +5607,98 @@
return NULL;
}
+
+/****************************************************************************
+
+> BOOL AttrBitmapFill::ReplaceBitmap(KernelBitmap* pOrigBitmap, KernelBitmap* pNewBitmap)
+
+ Author: Gerry
+ Created: 07/08/2006
+
+ Inputs: pOrigBitmap - pointer to a KernelBitmap
+ pNewBitmap - pointer to a KernelBitmap
+ Returns: TRUE if ok, FALSE if bother
+ Purpose:
+
+****************************************************************************/
+
+BOOL AttrBitmapFill::ReplaceBitmap(KernelBitmap* pOrigBitmap, KernelBitmap* pNewBitmap)
+{
+ if (!IsAFractalFill())
+ {
+ if (GetBitmap() == pOrigBitmap)
+ {
+ BitmapFillAttribute* pVal = (BitmapFillAttribute*)GetAttributeValue();
+ if (pVal)
+ pVal->GetBitmapRef()->Attach(pNewBitmap);
+
+ return(TRUE);
+ }
+ }
+
+ return FALSE;
+}
+
+
+/****************************************************************************
+
+> double AttrBitmapFill::GetEffectiveBitmapMinDPI(KernelBitmap* pBitmap)
+
+ Author: Gerry
+ Created: 07/08/2006
+
+ Inputs: pBitmap - pointer to a KernelBitmap
+ Returns:
+ Purpose: Returns the minimum effective dpi this bitmap is used at
+
+****************************************************************************/
+
+double AttrBitmapFill::GetEffectiveBitmapMinDPI(KernelBitmap* pBitmap)
+{
+ if (!IsAFractalFill() && GetBitmap() == pBitmap)
+ {
+ // Do we have a valid bitmap ?
+ OILBitmap *OilBM = pBitmap->ActualBitmap;
+ if (OilBM != NULL)
+ {
+ BitmapInfo Info;
+ OilBM->GetInfo(&Info);
+
+ // Get the Width of the Bitmap in Pixels
+ INT32 PixWidth = Info.PixelWidth;
+ INT32 PixHeight = Info.PixelHeight;
+
+ DocCoord Start(*GetStartPoint());
+ DocCoord End(*GetEndPoint());
+ DocCoord End2(*GetEndPoint2());
+
+ // Get the Width of the Bitmap in Millipoints
+ INT32 Width = INT32(Start.Distance(End));
+ INT32 Height = INT32(Start.Distance(End2));
+
+ // Use doubles so that we can round up as well as down. This improves
+ // the dpi calculated.
+ double HDpi = 0;
+ double VDpi = 0;
+
+ if (Width > 0)
+ HDpi = ((double)PixWidth * 72000.0)/(double)Width;
+
+ if (Height > 0)
+ VDpi = ((double)PixHeight * 72000.0)/(double)Height;
+
+ // Use the smaller of the two dpi values
+ if (HDpi < VDpi)
+ return(HDpi);
+ else
+ return(VDpi);
+ }
+ }
+
+ return(1e9);
+}
+
+
/********************************************************************************************
> virtual NodeAttribute* AttrBitmapFill::GetOtherAttrToApply(BOOL* IsMutate)
Index: Trunk/XaraLX/Kernel/xpfilter.cpp
===================================================================
--- Trunk/XaraLX/Kernel/xpfilter.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/xpfilter.cpp (revision 1708)
@@ -116,6 +116,8 @@
#include "progress.h"
#include "camprocess.h"
+#include "bmpcomp.h"
+#include "grndbmp.h"
// An implement to match the Declare in the .h file.
CC_IMPLEMENT_DYNAMIC(PluginNativeFilter, CamelotNativeFilter);
@@ -492,7 +494,7 @@
String_64 Str(_R(IDS_CONVERTING_DOCUMENT));
StartProgressBar(&Str);
- SetTotalProgressBarCount(500);
+ SetTotalProgressBarCount(600);
m_ProgressOffset = 0;
// UINT32 ThisPassCount = 0;
@@ -628,6 +630,14 @@
ok = DoConversionPassN(pPlugCaps, 5);
}
+ if (ok)
+ {
+ // Now handle the bitmap resampling pass
+ m_ProgressOffset = 500;
+ SetProgressBarCount(0);
+ ok = DoBitmapResamplePass(pPlugCaps);
+ }
+
SetProgressBarCount(100);
EndProgressBar(); // Kill progess bar
@@ -707,6 +717,211 @@
/****************************************************************************
+> BOOL PluginNativeFilter::DoBitmapResamplePass(CapabilityTree* pPlugCaps)
+
+ Author: Gerry
+ Created: 04/08/2006
+
+ Inputs: pPlugCaps - pointer to a CapabilityTree
+ Returns: TRUE if ok, FALSE if bother
+ Purpose:
+
+****************************************************************************/
+
+BOOL PluginNativeFilter::DoBitmapResamplePass(CapabilityTree* pPlugCaps)
+{
+ if (!pPlugCaps->GetBitmapResample())
+ return(TRUE);
+
+ TRACE(_T("DoBitmapResamplePass"));
+
+ Document* pDoc = Document::GetCurrent();
+ ERROR2IF(pDoc == NULL, FALSE, "No current document in DoBitmapResamplePass");
+
+ BitmapList* pBmpList = pDoc->GetBitmapList();
+ ERROR2IF(pDoc == NULL, FALSE, "No bitmap list in DoBitmapResamplePass");
+
+ // For each bitmap in the document's bitmap list
+ KernelBitmap* pBitmap = (KernelBitmap*)(pBmpList->GetHead());
+
+ while (pBitmap)
+ {
+ double MinDPI = 1e9;
+
+ List NodeList;
+
+ // Scan through new document tree finding all uses of the bitmap
+ Node* pNode = m_pNewTree->FindFirstDepthFirst();
+ while (pNode)
+ {
+ UINT32 Count = 0;
+ BOOL bAdd = FALSE;
+ KernelBitmap* pTestBitmap = pNode->EnumerateBitmaps(Count);
+ while (pTestBitmap)
+ {
+ if (pTestBitmap == pBitmap)
+ {
+ bAdd = TRUE; // Add this node to the list
+ double DPI = pNode->GetEffectiveBitmapMinDPI(pTestBitmap);
+ if (DPI < MinDPI)
+ MinDPI = DPI;
+ }
+
+ // Get the next bitmap from the node
+ Count++;
+ pTestBitmap = pNode->EnumerateBitmaps(Count);
+ }
+
+ if (bAdd)
+ {
+ NodeListItem* pItem = new NodeListItem(pNode);
+ if (pItem)
+ NodeList.AddTail(pItem);
+ }
+
+ // Get the next node
+ pNode = pNode->FindNextDepthFirst(m_pNewTree);
+ }
+
+ // If a minimum has been found for this bitmap
+ if (MinDPI < 1e9)
+ {
+ TRACE(_T("MinDPI = %f"), MinDPI);
+
+ double ratio = pPlugCaps->GetRasteriseDPI() / MinDPI;
+ // If the minimum dpi is above the resample dpi then
+ if (ratio < 0.9)
+ {
+ TRACE(_T("Resample bitmap"));
+ // Generate new bitmap with size so that minimum dpi is resample dpi
+
+ TRACE(_T("Actual size = (%d, %d)"), pBitmap->GetWidth(), pBitmap->GetHeight());
+
+ INT32 OutWidth = (INT32)(((double)pBitmap->GetWidth() * ratio) + 0.5);
+ INT32 OutHeight = (INT32)(((double)pBitmap->GetHeight() * ratio) + 0.5);
+ TRACE(_T("Needed size = (%d, %d)"), OutWidth, OutHeight);
+
+ KernelBitmap* pNewBitmap = NULL;
+ {
+ View* pView = View::GetCurrent();
+ Spread* pSpread = NULL;
+ BOOL bAlpha = pBitmap->IsTransparent();
+ Matrix ViewTrans;
+ FIXED16 TempScale(1.0);
+ double Dpi = 96.0;
+ DocRect BoundsRect(0, 0, OutWidth * 750, OutHeight * 750);
+
+ GRenderBitmap BitmapRR(BoundsRect, ViewTrans, TempScale, 32, Dpi);
+ if (bAlpha)
+ BitmapRR.m_DoCompression = TRUE;
+ BitmapRR.SetUsingSmoothedBitmaps(TRUE); // Make sure we do high quality
+ BitmapRR.AttachDevice(pView, NULL, pSpread);
+
+ // Start rendering into the bitmap
+ if (!BitmapRR.StartRender())
+ {
+ ERROR2(FALSE, "StartRender failed in DoBitmapResamplePass");
+ }
+
+ BitmapRR.SaveContext();
+
+ // Best quality please
+ QualityAttribute *pQualAttr = new QualityAttribute();
+ pQualAttr->QualityValue.SetQuality(QUALITY_MAX);
+ BitmapRR.SetQuality(pQualAttr, TRUE);
+
+ // Simple bitmap fill which fills the whole shape
+ BitmapFillAttribute* pBitmapAttr = new BitmapFillAttribute;
+ pBitmapAttr->GetBitmapRef()->SetBitmap(pBitmap);
+ pBitmapAttr->StartPoint = BoundsRect.lo;
+ pBitmapAttr->EndPoint = DocCoord(BoundsRect.hi.x, BoundsRect.lo.y);
+ pBitmapAttr->EndPoint2 = DocCoord(BoundsRect.lo.x, BoundsRect.hi.y);
+
+ // Set bitmap attribute, and get the render region to throw it away when it's finished
+ // with (hence the TRUE parameter).
+ BitmapRR.SetFillGeometry(pBitmapAttr, TRUE);
+
+ BitmapRR.SetLineColour(COLOUR_NONE);
+
+ Path RectPath;
+ if (RectPath.Initialise())
+ {
+ // Start at bottom left corner
+ RectPath.InsertMoveTo(BoundsRect.lo);
+ RectPath.InsertLineTo(DocCoord(BoundsRect.hi.x, BoundsRect.lo.y));
+ RectPath.InsertLineTo(BoundsRect.hi);
+ RectPath.InsertLineTo(DocCoord(BoundsRect.lo.x, BoundsRect.hi.y));
+ RectPath.InsertLineTo(BoundsRect.lo);
+
+ // Close the path properly
+ RectPath.CloseSubPath();
+ RectPath.IsFilled = TRUE;
+ RectPath.IsStroked = FALSE;
+ BitmapRR.DrawPath(&RectPath);
+ }
+
+ BitmapRR.RestoreContext();
+
+ // Stop rendering
+ BitmapRR.StopRender();
+
+ OILBitmap* pFullBitmap = BitmapRR.ExtractBitmap();
+ String_256 sName = GetNewBitmapName();
+ pFullBitmap->SetName(sName);
+ pNewBitmap = KernelBitmap::MakeKernelBitmap(pFullBitmap);
+
+ // Attach the bitmap to this document or a copy will be created when
+ // it is used in the attribute
+ BitmapList* pBmpList = NULL;
+ Document* pCurDoc = Document::GetCurrent();
+ if (pCurDoc)
+ pBmpList = pCurDoc->GetBitmapList();
+
+ // and then attach the bitmap (doesn't matter if BmpList is NULL)
+ pNewBitmap->Attach(pBmpList);
+
+ // Make sure we preserve the lossy flag
+ pNewBitmap->SetAsLossy(pBitmap->IsLossy());
+ }
+
+ if (pNewBitmap)
+ {
+ TRACE(_T("New bitmap = (%d, %d)"), pNewBitmap->GetWidth(), pNewBitmap->GetHeight());
+
+ // Loop through NodeList asking each node to replace the
+ // specified bitmap with this new one
+
+ NodeListItem* pItem = (NodeListItem*)(NodeList.GetHead());
+ while (pItem)
+ {
+ if (pItem->pNode)
+ {
+ if (!pItem->pNode->ReplaceBitmap(pBitmap, pNewBitmap))
+ {
+ TRACE(_T("Failed to replace bitmap"));
+ }
+ }
+
+ pItem = (NodeListItem*)(NodeList.GetNext(pItem));
+ }
+ }
+ else
+ {
+ TRACE(_T("Failed to create new bitmap"));
+ }
+ }
+ }
+
+ NodeList.DeleteAll();
+ pBitmap = (KernelBitmap*)(pBmpList->GetNext(pBitmap));
+ }
+
+ return(TRUE);
+}
+
+
+/****************************************************************************
+
> virtual Node* PluginNativeFilter::GetExportNode()
Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
Index: Trunk/XaraLX/Kernel/bmpcomp.cpp
===================================================================
--- Trunk/XaraLX/Kernel/bmpcomp.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/bmpcomp.cpp (revision 1708)
@@ -1474,6 +1474,7 @@
if (pSource != NULL)
{
pBitmap->SetOriginalSource(pSource, pBitmapFilter);
+ pBitmap->SetAsLossy();
}
}
else
@@ -1757,48 +1758,51 @@
// Find out whether we need to make an XPE record or not...
PORTNOTE("other","KernelBitmap::GetXPEInfo removed")
#ifndef EXCLUDE_FROM_XARALX
- KernelBitmap* pMaster = NULL;
- IXMLDOMDocumentPtr pEditList = NULL;
- pBitmap->GetXPEInfo(pMaster, pEditList);
- if (pMaster!=NULL && pEditList!=NULL)
+ if (pFilter->GetSaveXPEBitmaps() == FALSE)
{
- // Get master bitmap reference number (writing out the bitmap if necessary)
- INT32 MasterRecord = 0;
- MasterRecord = GetWriteBitmapReference(pMaster, pFilter);
-
- // Only write out new record style if we really have to...
- // (Helps forward compatibility)
- if (MasterRecord!=0)
+ KernelBitmap* pMaster = NULL;
+ IXMLDOMDocumentPtr pEditList = NULL;
+ pBitmap->GetXPEInfo(pMaster, pEditList);
+ if (pMaster!=NULL && pEditList!=NULL)
{
- // Create a new style XPE bitmap properties record
- CXaraFileRecord Rec(TAG_XPE_BITMAP_PROPERTIES);
-
- BSTR bstrValue;
- HRESULT hr;
- hr = pEditList->get_xml(&bstrValue);
- if (SUCCEEDED(hr))
+ // Get master bitmap reference number (writing out the bitmap if necessary)
+ INT32 MasterRecord = 0;
+ MasterRecord = GetWriteBitmapReference(pMaster, pFilter);
+
+ // Only write out new record style if we really have to...
+ // (Helps forward compatibility)
+ if (MasterRecord!=0)
{
- ok = Rec.Init();
- if (ok) ok = Rec.WriteReference(BmpRef); // bitmap reference
- if (ok) ok = Rec.WriteBYTE(Flags); // flags
-
- // TODO: write GIF animation properties here
-
- // reserved bytes
- for( INT32 i=0; i<7; i++ )
+ // Create a new style XPE bitmap properties record
+ CXaraFileRecord Rec(TAG_XPE_BITMAP_PROPERTIES);
+
+ BSTR bstrValue;
+ HRESULT hr;
+ hr = pEditList->get_xml(&bstrValue);
+ if (SUCCEEDED(hr))
{
- if (ok) ok = Rec.WriteBYTE(0);
+ ok = Rec.Init();
+ if (ok) ok = Rec.WriteReference(BmpRef); // bitmap reference
+ if (ok) ok = Rec.WriteBYTE(Flags); // flags
+
+ // TODO: write GIF animation properties here
+
+ // reserved bytes
+ for( INT32 i=0; i<7; i++ )
+ {
+ if (ok) ok = Rec.WriteBYTE(0);
+ }
+
+ // Now write out XPE stuff
+ if (ok) ok = Rec.WriteReference(MasterRecord); // Master bitmap record number
+ if (ok) ok = Rec.WriteUnicode(pBitmap->GetName()); // Oil Bitmap name
+ if (ok) ok = Rec.WriteBSTR(bstrValue); // UNICODE xml string edits list
+
+ // Write the record
+ if (ok) ok = pFilter->Write(&Rec);
+
+ return ok;
}
-
- // Now write out XPE stuff
- if (ok) ok = Rec.WriteReference(MasterRecord); // Master bitmap record number
- if (ok) ok = Rec.WriteUnicode(pBitmap->GetName()); // Oil Bitmap name
- if (ok) ok = Rec.WriteBSTR(bstrValue); // UNICODE xml string edits list
-
- // Write the record
- if (ok) ok = pFilter->Write(&Rec);
-
- return ok;
}
}
}
@@ -2008,6 +2012,22 @@
Tag = TAG_DEFINEBITMAP_JPEG;
SearchFilter = FILTERID_EXPORT_JPEG;
}
+ else if (Compression >= 201 && Compression <= 300)
+ {
+ // If compression is between 201 and 300 then use JPEG
+ // where the bitmap came from a lossy source
+ if (pBitmap->IsLossy())
+ {
+ Tag = TAG_DEFINEBITMAP_JPEG;
+ SearchFilter = FILTERID_EXPORT_JPEG;
+ Compression -= 200; // Get quality in the correct range
+ }
+ else
+ {
+ Tag = TAG_DEFINEBITMAP_PNG;
+ SearchFilter = FILTERID_PNG;
+ }
+ }
else
{
Tag = TAG_DEFINEBITMAP_PNG;
@@ -2015,10 +2035,29 @@
}
break;
case 32:
- // No choice but to use PNG or BMP in all cases as these are the only
- // formats that support 32bpp.
- Tag = TAG_DEFINEBITMAP_PNG;
- SearchFilter = FILTERID_PNG;
+ if (Compression >= 0 && Compression <= 200)
+ {
+ // Definitely use PNG is this case
+ Tag = TAG_DEFINEBITMAP_PNG;
+ SearchFilter = FILTERID_PNG;
+ }
+ else
+ {
+ // If compression indicates JPEG where possible then use
+ // JPEG where the bitmap came from a lossy source and has
+ // no transparency in its alpha channel
+ if (pBitmap->IsLossy() && !pBitmap->IsTransparent())
+ {
+ Tag = TAG_DEFINEBITMAP_JPEG;
+ SearchFilter = FILTERID_EXPORT_JPEG;
+ Compression -= 200; // Get quality in the correct range
+ }
+ else
+ {
+ Tag = TAG_DEFINEBITMAP_PNG;
+ SearchFilter = FILTERID_PNG;
+ }
+ }
break;
default:
ERROR2(0,"BitmapListComponent::SaveBitmapDefinition bad pixel depth");
Index: Trunk/XaraLX/Kernel/bitmap.h
===================================================================
--- Trunk/XaraLX/Kernel/bitmap.h (revision 1707)
+++ Trunk/XaraLX/Kernel/bitmap.h (revision 1708)
@@ -360,6 +360,7 @@
BOOL IsDefaultBitmap() { return this == OILBitmap::Default || HasBeenDeleted(); }
BOOL IsTemp() { return m_bTemp; }
BOOL IsInGlobalList() { return !m_bTemp; }
+ BOOL IsLossy() { return m_bIsLossy; }
void SetAsFractal() { m_bIsAFractal = TRUE;
m_bIsGreyscale = TRUE; }
@@ -368,6 +369,7 @@
// Informs this object that the bitmap it contains *is* a greyscale 8bpp bitmap, and that
// it therefore doesn't need to make a copy in GetGreyscaleVersion()
+ void SetAsLossy(BOOL bLossy = TRUE) { m_bIsLossy = bLossy; };
BOOL IsAFractal() { return m_bIsAFractal; }
virtual BOOL IsBrowserPalette() = 0;
@@ -431,6 +433,7 @@
BOOL m_bUsedByBrush : 1;
BOOL m_bNeedsXPERebuild : 1; // Bitmap data has been removed from memory, can be rebuilt from m_pMasterBitmap and m_pEditList
BOOL m_bHidden : 1; // Should not show up in bitmap gallery
+ BOOL m_bIsLossy : 1;
#ifdef _DEBUG
// Debug flag, so we can detect multiple references to temp bitmaps
@@ -555,6 +558,7 @@
BOOL IsDefaultBitmap();
BOOL HasBeenDeleted();
BOOL IsGreyscale();
+ BOOL IsLossy();
// Functions to access the orginal bitmap file
void SetOriginalSource(BitmapSource* pFileBuffer = NULL, BaseBitmapFilter* pImportFilter = NULL);
@@ -570,6 +574,7 @@
BOOL SetAsFractal();
BOOL SetAsGreyscale();
+ BOOL SetAsLossy(BOOL bLossy = TRUE);
UINT32 GetDelay();
void SetDelay(UINT32 Delay);
Index: Trunk/XaraLX/Kernel/nodebmp.cpp
===================================================================
--- Trunk/XaraLX/Kernel/nodebmp.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/nodebmp.cpp (revision 1708)
@@ -2440,7 +2440,88 @@
}
+/****************************************************************************
+> double NodeBitmap::GetEffectiveBitmapMinDPI(KernelBitmap* pBitmap)
+
+ Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
+ Created: 07/08/2006
+
+ Inputs: pBitmap - pointer to a KernelBitmap
+ Returns:
+ Purpose:
+
+****************************************************************************/
+
+double NodeBitmap::GetEffectiveBitmapMinDPI(KernelBitmap* pBitmap)
+{
+ if (GetBitmap() == pBitmap)
+ {
+ // Do we have a valid bitmap ?
+ OILBitmap *OilBM = pBitmap->ActualBitmap;
+ if (OilBM != NULL)
+ {
+ BitmapInfo Info;
+ OilBM->GetInfo(&Info);
+
+ // Get the Width of the Bitmap in Pixels
+ INT32 PixWidth = Info.PixelWidth;
+ INT32 PixHeight = Info.PixelHeight;
+
+ // Get the Width of the Bitmap in Millipoints
+ INT32 Width = INT32(Parallel[0].Distance(Parallel[1]));
+ INT32 Height = INT32(Parallel[1].Distance(Parallel[2]));
+
+ // Use doubles so that we can round up as well as down. This improves
+ // the dpi calculated.
+ double HDpi = 0;
+ double VDpi = 0;
+
+ if (Width > 0)
+ HDpi = ((double)PixWidth * 72000.0)/(double)Width;
+
+ if (Height > 0)
+ VDpi = ((double)PixHeight * 72000.0)/(double)Height;
+
+ // Use the smaller of the two dpi values
+ if (HDpi < VDpi)
+ return(HDpi);
+ else
+ return(VDpi);
+ }
+ }
+
+ return(1e9);
+}
+
+
+
+/****************************************************************************
+
+> BOOL NodeBitmap::ReplaceBitmap(KernelBitmap* pOrigBitmap, KernelBitmap* pNewBitmap)
+
+ Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
+ Created: 07/08/2006
+
+ Inputs: pOrigBitmap - pointer to a KernelBitmap
+ pNewBitmap - pointer to a KernelBitmap
+ Returns: TRUE if ok, FALSE if bother
+ Purpose:
+
+****************************************************************************/
+
+BOOL NodeBitmap::ReplaceBitmap(KernelBitmap* pOrigBitmap, KernelBitmap* pNewBitmap)
+{
+ if (GetBitmap() == pOrigBitmap)
+ {
+ BitmapRef.Attach(pNewBitmap);
+ return(TRUE);
+ }
+
+ return FALSE;
+}
+
+
/********************************************************************************************
> BOOL NodeBitmap::IsABitmap() const
Index: Trunk/XaraLX/Kernel/exjpeg.cpp
===================================================================
--- Trunk/XaraLX/Kernel/exjpeg.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/exjpeg.cpp (revision 1708)
@@ -945,6 +945,7 @@
break;
case 24:
+ case 32:
pOptions->SetColourModel(libJPEG::JCS_RGB);
break;
Index: Trunk/XaraLX/Kernel/camfiltr.cpp
===================================================================
--- Trunk/XaraLX/Kernel/camfiltr.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/camfiltr.cpp (revision 1708)
@@ -6994,54 +6994,31 @@
BOOL BaseCamelotFilter::WriteRemainingAtomicTagDefinitions ()
{
BOOL ok = TRUE;
-
+
CXaraFileRecord atomicRec(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
if (ok) ok = atomicRec.Init();
if (ok) ok = atomicRec.WriteUINT32(TAG_BEVEL); // NodeBevelController
- if (ok) ok = Write(&atomicRec); // And write out the record
+ if (ok) ok = atomicRec.WriteUINT32(TAG_BEVELINK); // NodeBevel
+ if (ok) ok = atomicRec.WriteUINT32(TAG_CONTOURCONTROLLER); // NodeContourController
+ if (ok) ok = atomicRec.WriteUINT32(TAG_CONTOUR); // NodeContour
+ if (ok) ok = atomicRec.WriteUINT32(TAG_SHADOWCONTROLLER); // NodeShadowController
+ if (ok) ok = atomicRec.WriteUINT32(TAG_SHADOW); // NodeShadow
+ if (ok) ok = atomicRec.WriteUINT32(TAG_CLIPVIEWCONTROLLER); // NodeClipViewController
+ if (ok) ok = atomicRec.WriteUINT32(TAG_CLIPVIEW); // NodeClipView
+ if (ok) ok = atomicRec.WriteUINT32(TAG_CURRENTATTRIBUTES); // Current Attributes container/component
+ // --------------------------------------------------------------
+ // Effect nodes marked as atomic in "Xara X2", 28/06/2005
+ if (ok) ok = atomicRec.WriteUINT32(TAG_LIVE_EFFECT); // NodeLiveEffect
+ if (ok) ok = atomicRec.WriteUINT32(TAG_LOCKED_EFFECT); // NodeLockedEffect
+ if (ok) ok = atomicRec.WriteUINT32(TAG_FEATHER_EFFECT); // NodeFeatherEffect
+// if (ok) ok = atomicRec.WriteUINT32(TAG_CURRENTATTRIBUTES_PHASE2); // Current Attributes container/component
+// if (ok) ok = atomicRec.WriteUINT32(TAG_SPREAD_PHASE2); // NodeSpread (in multi-spread docs)
- CXaraFileRecord atomicRec2(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
- if (ok) ok = atomicRec2.Init();
- if (ok) ok = atomicRec2.WriteUINT32(TAG_BEVELINK); // NodeBevel
- if (ok) ok = Write(&atomicRec2);
+ // Just keep writing more tags to the end of this one record
- CXaraFileRecord atomicRec3(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
- if (ok) ok = atomicRec3.Init();
- if (ok) ok = atomicRec3.WriteUINT32(TAG_CONTOURCONTROLLER); // NodeContourController
- if (ok) ok = Write(&atomicRec3);
+ // Write the whole record out
+ if (ok) ok = Write(&atomicRec);
- CXaraFileRecord atomicRec4(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
- if (ok) ok = atomicRec4.Init();
- if (ok) ok = atomicRec4.WriteUINT32(TAG_CONTOUR); // NodeContour
- if (ok) ok = Write(&atomicRec4);
-
- CXaraFileRecord atomicRec5(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
- if (ok) ok = atomicRec5.Init();
- if (ok) ok = atomicRec5.WriteUINT32(TAG_SHADOWCONTROLLER); // NodeShadowController
- if (ok) ok = Write(&atomicRec5);
-
- CXaraFileRecord atomicRec6(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
- if (ok) ok = atomicRec6.Init();
- if (ok) ok = atomicRec6.WriteUINT32(TAG_SHADOW); // NodeShadow
- if (ok) ok = Write(&atomicRec6);
-
- CXaraFileRecord atomicRec7(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
- if (ok) ok = atomicRec7.Init();
- if (ok) ok = atomicRec7.WriteUINT32(TAG_CLIPVIEWCONTROLLER); // NodeClipViewController
- if (ok) ok = Write(&atomicRec7);
-
- CXaraFileRecord atomicRec8(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
- if (ok) ok = atomicRec8.Init();
- if (ok) ok = atomicRec8.WriteUINT32(TAG_CLIPVIEW); // NodeClipView
- if (ok) ok = Write(&atomicRec8);
-
- CXaraFileRecord atomicRec9(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE);
- if (ok) ok = atomicRec9.Init();
- if (ok) ok = atomicRec9.WriteUINT32(TAG_CURRENTATTRIBUTES); // Current Attributes container/component
- if (ok) ok = Write(&atomicRec9);
-
-
-
return (ok);
}
Index: Trunk/XaraLX/Kernel/xpfrgn.cpp
===================================================================
--- Trunk/XaraLX/Kernel/xpfrgn.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/xpfrgn.cpp (revision 1708)
@@ -2262,6 +2262,7 @@
BOOL bOldLayerVisibility = FALSE;
Layer* pSingleLayer = NULL;
Spread* pSingleSpread = NULL;
+ NodeBitmap* pSingleBitmap = NULL;
if (pFirstNode == pLastNode)
{
if (pFirstNode->IsLayer())
@@ -2270,10 +2271,14 @@
bOldLayerVisibility = pSingleLayer->GetVisibleFlagState();
pSingleLayer->SetVisible(TRUE);
}
- if (pFirstNode->IsSpread())
+ else if (pFirstNode->IsSpread())
{
pSingleSpread = (Spread*)pFirstNode;
}
+ else if (pFirstNode->IsABitmap())
+ {
+ pSingleBitmap = (NodeBitmap*)pFirstNode;
+ }
}
// Find the bounding rect of the nodes and determine if the background needs
@@ -2443,6 +2448,12 @@
KernelBitmap* pRealBmp = KernelBitmap::MakeKernelBitmap(pFullBitmap);
+ // If we are converting a single NodeBitmap then maintain the lossy flag
+ if (pSingleBitmap && pSingleBitmap->GetBitmap())
+ {
+ pRealBmp->SetAsLossy(pSingleBitmap->GetBitmap()->IsLossy());
+ }
+
// Attach the bitmap to this document or a copy will be created when
// it is used in the NodeBitmap
BitmapList* pBmpList = NULL;
Index: Trunk/XaraLX/Kernel/imjpeg.cpp
===================================================================
--- Trunk/XaraLX/Kernel/imjpeg.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/imjpeg.cpp (revision 1708)
@@ -526,6 +526,9 @@
return FALSE;
}
+ // Make sure this bitmap is treated as lossy
+ pOilBitmap->SetAsLossy();
+
// Clear any eof signal as CCFile considers this an error
if (m_pFile->eof())
{
Index: Trunk/XaraLX/Kernel/node.h
===================================================================
--- Trunk/XaraLX/Kernel/node.h (revision 1707)
+++ Trunk/XaraLX/Kernel/node.h (revision 1708)
@@ -533,7 +533,13 @@
// This function returns NULL in the base class.
virtual KernelBitmap* EnumerateBitmaps(UINT32 Count);
-
+
+ // This function returns the special value 1e9 to indicate no effective minimum
+ virtual double GetEffectiveBitmapMinDPI(KernelBitmap* pBitmap) { return(1e9); }
+
+ // Replace a specific bitmap with another one
+ virtual BOOL ReplaceBitmap(KernelBitmap* pOrigBitmap, KernelBitmap* pNewBitmap) { return(FALSE); }
+
// Find out the optoken of the default operation for this node. (See EditSelectionOp and Return hotkey.)
virtual TCHAR* GetDefaultOpToken() {return NULL;}
Index: Trunk/XaraLX/Kernel/bitmap.cpp
===================================================================
--- Trunk/XaraLX/Kernel/bitmap.cpp (revision 1707)
+++ Trunk/XaraLX/Kernel/bitmap.cpp (revision 1708)
@@ -594,6 +594,37 @@
/********************************************************************************************
+> BOOL KernelBitmap::SetAsLossy(BOOL bLossy = TRUE)
+
+ Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
+ Created: 20/2/97
+
+ Returns: FALSE if invalid pointer found
+
+ Purpose: Set this bitmap' lossy flag
+
+********************************************************************************************/
+
+BOOL KernelBitmap::SetAsLossy(BOOL bLossy)
+{
+ if (ActualBitmap == NULL)
+ return FALSE;
+
+ ERROR3IF_OILBMP_PTR_INVALID(ActualBitmap,
+ "Bitmap Error. Found a reference to a deleted bitmap.");
+
+ if (ActualBitmap)
+ {
+ ActualBitmap->SetAsLossy(bLossy);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/********************************************************************************************
+
> BOOL KernelBitmap::IsDefaultBitmap()
Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xxxxxxxx>
@@ -1542,6 +1573,8 @@
{
// We can't replace the default bitmap so make a new OilBitmap and attach that
CWxBitmap *pOilBitmap = new CWxBitmap(pInfo, pBits);
+ if (pOilBitmap && IsLossy())
+ pOilBitmap->SetAsLossy();
ActualBitmap = OILBitmap::Attach(pOilBitmap);
}
else
@@ -1748,6 +1781,31 @@
}
+/********************************************************************************************
+
+> BOOL KernelBitmap::IsLossy()
+
+ Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
+ Created: 15/8/96
+ Purpose: Finds if this bitmap is lossy or not
+
+********************************************************************************************/
+
+BOOL KernelBitmap::IsLossy()
+{
+ if (ActualBitmap == NULL)
+ return FALSE;
+
+ ERROR3IF_OILBMP_PTR_INVALID(ActualBitmap,
+ "Bitmap Error. Found a reference to a deleted bitmap.");
+
+ if (HasBeenDeleted())
+ return OILBitmap::Default->IsLossy();
+
+ return ActualBitmap->IsLossy();
+}
+
+
/*******************************************************************************************
> UINT32 KernelBitmap::GetDelay()
@@ -2217,6 +2275,7 @@
m_bIsAFractal = FALSE;
m_bIsGreyscale = FALSE;
+ m_bIsLossy = FALSE;
SetBitmapAnimDelay(10);
SetAnimationRestoreType(GDM_LEAVE);
Index: Trunk/XaraLX/wxOil/xpoilflt.cpp
===================================================================
--- Trunk/XaraLX/wxOil/xpoilflt.cpp (revision 1707)
+++ Trunk/XaraLX/wxOil/xpoilflt.cpp (revision 1708)
@@ -857,6 +857,7 @@
BOOL bAlpha = TRUE;
long Compression = 200;
String_256 CommonTrans;
+ BOOL bResample = FALSE;
wxString str;
str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"dpi"));
@@ -883,8 +884,14 @@
CommonTrans = str;
}
- pCapTree->SetRasterise(DPI, bAlpha, (INT32)Compression, CommonTrans);
+ str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"resample"));
+ if (!str.IsEmpty())
+ {
+ bResample = (str == _T("true"));
+ }
+ pCapTree->SetRasterise(DPI, bAlpha, (INT32)Compression, CommonTrans, bResample);
+
return TRUE;
}
Xara