[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]
[XaraXtreme-commits] Commit Complete
Commit by : gerry
Repository : xara
Revision : 1366
Date : Mon Jun 26 12:18:21 BST 2006
Changed paths:
M /Trunk/XaraLX/Kernel/bitmap.h
M /Trunk/XaraLX/Kernel/rndrgn.cpp
M /Trunk/XaraLX/Kernel/rndrgn.h
M /Trunk/XaraLX/Kernel/xpfcaps.cpp
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/Kernel/xpfrgn.h
M /Trunk/XaraLX/PreComp/camtypes.h
M /Trunk/XaraLX/wxOil/oilbitmap.cpp
M /Trunk/XaraLX/wxOil/oilbitmap.h
M /Trunk/XaraLX/wxOil/xpoilflt.cpp
M /Trunk/XaraLX/wxOil/xrc/EN/xpfres-strings.xrc
Updates to conversion system to support commontrans and onlycontent attributes and generate masked bitmaps
Diff:
Index: Trunk/XaraLX/Kernel/xpfilter.h
===================================================================
--- Trunk/XaraLX/Kernel/xpfilter.h (revision 1365)
+++ Trunk/XaraLX/Kernel/xpfilter.h (revision 1366)
@@ -222,6 +222,7 @@
BOOL m_bSaveXPEBitmaps;
BoundsWriteLevel m_BoundsLevel;
+ INT32 m_BitmapCompression;
List m_BitmapList;
INT32 m_BitmapCount;
Index: Trunk/XaraLX/Kernel/xpfcaps.h
===================================================================
--- Trunk/XaraLX/Kernel/xpfcaps.h (revision 1365)
+++ Trunk/XaraLX/Kernel/xpfcaps.h (revision 1366)
@@ -141,6 +141,9 @@
typedef INT32 XPFProp;
+#define XPFP_CONTENTONLY_TEXT 1
+#define XPFP_CONTENTONLY_PLAINTEXT 2
+
#define XPFP_UNKNOWN -1
#define XPFP_SHADOWTYPE_WALL 1
#define XPFP_SHADOWTYPE_FLOOR 2
@@ -247,6 +250,9 @@
virtual BOOL DoAttributesMatch(RenderRegion* pRegion) { return(FALSE); }
virtual BOOL DoesColourMatch(DocColour* pColour) { return(FALSE); }
+ BOOL AreAllChildrenText(Node* pRootNode, BOOL bPlain);
+ BOOL IsTextStoryPlain(Node* pNode);
+
protected:
XPFCapability* m_pNext;
XPFCapability* m_pChild;
@@ -313,7 +319,8 @@
XPFBOOL bPrintable,
XPFBOOL bActive,
XPFBOOL bBackground,
- XPFBOOL bGuide)
+ XPFBOOL bGuide,
+ XPFProp ContentOnly)
: XPFCComplexClass(CC_RUNTIME_CLASS(Layer), ConvertType)
{
m_bVisible = bVisible;
@@ -322,6 +329,7 @@
m_bActive = bActive;
m_bBackground = bBackground;
m_bGuide = bGuide;
+ m_ContentOnly = ContentOnly;
}
virtual ~XPFCLayer()
{
@@ -337,6 +345,7 @@
XPFBOOL m_bActive;
XPFBOOL m_bBackground;
XPFBOOL m_bGuide;
+ XPFProp m_ContentOnly;
};
@@ -693,7 +702,6 @@
protected:
virtual BOOL DoesNodeMatch(Node* pNode);
- BOOL IsNodePlain(Node* pNode);
BOOL IsNodeJustified(Node* pNode);
protected:
@@ -1023,6 +1031,7 @@
m_bSelection = FALSE;
m_RasteriseDPI = 96.0;
m_bRasteriseAlpha = TRUE;
+ m_BitmapCompression = 200;
m_SpreadType = XPFCONVTYPE_NATIVE;
m_pObjects = NULL;
m_ObjectsType = XPFCONVTYPE_NATIVE;
@@ -1071,10 +1080,12 @@
void SetSpreadType(XPFConvertType Type) { m_SpreadType = Type; }
- void SetRasterise(double DPI, BOOL bAlpha)
+ void SetRasterise(double DPI, BOOL bAlpha, INT32 Compression, const String_256& CommonTrans)
{
m_RasteriseDPI = DPI;
m_bRasteriseAlpha = bAlpha;
+ m_BitmapCompression = Compression;
+ m_CommonTrans = CommonTrans;
}
void SetObjectsTree(XPFCapability* pObjects, XPFConvertType ObjectsType)
@@ -1103,6 +1114,10 @@
double GetRasteriseDPI() { return(m_RasteriseDPI); }
BOOL GetRasteriseAlpha() { return(m_bRasteriseAlpha); }
+ BOOL GetBitmapCompression() { return(m_BitmapCompression); }
+ BOOL HasRasteriseCommonTrans() { return(!m_CommonTrans.IsEmpty()); }
+ // Move this into cpp file when implemented
+ BOOL IsRasteriseCommonTrans(UINT32 Type);
XPFCapability* GetObjects(void) const { return(m_pObjects); }
XPFCapability* GetAttributes(void) const { return(m_pAttributes); }
@@ -1119,6 +1134,8 @@
double m_RasteriseDPI;
BOOL m_bRasteriseAlpha;
+ INT32 m_BitmapCompression;
+ String_256 m_CommonTrans;
XPFConvertType m_SpreadType;
Index: Trunk/XaraLX/Kernel/xpfcaps.cpp
===================================================================
--- Trunk/XaraLX/Kernel/xpfcaps.cpp (revision 1365)
+++ Trunk/XaraLX/Kernel/xpfcaps.cpp (revision 1366)
@@ -187,7 +187,157 @@
}
+BOOL XPFCapability::AreAllChildrenText(Node* pRootNode, BOOL bPlain)
+{
+ Node* pNode = pRootNode->FindFirstChild();
+ while (pNode)
+ {
+ // Check this node
+ if (pNode->IsAnObject())
+ {
+ // If it is a group then check its children
+ if (pNode->IsAGroup() && !AreAllChildrenText(pNode, bPlain))
+ return(FALSE);
+ // If it is not a text story then return false
+ if (!IS_A(pNode, TextStory))
+ return(FALSE);
+
+ if (bPlain && !IsTextStoryPlain(pNode))
+ return(FALSE);
+ }
+
+ // Move on to the next node
+ pNode = pNode->FindNext();
+ }
+
+ return(TRUE);
+}
+
+
+/****************************************************************************
+
+> BOOL XPFCapability::IsTextStoryPlain(Node* pNode)
+
+ Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
+ Created: 17/08/2005
+
+ Returns: TRUE if the node only contains "plain" text, FALSE if it doesn't
+ Purpose: This determines if a text story only contains simple text.
+ This is currently defined as flat fill, flat fill trans,
+ constant line width, no dash patterns etc...
+
+****************************************************************************/
+
+BOOL XPFCapability::IsTextStoryPlain(Node* pNode)
+{
+// TRACEUSER( "Gerry", _T("IsTextStoryPlain(%s)
"), pNode->GetRuntimeClass()->m_lpszClassName);
+
+ // If the node has children then we must loop through them testing each
+ Node* pChild = pNode->FindFirstChild();
+ while (pChild)
+ {
+ if (!IsTextStoryPlain(pChild))
+ return(FALSE);
+
+ pChild = pChild->FindNext();
+ }
+
+ if (pNode->IsAnAttribute())
+ {
+ NodeAttribute* pAttr = (NodeAttribute*)pNode;
+
+ // These don't return a sensible value from GetAttributeIndex so
+ // we have to check the runtime class
+ if (pAttr->GetAttributeType() == CC_RUNTIME_CLASS(AttrFillGeometry))
+ {
+ if (!pAttr->IsAFlatFill())
+ return(FALSE);
+ }
+ else if (pAttr->GetAttributeType() == CC_RUNTIME_CLASS(AttrTranspFillGeometry))
+ {
+ if (!pAttr->IsAFlatFill())
+ return(FALSE);
+
+ TranspFillAttribute* pTrans = (TranspFillAttribute*)(pAttr->GetAttributeValue());
+ // Get the type
+ UINT32 Type = pTrans->GetTranspType();
+ // If we are flat, mix and 0% trans
+ if (Type != TT_Mix ||
+ *(pTrans->GetStartTransp()) != 0)
+ {
+ return(FALSE);
+ }
+ }
+ else
+ {
+ switch (pAttr->GetAttributeIndex())
+ {
+ case ATTR_FILLGEOMETRY:
+ case ATTR_TRANSPFILLGEOMETRY:
+ {
+ TRACEUSER( "Gerry", _T("FillGeometry attribute not trapped
"));
+ }
+ break;
+
+ case ATTR_DASHPATTERN:
+ {
+ DashPatternAttribute* pDash = (DashPatternAttribute*)(pAttr->GetAttributeValue());
+ DashPatternAttribute NoDash;
+ // If the attribute is different to the "no dash" then return FALSE
+ // then we do not match
+ if (NoDash.IsDifferent(pDash))
+ return(FALSE);
+ }
+ break;
+
+ case ATTR_STROKETYPE:
+ {
+ StrokeTypeAttrValue* pStroke = (StrokeTypeAttrValue*)(pAttr->GetAttributeValue());
+ StrokeTypeAttrValue DefStroke;
+ if (!((*pStroke) == DefStroke))
+ return(FALSE);
+ }
+ break;
+
+ case ATTR_VARWIDTH:
+ {
+ VariableWidthAttrValue* pVarWidth = (VariableWidthAttrValue*)(pAttr->GetAttributeValue());
+ VariableWidthAttrValue DefVarWidth;
+ if (!((*pVarWidth) == DefVarWidth))
+ return(FALSE);
+ }
+ break;
+
+ case ATTR_BRUSHTYPE:
+ {
+ BrushAttrValue* pBrush = (BrushAttrValue*)(pAttr->GetAttributeValue());
+ BrushAttrValue DefBrush;
+ if (DefBrush.IsDifferent(pBrush))
+ return(FALSE);
+ }
+ break;
+
+ case ATTR_FEATHER:
+ {
+ FeatherAttrValue* pFeather = (FeatherAttrValue*)(pAttr->GetAttributeValue());
+ if (pFeather->GetFeatherSize() != 0)
+ return(FALSE);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ // We've got this far so there are no non-plain attributes and we can return TRUE
+ return(TRUE);
+}
+
+
+
BOOL XPFCComplexClass::DoesNodeMatch(Node* pNode)
{
return(pNode->IsKindOf(m_pClass));
@@ -221,6 +371,17 @@
if (m_bGuide != XPFB_UNKNOWN && pLayer->IsGuide() != m_bGuide)
return(FALSE);
+ if (m_ContentOnly != XPFP_UNKNOWN)
+ {
+ // Currently we only support text and plaintext
+ // Loop through subtree checking all objects
+ // If not a text story then return false
+ // If doing plaintext then if not plain return false
+
+ if (!AreAllChildrenText(pNode, (m_ContentOnly == XPFP_CONTENTONLY_PLAINTEXT)))
+ return(FALSE);
+ }
+
return(TRUE);
}
@@ -506,8 +667,8 @@
if (m_bPlain != XPFB_UNKNOWN)
{
// Scan story for non-plain attributes
- BOOL bPlain = IsNodePlain(pStory);
- TRACEUSER( "Gerry", _T("IsNodePlain returned %s
"), bPlain ? _T("true") : _T("false"));
+ BOOL bPlain = IsTextStoryPlain(pStory);
+ TRACEUSER( "Gerry", _T("IsTextStoryPlain returned %s
"), bPlain ? _T("true") : _T("false"));
if (bPlain != m_bPlain)
return(FALSE);
}
@@ -533,128 +694,6 @@
/****************************************************************************
-> BOOL XPFCText::IsNodePlain(Node* pNode)
-
- Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
- Created: 17/08/2005
-
- Returns: TRUE if the node only contains "plain" text, FALSE if it doesn't
- Purpose: This determines if a text story only contains simple text.
- This is currently defined as flat fill, flat fill trans,
- constant line width, no dash patterns etc...
-
-****************************************************************************/
-
-BOOL XPFCText::IsNodePlain(Node* pNode)
-{
-// TRACEUSER( "Gerry", _T("IsNodePlain(%s)
"), pNode->GetRuntimeClass()->m_lpszClassName);
-
- // If the node has children then we must loop through them testing each
- Node* pChild = pNode->FindFirstChild();
- while (pChild)
- {
- if (!IsNodePlain(pChild))
- return(FALSE);
-
- pChild = pChild->FindNext();
- }
-
- if (pNode->IsAnAttribute())
- {
- NodeAttribute* pAttr = (NodeAttribute*)pNode;
-
- // These don't return a sensible value from GetAttributeIndex so
- // we have to check the runtime class
- if (pAttr->GetAttributeType() == CC_RUNTIME_CLASS(AttrFillGeometry))
- {
- if (!pAttr->IsAFlatFill())
- return(FALSE);
- }
- else if (pAttr->GetAttributeType() == CC_RUNTIME_CLASS(AttrTranspFillGeometry))
- {
- if (!pAttr->IsAFlatFill())
- return(FALSE);
-
- TranspFillAttribute* pTrans = (TranspFillAttribute*)(pAttr->GetAttributeValue());
- // Get the type
- UINT32 Type = pTrans->GetTranspType();
- // If we are flat, mix and 0% trans
- if (Type != TT_Mix ||
- *(pTrans->GetStartTransp()) != 0)
- {
- return(FALSE);
- }
- }
- else
- {
- switch (pAttr->GetAttributeIndex())
- {
- case ATTR_FILLGEOMETRY:
- case ATTR_TRANSPFILLGEOMETRY:
- {
- TRACEUSER( "Gerry", _T("FillGeometry attribute not trapped
"));
- }
- break;
-
- case ATTR_DASHPATTERN:
- {
- DashPatternAttribute* pDash = (DashPatternAttribute*)(pAttr->GetAttributeValue());
- DashPatternAttribute NoDash;
- // If the attribute is different to the "no dash" then return FALSE
- // then we do not match
- if (NoDash.IsDifferent(pDash))
- return(FALSE);
- }
- break;
-
- case ATTR_STROKETYPE:
- {
- StrokeTypeAttrValue* pStroke = (StrokeTypeAttrValue*)(pAttr->GetAttributeValue());
- StrokeTypeAttrValue DefStroke;
- if (!((*pStroke) == DefStroke))
- return(FALSE);
- }
- break;
-
- case ATTR_VARWIDTH:
- {
- VariableWidthAttrValue* pVarWidth = (VariableWidthAttrValue*)(pAttr->GetAttributeValue());
- VariableWidthAttrValue DefVarWidth;
- if (!((*pVarWidth) == DefVarWidth))
- return(FALSE);
- }
- break;
-
- case ATTR_BRUSHTYPE:
- {
- BrushAttrValue* pBrush = (BrushAttrValue*)(pAttr->GetAttributeValue());
- BrushAttrValue DefBrush;
- if (DefBrush.IsDifferent(pBrush))
- return(FALSE);
- }
- break;
-
- case ATTR_FEATHER:
- {
- FeatherAttrValue* pFeather = (FeatherAttrValue*)(pAttr->GetAttributeValue());
- if (pFeather->GetFeatherSize() != 0)
- return(FALSE);
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- // We've got this far so there are no non-plain attributes and we can return TRUE
- return(TRUE);
-}
-
-
-/****************************************************************************
-
> BOOL XPFCText::IsNodeJustified(Node* pNode)
Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
@@ -1028,6 +1067,32 @@
}
+BOOL CapabilityTree::IsRasteriseCommonTrans(UINT32 Type)
+{
+ String_16 TransStr;
+
+ if (Type == TT_StainGlass)
+ TransStr = _T("stained");
+ else if (Type == TT_Bleach)
+ TransStr = _T("bleach");
+ else if (Type == TT_CONTRAST)
+ TransStr = _T("contrast");
+ else if (Type == TT_SATURATION)
+ TransStr = _T("saturation");
+ else if (Type == TT_LUMINOSITY)
+ TransStr = _T("luminosity");
+ else if (Type == TT_HUE)
+ TransStr = _T("hue");
+ else
+ return(FALSE);
+
+ if (camStrstr(m_CommonTrans, TransStr) != NULL)
+ return(TRUE);
+
+ return(FALSE);
+}
+
+
// Pass 1 can return the following convert types:
// Spread: native, bitmap, simple
// Layer: native, bitmap, simple
@@ -1128,6 +1193,12 @@
XPFConvertType CapabilityTree::GetConvertTypePass4(Node* pNode, XPFRenderRegion* pRegion)
{
+ // This pass must NOT convert any spreads or layers to bitmap as that will
+ // have been done during the first pass but the spread/layer node will still
+ // be present in the tree
+ if (pNode->IsSpread() || pNode->IsLayer())
+ return(XPFCONVTYPE_NATIVE);
+
XPFConvertType Type = GetObjectsType();
XPFCapability* pItem = GetObjects();
while (pItem)
Index: Trunk/XaraLX/Kernel/rndrgn.cpp
===================================================================
--- Trunk/XaraLX/Kernel/rndrgn.cpp (revision 1365)
+++ Trunk/XaraLX/Kernel/rndrgn.cpp (revision 1366)
@@ -382,6 +382,8 @@
m_fOwned = FALSE;
ScaleFactor = FIXED16(1);
+ m_bForceMix = FALSE;
+
// double m_dboostm = 1.0;
// double m_dboostc = 0.0;
@@ -485,6 +487,8 @@
m_countTotal = 0;
m_countStored = 0;
+ m_bForceMix = FALSE;
+
#ifdef _DEBUG
m_CurrentContextLevel = 0;
m_TraceOutContextLevels = FALSE;
@@ -592,6 +596,8 @@
m_countTotal = other.m_countTotal;
m_countStored = other.m_countStored;
+ m_bForceMix = other.m_bForceMix;
+
#ifdef _DEBUG
m_CurrentContextLevel = 0;
m_TraceOutContextLevels = FALSE;
@@ -2620,8 +2626,43 @@
void RenderRegion::SetLineTransp(StrokeTranspAttribute *pAttr, BOOL Temp)
{
+ StrokeTranspAttribute* pNewAttr = NULL;
+ if (m_bForceMix)
+ {
+ UINT32 Type = pAttr->GetTranspType();
+ if (Type != TT_NoTranspType &&
+ Type != TT_Mix &&
+ Type != TT_DARKEN &&
+ Type != TT_LIGHTEN &&
+ Type != TT_BRIGHTNESS &&
+ Type != TT_BEVEL)
+ {
+ if (Temp)
+ {
+ pNewAttr = pAttr;
+ }
+ else
+ {
+ pNewAttr = (StrokeTranspAttribute*)(pAttr->GetRuntimeClass()->CreateObject());
+ if (pNewAttr)
+ {
+ pNewAttr->SimpleCopy(pAttr);
+ }
+ }
+
+ }
+ }
+
+ if (pNewAttr)
+ {
+ pNewAttr->SetTranspType(TT_Mix);
+ Temp = TRUE;
+ }
+ else
+ pNewAttr = pAttr;
+
// Save the current attribute and set up the new one
- if (SaveAttribute(ATTR_STROKETRANSP, pAttr, Temp))
+ if (SaveAttribute(ATTR_STROKETRANSP, pNewAttr, Temp))
{
// The line attributes need to be reset before drawing anything.
SetLineAttributes(CHANGEATTR_STROKETRANSP);
@@ -2996,15 +3037,50 @@
void RenderRegion::SetTranspFillGeometry(TranspFillAttribute *pAttr, BOOL Temp)
{
+ TranspFillAttribute* pNewAttr = NULL;
+ if (m_bForceMix)
+ {
+ UINT32 Type = pAttr->GetTranspType();
+ if (Type != TT_NoTranspType &&
+ Type != TT_Mix &&
+ Type != TT_DARKEN &&
+ Type != TT_LIGHTEN &&
+ Type != TT_BRIGHTNESS &&
+ Type != TT_BEVEL)
+ {
+ if (Temp)
+ {
+ pNewAttr = pAttr;
+ }
+ else
+ {
+ pNewAttr = (TranspFillAttribute*)(pAttr->GetRuntimeClass()->CreateObject());
+ if (pNewAttr)
+ {
+ pNewAttr->SimpleCopy(pAttr);
+ }
+ }
+
+ }
+ }
+
+ if (pNewAttr)
+ {
+ pNewAttr->SetTranspType(TT_Mix);
+ Temp = TRUE;
+ }
+ else
+ pNewAttr = pAttr;
+
// Save the current attribute
- if (SaveAttribute(ATTR_TRANSPFILLGEOMETRY, pAttr, Temp))
+ if (SaveAttribute(ATTR_TRANSPFILLGEOMETRY, pNewAttr, Temp))
{
// The fill attributes need to be reset before drawing anything.
SetFillAttributes(CHANGEATTR_TRANSP_GEOMETRY);
// The capture system needs to know about non-MIX transparencies being set
// because it can't capture them in RGBT bitmaps...
- UINT32 ttype = pAttr->GetTranspType();
+ UINT32 ttype = pNewAttr->GetTranspType();
ERROR3IF(ttype<TT_NoTranspType || ttype>TT_MAX, "Someone's trying to set an unknown transp type!");
// if (!(ttype==TT_NoTranspType || ttype==TT_Mix))
Index: Trunk/XaraLX/Kernel/xpfilter.cpp
===================================================================
--- Trunk/XaraLX/Kernel/xpfilter.cpp (revision 1365)
+++ Trunk/XaraLX/Kernel/xpfilter.cpp (revision 1366)
@@ -141,6 +141,7 @@
m_ProgressOffset = 0;
m_bSaveXPEBitmaps = TRUE; // For now we will default this to saving out the bitmaps
m_BoundsLevel = BWL_NONE;
+ m_BitmapCompression = 200; // Default to full PNG quality
m_BitmapCount = 0;
}
@@ -382,6 +383,9 @@
// Update our bounds write level
m_BoundsLevel = PlugCaps.GetBoundsLevel();
+ // Update our bitmap compression setting
+ m_BitmapCompression = PlugCaps.GetBitmapCompression();
+
KernelBitmap::SetCreateTracker(&m_BitmapList);
// Convert the document according to the capabilites
@@ -765,7 +769,7 @@
INT32 PluginNativeFilter::GetBitmapCompression()
{
// Always use a lossless format such as PNG in native files
- return 200;
+ return m_BitmapCompression;
}
/********************************************************************************************
Index: Trunk/XaraLX/Kernel/bitmap.h
===================================================================
--- Trunk/XaraLX/Kernel/bitmap.h (revision 1365)
+++ Trunk/XaraLX/Kernel/bitmap.h (revision 1366)
@@ -399,6 +399,8 @@
virtual BOOL RebuildXPEBitmap();
virtual BOOL NeedsXPERebuild();
+ virtual void CopyFullyTransparentFrom(OILBitmap* pBitmap) = 0;
+
protected:
String_256 m_BitmapName;
UINT32 m_BitmapAnimDelay;
Index: Trunk/XaraLX/Kernel/rndrgn.h
===================================================================
--- Trunk/XaraLX/Kernel/rndrgn.h (revision 1365)
+++ Trunk/XaraLX/Kernel/rndrgn.h (revision 1366)
@@ -712,6 +712,8 @@
void SetImmediateRender(BOOL SetVal) {RenderFlags.bImmediateRender = SetVal;}
BOOL GetImmediateRender() const {return RenderFlags.bImmediateRender;}
+ void SetForceMixTransparency(BOOL bForceMix) { m_bForceMix = bForceMix; }
+
/////////////////////////////////////////////////////////////////////
//
// New Capture system
@@ -933,6 +935,9 @@
// Used to record a connection to a filter
Filter* m_pFilter;
+ // Used to force all non-alpha compatible transparency to mix
+ BOOL m_bForceMix;
+
// double m_dboostm;
// double m_dboostc;
Index: Trunk/XaraLX/Kernel/xpfrgn.h
===================================================================
--- Trunk/XaraLX/Kernel/xpfrgn.h (revision 1365)
+++ Trunk/XaraLX/Kernel/xpfrgn.h (revision 1366)
@@ -107,6 +107,7 @@
class TextStory;
class TextLine;
class FormatRegion;
+class CommonTransInfo;
/********************************************************************************************
@@ -124,7 +125,7 @@
CC_DECLARE_DYNAMIC(XPFRenderRegion);
// Construction and destruction
- XPFRenderRegion(PluginNativeFilter* pFilter, CapabilityTree* pPlugCaps);
+ XPFRenderRegion(PluginNativeFilter* pFilter, CapabilityTree* pPlugCaps, CommonTransInfo* pTransInfo = NULL);
~XPFRenderRegion();
virtual BOOL AttachDevice(View*, CNativeDC*, Spread* SpreadToAttach = NULL);
@@ -177,9 +178,25 @@
protected:
PluginNativeFilter* m_pFilter;
double m_PixelsPerInch;
+ CommonTransInfo* m_pTransInfo;
};
+class CommonTransInfo
+{
+public:
+ CommonTransInfo();
+
+ BOOL IsCommonType() { return(m_bCommonType); }
+ void UpdateCommonType(UINT32 Type);
+ UINT32 GetCommonType();
+
+protected:
+ BOOL m_bCommonType;
+ UINT32 m_CommonType;
+};
+
+
class SpanListItem : public ListItem
{
public:
@@ -257,7 +274,7 @@
void RemoveChildAttrs(Node* pNode, CCRuntimeClass* pClass);
NodeAttribute* FindChildAttr(Node* pNode, CCRuntimeClass* pClass);
- NodeBitmap* RenderNodesToBitmap(Node* pFirstNode, Node* pLastNode, BOOL bNonAlphaTrans);
+ Node* RenderNodesToBitmap(Node* pFirstNode, Node* pLastNode, BOOL bNonAlphaTrans);
KernelBitmap* RenderFillToBitmap(Node* pNode, DocRect& BoundsRect);
KernelBitmap* RenderTransToBitmap(Node* pNode, DocRect& BoundsRect, UINT32* pTransType);
KernelBitmap* RenderFillAndTransToBitmap(Node* pNode, DocRect& BoundsRect);
@@ -267,6 +284,7 @@
BOOL CopyAttributesFromNode(Node* pDestNode, Node* pSrcNode);
BOOL DoesNodeUseNonAlphaTrans(Node* pRootNode);
+ BOOL FindCommonTransTypeToApply(Node* pFirstNode, Node* pLastNode, UINT32* pCommonType);
private:
INT32 m_ConvertPass;
@@ -301,117 +319,10 @@
m_RenderState = RS_BEFORESPAN;
}
- virtual BOOL BeforeNode(RenderRegion* pRegion, Node* pNode)
- {
-// char* pStateStr = (m_RenderState == RS_INSPAN) ? "in" : (m_RenderState == RS_AFTERSPAN) ? "after" : "before";
-// TRACE( _T("XPFSpanRC# BeforeNode 0x%08x - %s %s
"), pNode, pNode->GetRuntimeClass()->m_lpszClassName, pStateStr);
-
- BOOL bRender = FALSE;
- switch (m_RenderState)
- {
- case RS_BEFORESPAN:
- if (m_bBackground || pNode->IsAnAttribute() || pNode->IsANodeClipView())
- {
- // Let it render normally
- bRender = TRUE;
- }
- break;
+ virtual BOOL BeforeNode(RenderRegion* pRegion, Node* pNode);
+ virtual BOOL BeforeSubtree(RenderRegion* pRegion, Node* pNode, Node** ppNextNode, BOOL bClip, SubtreeRenderState* pState);
+ virtual BOOL AfterSubtree(RenderRegion* pRegion, Node* pNode);
- case RS_INSPAN:
- bRender = TRUE;
- break;
-
- case RS_AFTERSPAN:
- // Must skip everything until the end
- bRender = FALSE;
- break;
-
- default:
- TRACE( _T("XPFSpanRC# Bad RenderState in BeforeNode
"));
- break;
- }
-// TRACE( _T("XPFSpanRC# BeforeNode 0x%08x - %s returning %s
", pNode, pNode->GetRuntimeClass()->m_lpszClassName, bRender ? "true" : "false"));
- return(bRender);
- }
-
- virtual BOOL BeforeSubtree(RenderRegion* pRegion, Node* pNode, Node** ppNextNode, BOOL bClip, SubtreeRenderState* pState)
- {
-// char* pStateStr = (m_RenderState == RS_INSPAN) ? "in" : (m_RenderState == RS_AFTERSPAN) ? "after" : "before";
-// TRACE( _T("XPFSpanRC# BeforeSubtree 0x%08x - %s %s
"), pNode, pNode->GetRuntimeClass()->m_lpszClassName, pStateStr);
-
- switch (m_RenderState)
- {
- case RS_BEFORESPAN:
- if (pNode == m_pFirstNode)
- {
-// TRACE( _T("XPFSpanRC# Start of span
"));
- // Change state to be in the span
- m_RenderState = RS_INSPAN;
- }
- else if (!pNode->IsAnAttribute() && !m_bBackground && !pNode->IsNodeInSubtree(m_pFirstNode))
- {
- // The first node isn't in this subtree so don't bother rendering it
- *pState = SUBTREE_NORENDER;
- return(TRUE);
- }
- break;
-
- case RS_INSPAN:
- break;
-
- case RS_AFTERSPAN:
- // Don't render this subtree
- *pState = SUBTREE_NORENDER;
- return(TRUE);
- break;
-
- default:
- TRACE( _T("XPFSpanRC# Bad RenderState in BeforeSubtree
"));
- break;
- }
-
- return(FALSE);
- }
-
- virtual BOOL AfterSubtree(RenderRegion* pRegion, Node* pNode)
- {
-// char* pStateStr = (m_RenderState == RS_INSPAN) ? "in" : (m_RenderState == RS_AFTERSPAN) ? "after" : "before";
-// TRACE( _T("XPFSpanRC# AfterSubtree 0x%08x - %s %s
"), pNode, pNode->GetRuntimeClass()->m_lpszClassName, pStateStr);
-
- // By default we do want RenderAfterSubtree to be called
- BOOL bStopRender = FALSE;
- switch (m_RenderState)
- {
- case RS_BEFORESPAN:
- if (!m_bBackground && !pNode->IsNodeInSubtree(m_pFirstNode))
- {
- // The first node isn't in this subtree so don't bother rendering it
- bStopRender = TRUE;
- }
- break;
-
- case RS_INSPAN:
- if (pNode == m_pLastNode)
- {
-// TRACE( _T("XPFSpanRC# End of span
"));
- // Change state to be after the span
- m_RenderState = RS_AFTERSPAN;
- }
- break;
-
- case RS_AFTERSPAN:
- // Must skip everything until the end
- bStopRender = TRUE;
- break;
-
- default:
- TRACE( _T("XPFSpanRC# Bad RenderState in AfterSubtree
"));
- break;
- }
-// TRACE( _T("XPFSpanRC# AfterSubtree 0x%08x - %s returning %s
", pNode, pNode->GetRuntimeClass()->m_lpszClassName, bStopRender ? "true" : "false"));
- return(bStopRender);
- }
-
protected:
Node* m_pFirstNode; // pointer to first node in span
Node* m_pLastNode; // pointer to last node in span
Index: Trunk/XaraLX/Kernel/xpfrgn.cpp
===================================================================
--- Trunk/XaraLX/Kernel/xpfrgn.cpp (revision 1365)
+++ Trunk/XaraLX/Kernel/xpfrgn.cpp (revision 1366)
@@ -135,7 +135,9 @@
/********************************************************************************************
-> XPFRenderRegion::XPFRenderRegion(PluginNativeFilter* pFilter, CapabilityTree* pPlugCaps)
+> XPFRenderRegion::XPFRenderRegion(PluginNativeFilter* pFilter,
+ CapabilityTree* pPlugCaps,
+ CommonTransInfo* pTransInfo)
Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xxxxxxxx>
Created: 6/4/95
@@ -144,10 +146,11 @@
********************************************************************************************/
-XPFRenderRegion::XPFRenderRegion(PluginNativeFilter* pFilter, CapabilityTree* pPlugCaps)
+XPFRenderRegion::XPFRenderRegion(PluginNativeFilter* pFilter, CapabilityTree* pPlugCaps, CommonTransInfo* pTransInfo)
{
m_pFilter = pFilter;
- m_PixelsPerInch = pPlugCaps->GetRasteriseDPI();
+ m_PixelsPerInch = pPlugCaps ? pPlugCaps->GetRasteriseDPI() : 96.0;
+ m_pTransInfo = pTransInfo;
}
@@ -238,6 +241,41 @@
void XPFRenderRegion::DrawPathToOutputDevice(Path* pPathToRender, PathShape)
{
+ if (m_pTransInfo && m_pTransInfo->IsCommonType())
+ {
+ // Path rendering happens in two parts, the fill and the stroke
+ // so these must be checked separately
+
+ if (pPathToRender->IsFilled)
+ {
+ // Get the fill attribute
+ FillGeometryAttribute* pFillAttr = (FillGeometryAttribute*) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
+
+ // If it is not a no-colour flat fill then
+
+ if (!IS_A(pFillAttr, FlatFillAttribute) || !(RR_FILLCOLOUR().IsTransparent()))
+ {
+ // Get the current Transparency Fill Geometry
+ TranspFillAttribute* pTransAttr = RR_FILLTRANSP();
+
+ // And update the common type object
+ m_pTransInfo->UpdateCommonType(pTransAttr->GetTranspType());
+ }
+ }
+
+ if (pPathToRender->IsStroked)
+ {
+ // If the stroke colour is not transparent
+ if (!(RR_STROKECOLOUR().IsTransparent()))
+ {
+ // Get the current Transparency Fill Geometry
+ StrokeTranspAttribute* pTransAttr = RR_STROKETRANSP();
+
+ // And update the common type object
+ m_pTransInfo->UpdateCommonType(pTransAttr->GetTranspType());
+ }
+ }
+ }
}
@@ -1031,7 +1069,7 @@
BOOL bNonAlphaTrans = DoesNodeUseNonAlphaTrans(pNode);
TRACEUSER("Gerry", _T("XPFRC# Converting %s to bitmap (%s)
"), pNode->GetRuntimeClass()->m_lpszClassName, bNonAlphaTrans ? _T("NonAlpha") : _T("Alpha"));
- NodeBitmap* pNodeToAttach = RenderNodesToBitmap(pNode, pNode, bNonAlphaTrans);
+ Node* pNodeToAttach = RenderNodesToBitmap(pNode, pNode, bNonAlphaTrans);
if (pNodeToAttach)
{
// Attach the new node into the output tree
@@ -1500,40 +1538,44 @@
// transparency types (anywhere in its subtree)
// If this isn't a renderable ink node then get out
- if (!pRootNode->IS_KIND_OF(NodeRenderableInk))
- return(FALSE);
+ // It might be a layer or spread which are paper nodes!
+// if (!pRootNode->IS_KIND_OF(NodeRenderableInk))
+// return(FALSE);
- NodeRenderableInk* pInkNode = (NodeRenderableInk*)pRootNode;
- // Basically, it just needs to check any transparency attributes
- // First it needs to check the attributes applied above this node in the tree
+ if (pRootNode->IsAnObject())
+ {
+ NodeRenderableInk* pInkNode = (NodeRenderableInk*)pRootNode;
+ // Basically, it just needs to check any transparency attributes
+ // First it needs to check the attributes applied above this node in the tree
- AttrStrokeTransp* pStrkAttr = (AttrStrokeTransp*)(pInkNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeTransp), TRUE));
- if (pStrkAttr)
- {
- UINT32 Type = pStrkAttr->GetTranspType();
- if (Type != TT_NoTranspType &&
- Type != TT_Mix &&
- Type != TT_DARKEN &&
- Type != TT_LIGHTEN &&
- Type != TT_BRIGHTNESS &&
- Type != TT_BEVEL)
+ AttrStrokeTransp* pStrkAttr = (AttrStrokeTransp*)(pInkNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeTransp), TRUE));
+ if (pStrkAttr)
{
- return(TRUE);
+ UINT32 Type = pStrkAttr->GetTranspType();
+ if (Type != TT_NoTranspType &&
+ Type != TT_Mix &&
+ Type != TT_DARKEN &&
+ Type != TT_LIGHTEN &&
+ Type != TT_BRIGHTNESS &&
+ Type != TT_BEVEL)
+ {
+ return(TRUE);
+ }
}
- }
- AttrFillGeometry* pFillAttr = (AttrFillGeometry*)(pInkNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrTranspFillGeometry), TRUE));
- if (pFillAttr)
- {
- UINT32 Type = pFillAttr->GetTranspType();
- if (Type != TT_NoTranspType &&
- Type != TT_Mix &&
- Type != TT_DARKEN &&
- Type != TT_LIGHTEN &&
- Type != TT_BRIGHTNESS &&
- Type != TT_BEVEL)
+ AttrFillGeometry* pFillAttr = (AttrFillGeometry*)(pInkNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrTranspFillGeometry), TRUE));
+ if (pFillAttr)
{
- return(TRUE);
+ UINT32 Type = pFillAttr->GetTranspType();
+ if (Type != TT_NoTranspType &&
+ Type != TT_Mix &&
+ Type != TT_DARKEN &&
+ Type != TT_LIGHTEN &&
+ Type != TT_BRIGHTNESS &&
+ Type != TT_BEVEL)
+ {
+ return(TRUE);
+ }
}
}
@@ -2028,12 +2070,12 @@
// Render the node span to a bitmap
BOOL bNonAlphaTrans = DoesNodeUseNonAlphaTrans(pNode);
- NodeBitmap* pNodeBmp = RenderNodesToBitmap(pNode, pNode, bNonAlphaTrans);
- if (!pNodeBmp)
+ Node* pNewNode = RenderNodesToBitmap(pNode, pNode, bNonAlphaTrans);
+ if (!pNewNode)
return(FALSE);
// Attach the new node as the previous of the first in the span
- pNodeBmp->AttachNode(pNode, PREV);
+ pNewNode->AttachNode(pNode, PREV);
// Delete the node we have just replaced
pNode->CascadeDelete();
@@ -2081,12 +2123,12 @@
TRACEUSER( "Gerry", _T("SpanListItem 0x%08x (%s) to 0x%08x (%s)
"), pItem->m_pFirstNode, pItem->m_pFirstNode->GetRuntimeClass()->m_lpszClassName, pItem->m_pLastNode, pItem->m_pLastNode->GetRuntimeClass()->m_lpszClassName);
// Render the node span to a bitmap
- NodeBitmap* pNodeBmp = RenderNodesToBitmap(pItem->m_pFirstNode, pItem->m_pLastNode, pItem->m_bNonAlphaTrans);
- if (!pNodeBmp)
+ Node* pNewNode = RenderNodesToBitmap(pItem->m_pFirstNode, pItem->m_pLastNode, pItem->m_bNonAlphaTrans);
+ if (!pNewNode)
return(FALSE);
// Attach the new node as the previous of the first in the span
- pNodeBmp->AttachNode(pItem->m_pFirstNode, PREV);
+ pNewNode->AttachNode(pItem->m_pFirstNode, PREV);
// Delete all the nodes in the span
Node* pNode = pItem->m_pFirstNode;
@@ -2115,10 +2157,75 @@
}
+/****************************************************************************
+> BOOL XPFRenderCallback::FindCommonTransTypeToApply(Node* pFirstNode, Node* pLastNode, UINT32* pCommonType)
+
+ Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
+ Created: 15/06/2006
+
+ Inputs: pFirstNode - pointer to a Node
+ pLastNode - pointer to a Node
+ pCommonType - pointer to a UINT32
+ Returns: TRUE if ok, FALSE if bother
+ Purpose:
+
+****************************************************************************/
+
+BOOL XPFRenderCallback::FindCommonTransTypeToApply(Node* pFirstNode, Node* pLastNode, UINT32* pCommonType)
+{
+ // If CommonTrans isn't set then return false
+ if (!m_pCapTree->HasRasteriseCommonTrans())
+ return(FALSE);
+
+ // Render the node span using an XPFRenderRegion and XPFSpanRenderCallback
+ // to track the transparency used
+ View *pView = View::GetCurrent();
+ Spread* pSpread = pFirstNode->FindParentSpread();;
+
+ CommonTransInfo TransInfo;
+
+ // Create and set up a new XPFRenderRegion
+ XPFRenderRegion XPFRegion(NULL, NULL, &TransInfo);
+
+ // Attach a device to the scanning render region
+ // Since this rr does no real rendering, it does not need a Device context
+ XPFRegion.AttachDevice(pView, NULL, pSpread);
+
+ // Start the render region and return if it fails
+ if (XPFRegion.StartRender())
+ {
+ TRACEUSER( "Gerry", _T("Rendering nodes from 0x%08x to 0x%08x
"), pFirstNode, pLastNode);
+ XPFSpanRenderCallback SpanCallback(pFirstNode, pLastNode, FALSE);
+ // Call RenderTree to do the rendering
+ XPFRegion.RenderTree(pSpread, FALSE, FALSE, &SpanCallback);
+
+ // Thats all the nodes rendered, so stop rendering
+ XPFRegion.StopRender();
+
+ // Check the CommonTransInfo
+ if (TransInfo.IsCommonType())
+ {
+ UINT32 CommonType = TransInfo.GetCommonType();
+ if (CommonType != TT_Mix)
+ {
+ *pCommonType = CommonType;
+ return(TRUE);
+ }
+ }
+ }
+ else
+ {
+ ERROR2(FALSE, "StartRender failed");
+ }
+
+ return(FALSE);
+}
+
+
/****************************************************************************
-> NodeBitmap* XPFRenderCallback::RenderNodesToBitmap(Node* pFirstNode, Node* pLastNode, BOOL bNonAlphaTrans)
+> Node* XPFRenderCallback::RenderNodesToBitmap(Node* pFirstNode, Node* pLastNode, BOOL bNonAlphaTrans)
Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
Created: 31/10/2005
@@ -2134,14 +2241,49 @@
****************************************************************************/
-NodeBitmap* XPFRenderCallback::RenderNodesToBitmap(Node* pFirstNode, Node* pLastNode, BOOL bNonAlphaTrans)
+Node* XPFRenderCallback::RenderNodesToBitmap(Node* pFirstNode, Node* pLastNode, BOOL bNonAlphaTrans)
{
+ // First we detect the single layer case for various bits of special handling
+ BOOL bOldLayerVisibility = FALSE;
+ Layer* pSingleLayer = NULL;
+ Spread* pSingleSpread = NULL;
+ if (pFirstNode == pLastNode)
+ {
+ if (pFirstNode->IsLayer())
+ {
+ pSingleLayer = (Layer*)pFirstNode;
+ bOldLayerVisibility = pSingleLayer->GetVisibleFlagState();
+ pSingleLayer->SetVisible(TRUE);
+ }
+ if (pFirstNode->IsSpread())
+ {
+ pSingleSpread = (Spread*)pFirstNode;
+ }
+ }
+
// Find the bounding rect of the nodes and determine if the background needs
// to be rendered
DocRect SpanBounds;
- BOOL bBackground = bNonAlphaTrans;
- if (!m_pCapTree->GetRasteriseAlpha())
+ BOOL bBackground = FALSE;
+ BOOL bForceMix = FALSE;
+ BOOL bAlpha = m_pCapTree->GetRasteriseAlpha();
+ UINT32 TransToApply = TT_NoTranspType;
+ if (!bAlpha)
+ {
bBackground = TRUE;
+ }
+ else
+ {
+ if (FindCommonTransTypeToApply(pFirstNode, pLastNode, &TransToApply))
+ {
+ bBackground = FALSE;
+ bForceMix = TRUE;
+ }
+ else
+ {
+ bBackground = bNonAlphaTrans;
+ }
+ }
Node* pNode = pFirstNode;
while (pNode)
@@ -2165,59 +2307,125 @@
FIXED16 TempScale(1.0);
double Dpi = m_pCapTree->GetRasteriseDPI();
- // Make sure that SpanBounds wont end up as a zero-sized rectangle
+ // Make sure that SpanBounds is an exact multiple of pixels and is at
+ // pixel multiples and is not zero-sized
double MPPerPix = 72000.0 / Dpi;
+
+ INT32 IntVal = (INT32)floor((double)SpanBounds.lo.x / MPPerPix);
+ SpanBounds.lo.x = (INT32)floor((double)IntVal * MPPerPix);
+ IntVal = (INT32)floor((double)SpanBounds.lo.y / MPPerPix);
+ SpanBounds.lo.y = (INT32)floor((double)IntVal * MPPerPix);
+ IntVal = (INT32)ceil((double)SpanBounds.hi.x / MPPerPix);
+ SpanBounds.hi.x = (INT32)ceil((double)IntVal * MPPerPix);
+ IntVal = (INT32)ceil((double)SpanBounds.hi.y / MPPerPix);
+ SpanBounds.hi.y = (INT32)ceil((double)IntVal * MPPerPix);
+
if (SpanBounds.Width() < MPPerPix)
- SpanBounds.hi.x = SpanBounds.lo.x + (INT32)(MPPerPix + 0.5);
+ SpanBounds.hi.x = (INT32)ceil((double)SpanBounds.lo.x + MPPerPix);
if (SpanBounds.Height() < MPPerPix)
- SpanBounds.hi.y = SpanBounds.lo.y + (INT32)(MPPerPix + 0.5);
+ SpanBounds.hi.y = (INT32)ceil((double)SpanBounds.lo.y + MPPerPix);
+ // Create a full 32bpp RGBA for the mask
+ // This is so that the antialiased pixels are handled correctly in the mask
+ // Rendering into a 1bpp mask only sets half of the edge pixels that an
+ // anti-aliased render does and the mask spreading feature doesn't correctly
+ // account for the difference
+ GRenderBitmap MaskBitmap(SpanBounds, ViewTrans, TempScale, 32, Dpi);
+ if (bBackground && bAlpha)
+ {
+ MaskBitmap.m_DoCompression = TRUE;
+ MaskBitmap.AttachDevice(pView, NULL, pSpread);
+
+ if (MaskBitmap.StartRender())
+ {
+ // Save the context here so we can clear everything up later
+ MaskBitmap.SaveContext();
+
+ // Best quality please
+ QualityAttribute *pQualAttr = new QualityAttribute();
+ pQualAttr->QualityValue.SetQuality(QUALITY_MAX);
+ MaskBitmap.SetQuality(pQualAttr, TRUE);
+
+ XPFSpanRenderCallback MaskCallback(pFirstNode, pLastNode, FALSE);
+ MaskBitmap.RenderTree(pSpread, FALSE, FALSE, &MaskCallback);
+
+ // Save the context here so we can clear everything up later
+ MaskBitmap.RestoreContext();
+
+ // Tell the render region we are done rendering
+ MaskBitmap.StopRender();
+ }
+ }
+
GRenderBitmap BitmapRR(SpanBounds, ViewTrans, TempScale, 32, Dpi);
if (!bBackground)
BitmapRR.m_DoCompression = TRUE;
+ BitmapRR.SetForceMixTransparency(bForceMix);
+ BitmapRR.SetUsingSmoothedBitmaps(TRUE); // Make sure we do high quality
BitmapRR.AttachDevice(pView, NULL, pSpread);
// Start rendering into the bitmap
- if (!BitmapRR.StartRender())
+ if (BitmapRR.StartRender())
{
- ERROR2(NULL, "StartRender failed in RenderNodesToBitmap");
- }
+ // Save the context here so we can clear everything up later
+ BitmapRR.SaveContext();
- // Save the context here so we can clear everything up later
- BitmapRR.SaveContext();
+ if (bBackground)
+ {
+ // Draw required background
+ DocRect DrawRect = SpanBounds;
+ // Inflate the rect by 2 pixels
+ DrawRect.Inflate( (INT32)(2*72000.0/Dpi + 0.5) );
- if (bBackground)
- {
- // Draw required background
- DocRect DrawRect = SpanBounds;
- // Inflate the rect by 2 pixels
- DrawRect.Inflate( (INT32)(2*72000.0/Dpi + 0.5) );
+ BitmapRR.SaveContext();
+ DocColour White(255,255,255);
+ BitmapRR.SetFillColour(White);
+ BitmapRR.DrawRect(&DrawRect);
+ BitmapRR.RestoreContext();
+ }
- BitmapRR.SaveContext();
- BitmapRR.SetFillColour(COLOUR_WHITE);
- BitmapRR.DrawRect(&DrawRect);
- BitmapRR.RestoreContext();
- }
+ // Best quality please
+ QualityAttribute *pQualAttr = new QualityAttribute();
+ pQualAttr->QualityValue.SetQuality(QUALITY_MAX);
+ BitmapRR.SetQuality(pQualAttr, TRUE);
- // Best quality please
- QualityAttribute *pQualAttr = new QualityAttribute();
- pQualAttr->QualityValue.SetQuality(QUALITY_MAX);
- BitmapRR.SetQuality(pQualAttr, TRUE);
+ // Render the relevant span of the tree
+ TRACEUSER("Gerry", _T("Rendering nodes from 0x%08x to 0x%08x%s
"), pFirstNode, pLastNode, bBackground ? _T(" with background") : _T(""));
+ XPFSpanRenderCallback SpanCallback(pFirstNode, pLastNode, bBackground);
+ BitmapRR.RenderTree(pSpread, FALSE, FALSE, &SpanCallback);
- // Render the relevant span of the tree
- TRACEUSER("Gerry", _T("Rendering nodes from 0x%08x to 0x%08x%s
"), pFirstNode, pLastNode, bBackground ? _T(" with background") : _T(""));
- XPFSpanRenderCallback SpanCallback(pFirstNode, pLastNode, bBackground);
- BitmapRR.RenderTree(pSpread, FALSE, FALSE, &SpanCallback);
+ // This should stop any captures
+ BitmapRR.RestoreContext();
- // This should stop any captures
- BitmapRR.RestoreContext();
+ // Stop rendering
+ BitmapRR.StopRender();
- // Stop rendering
- BitmapRR.StopRender();
+ // Reset the layer visiblity to the correct value
+ if (pSingleLayer)
+ pSingleLayer->SetVisible(bOldLayerVisibility);
+ }
+ else
+ {
+ ERROR2(NULL, "StartRender failed in RenderNodesToBitmap");
+ }
+ // Get the rendered OILBitmap
OILBitmap* pFullBitmap = BitmapRR.ExtractBitmap();
- String_256 BmpName = m_pFilter->GetNewBitmapName();
+ String_256 BmpName(m_pFilter->GetNewBitmapName());
pFullBitmap->SetName(BmpName);
+
+ if (bBackground && bAlpha)
+ {
+ // Merge in the mask info to knock out the surrounding areas
+ OILBitmap* pMaskBitmap = MaskBitmap.ExtractBitmap();
+ pFullBitmap->CopyFullyTransparentFrom(pMaskBitmap);
+
+ // We can't delete an OILBitmap directly so we create a
+ // KernelBitmap and then delete that
+ KernelBitmap* pTempBmp = KernelBitmap::MakeKernelBitmap(pMaskBitmap);
+ delete pTempBmp;
+ }
+
KernelBitmap* pRealBmp = KernelBitmap::MakeKernelBitmap(pFullBitmap);
// Attach the bitmap to this document or a copy will be created when
@@ -2232,16 +2440,55 @@
// Create a NodeBitmap not in the tree
NodeBitmap* pNodeBmp = new NodeBitmap();
- if (!pNodeBmp)
- {
- return(NULL);
- }
+ ERROR2IF(!pNodeBmp, NULL, "Failed to create NodeBitmap");
pNodeBmp->SetUpPath();
pNodeBmp->CreateShape(SpanBounds);
pNodeBmp->BitmapRef.Attach(pRealBmp); // Attach the correct bitmap
pNodeBmp->ApplyDefaultBitmapAttrs(NULL); // Apply the correct attrs
+ // If we should be applying a non-mix transparency then do so
+ if (TransToApply != TT_NoTranspType && TransToApply != TT_Mix)
+ {
+ AttrFlatTranspFill* pTrans = new AttrFlatTranspFill(pNodeBmp, FIRSTCHILD);
+ if (pTrans)
+ {
+ pTrans->SetTranspType(TransToApply);
+ UINT32 TransVal = 0;
+ pTrans->SetStartTransp(&TransVal);
+ }
+ }
+
+ if (pSingleSpread)
+ {
+ // Copy the spread and create a default layer
+ Spread* pNewSpread = (Spread*)(pSingleSpread->PublicCopy());
+ ERROR2IF(!pNewSpread, NULL, "Failed to create Spread");
+
+ Layer* pNewLayer = new Layer(pNewSpread, FIRSTCHILD, String_256("Layer 1"));
+ ERROR2IF(!pNewLayer, NULL, "Failed to create Layer");
+
+ // Attach the NodeBitmap as the first child of the new layer
+ pNodeBmp->AttachNode(pNewLayer, FIRSTCHILD);
+
+ // Return the new spread node
+ return(pNewSpread);
+ }
+
+ if (pSingleLayer)
+ {
+ // Create a shallow copy of the layer
+ Layer* pNewLayer = (Layer*)(pSingleLayer->PublicCopy());
+ ERROR2IF(!pNewLayer, NULL, "Failed to create Layer");
+
+ // Attach the NodeBitmap as the first child of the new layer
+ pNodeBmp->AttachNode(pNewLayer, FIRSTCHILD);
+
+ // Return the new layer node
+ return(pNewLayer);
+ }
+
+ // Just return the NodeBitmap
return(pNodeBmp);
}
@@ -2658,6 +2905,200 @@
/****************************************************************************
+> BOOL XPFSpanRenderCallback::BeforeNode(RenderRegion* pRegion, Node* pNode)
+
+ Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
+ Created: 19/06/2006
+
+ Inputs: pRegion - pointer to a RenderRegion
+ pNode - pointer to a Node
+ Returns: TRUE if ok, FALSE if bother
+ Purpose:
+
+****************************************************************************/
+
+BOOL XPFSpanRenderCallback::BeforeNode(RenderRegion* pRegion, Node* pNode)
+{
+// char* pStateStr = (m_RenderState == RS_INSPAN) ? "in" : (m_RenderState == RS_AFTERSPAN) ? "after" : "before";
+// TRACE( _T("XPFSpanRC# BeforeNode 0x%08x - %s %s
"), pNode, pNode->GetRuntimeClass()->m_lpszClassName, pStateStr);
+
+ BOOL bRender = FALSE;
+ switch (m_RenderState)
+ {
+ case RS_BEFORESPAN:
+ if (m_bBackground || pNode->IsAnAttribute() || pNode->IsANodeClipView())
+ {
+ // Let it render normally
+ bRender = TRUE;
+ }
+ break;
+
+ case RS_INSPAN:
+ bRender = TRUE;
+ break;
+
+ case RS_AFTERSPAN:
+ // Must skip everything until the end
+ bRender = FALSE;
+ break;
+
+ default:
+ TRACE( _T("XPFSpanRC# Bad RenderState in BeforeNode
"));
+ break;
+ }
+
+// TRACE( _T("XPFSpanRC# BeforeNode 0x%08x - %s returning %s
", pNode, pNode->GetRuntimeClass()->m_lpszClassName, bRender ? "true" : "false"));
+ return(bRender);
+}
+
+
+/****************************************************************************
+
+> BOOL XPFSpanRenderCallback::BeforeSubtree(RenderRegion* pRegion, Node* pNode, Node** ppNextNode, BOOL bClip, SubtreeRenderState* pState)
+
+ Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
+ Created: 19/06/2006
+
+ Inputs: pRegion - pointer to a RenderRegion
+ pNode - pointer to a Node
+ ppNextNode - pointer to a pointer to a Node
+ bClip -
+ pState - pointer to a SubtreeRenderState
+ Returns: TRUE if ok, FALSE if bother
+ Purpose:
+
+****************************************************************************/
+
+BOOL XPFSpanRenderCallback::BeforeSubtree(RenderRegion* pRegion, Node* pNode, Node** ppNextNode, BOOL bClip, SubtreeRenderState* pState)
+{
+// char* pStateStr = (m_RenderState == RS_INSPAN) ? "in" : (m_RenderState == RS_AFTERSPAN) ? "after" : "before";
+// TRACE( _T("XPFSpanRC# BeforeSubtree 0x%08x - %s %s
"), pNode, pNode->GetRuntimeClass()->m_lpszClassName, pStateStr);
+
+ switch (m_RenderState)
+ {
+ case RS_BEFORESPAN:
+ if (pNode == m_pFirstNode)
+ {
+// TRACE( _T("XPFSpanRC# Start of span
"));
+ // Change state to be in the span
+ m_RenderState = RS_INSPAN;
+ }
+ else if (!pNode->IsAnAttribute() && !m_bBackground && !pNode->IsNodeInSubtree(m_pFirstNode))
+ {
+ // The first node isn't in this subtree so don't bother rendering it
+ *pState = SUBTREE_NORENDER;
+ return(TRUE);
+ }
+ break;
+
+ case RS_INSPAN:
+ break;
+
+ case RS_AFTERSPAN:
+ // Don't render this subtree
+ *pState = SUBTREE_NORENDER;
+ return(TRUE);
+ break;
+
+ default:
+ TRACE( _T("XPFSpanRC# Bad RenderState in BeforeSubtree
"));
+ break;
+ }
+
+ return(FALSE);
+}
+
+
+/****************************************************************************
+
+> BOOL XPFSpanRenderCallback::AfterSubtree(RenderRegion* pRegion, Node* pNode)
+
+ Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
+ Created: 19/06/2006
+
+ Inputs: pRegion - pointer to a RenderRegion
+ pNode - pointer to a Node
+ Returns: TRUE if ok, FALSE if bother
+ Purpose:
+
+****************************************************************************/
+
+BOOL XPFSpanRenderCallback::AfterSubtree(RenderRegion* pRegion, Node* pNode)
+{
+// char* pStateStr = (m_RenderState == RS_INSPAN) ? "in" : (m_RenderState == RS_AFTERSPAN) ? "after" : "before";
+// TRACE( _T("XPFSpanRC# AfterSubtree 0x%08x - %s %s
"), pNode, pNode->GetRuntimeClass()->m_lpszClassName, pStateStr);
+
+ // By default we do want RenderAfterSubtree to be called
+ BOOL bStopRender = FALSE;
+ switch (m_RenderState)
+ {
+ case RS_BEFORESPAN:
+ if (!m_bBackground && !pNode->IsNodeInSubtree(m_pFirstNode))
+ {
+ // The first node isn't in this subtree so don't bother rendering it
+ bStopRender = TRUE;
+ }
+ break;
+
+ case RS_INSPAN:
+ if (pNode == m_pLastNode)
+ {
+// TRACE( _T("XPFSpanRC# End of span
"));
+ // Change state to be after the span
+ m_RenderState = RS_AFTERSPAN;
+ }
+ break;
+
+ case RS_AFTERSPAN:
+ // Must skip everything until the end
+ bStopRender = TRUE;
+ break;
+
+ default:
+ TRACE( _T("XPFSpanRC# Bad RenderState in AfterSubtree
"));
+ break;
+ }
+// TRACE( _T("XPFSpanRC# AfterSubtree 0x%08x - %s returning %s
", pNode, pNode->GetRuntimeClass()->m_lpszClassName, bStopRender ? "true" : "false"));
+ return(bStopRender);
+}
+
+
+
+CommonTransInfo::CommonTransInfo()
+{
+ m_bCommonType = TRUE;
+ m_CommonType = TT_NoTranspType;
+}
+
+void CommonTransInfo::UpdateCommonType(UINT32 Type)
+{
+ if (m_bCommonType)
+ {
+ if (Type == TT_NoTranspType ||
+ Type == TT_DARKEN ||
+ Type == TT_LIGHTEN ||
+ Type == TT_BRIGHTNESS ||
+ Type == TT_BEVEL)
+ {
+ Type = TT_Mix; // These are all mix
+ }
+
+ if (m_CommonType == TT_NoTranspType)
+ m_CommonType = Type;
+ else if (m_CommonType != Type)
+ m_bCommonType = FALSE;
+ }
+}
+
+UINT32 CommonTransInfo::GetCommonType()
+{
+ return(m_bCommonType ? m_CommonType : TT_NoTranspType);
+}
+
+
+
+/****************************************************************************
+
> XPFView::~XPFView()
Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xxxxxxxx>
Index: Trunk/XaraLX/wxOil/oilbitmap.cpp
===================================================================
--- Trunk/XaraLX/wxOil/oilbitmap.cpp (revision 1365)
+++ Trunk/XaraLX/wxOil/oilbitmap.cpp (revision 1366)
@@ -4270,4 +4270,34 @@
}
+void CWxBitmap::CopyFullyTransparentFrom(OILBitmap* pBitmap)
+{
+ if (GetWidth() != pBitmap->GetWidth() ||
+ GetHeight() != pBitmap->GetHeight() ||
+ GetBPP() != 32 ||
+ pBitmap->GetBPP() != 32)
+ {
+ ERROR3("Incompatible bitmaps passed to CopyFullyTransparentFrom");
+ return;
+ }
+ // Pointers to the pixel we are dealing with
+ UINT32* pMask = (UINT32*)(pBitmap->GetBitmapBits());
+ UINT32* pDest = (UINT32*)GetBitmapBits();
+
+ // Loop through all the pixels
+ for (UINT32 j=0; j < pBitmap->GetHeight(); j++)
+ {
+ for (UINT32 i=0; i < pBitmap->GetWidth(); i++)
+ {
+ // If this bit is background then set the corresponding pixel
+ // in the output bitmap to fully transparent black
+ if (*pMask == 0xFF000000)
+ *pDest = 0xFF000000;
+
+ // Move to the next pixel
+ pMask++;
+ pDest++;
+ }
+ }
+}
Index: Trunk/XaraLX/wxOil/xpoilflt.cpp
===================================================================
--- Trunk/XaraLX/wxOil/xpoilflt.cpp (revision 1365)
+++ Trunk/XaraLX/wxOil/xpoilflt.cpp (revision 1366)
@@ -204,6 +204,9 @@
{_T("bevel"), TT_BEVEL},
{NULL, XPFP_UNKNOWN}};
+PropMapEntry aContentOnly[] = { {_T("text"), XPFP_CONTENTONLY_TEXT},
+ {_T("plaintext"), XPFP_CONTENTONLY_PLAINTEXT},
+ {NULL, XPFP_UNKNOWN}};
/********************************************************************************************
@@ -710,60 +713,69 @@
{
// ignore it
}
- else if (strChildName == _T("Options"))
+ else if (strChildName == _T("Private"))
{
if (Phase > 0)
{
ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE0));
}
- bOK = ReadOptions(pChild, pCapTree); // Read the options attributes
+ // Ignore the entire element
Phase = 1;
}
- else if (strChildName == _T("Rasterise"))
+ else if (strChildName == _T("Options"))
{
if (Phase > 1)
{
ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE1));
}
- bOK = ReadRasterise(pChild, pCapTree); // Read the dpi and alpha attributes
+ bOK = ReadOptions(pChild, pCapTree); // Read the options attributes
Phase = 2;
}
- else if (strChildName == _T("Spread"))
+ else if (strChildName == _T("Rasterise"))
{
if (Phase > 2)
{
ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE2));
}
- bOK = ReadSpread(pChild, pCapTree); // Read the as attribute
+ bOK = ReadRasterise(pChild, pCapTree); // Read the dpi and alpha attributes
Phase = 3;
}
- else if (strChildName == _T("Objects"))
+ else if (strChildName == _T("Spread"))
{
if (Phase > 3)
{
ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE3));
}
- bOK = ReadObjects(pChild, pCapTree); // Build the tree of XPFCapability derived objects
+ bOK = ReadSpread(pChild, pCapTree); // Read the as attribute
Phase = 4;
}
- else if (strChildName == _T("Attributes"))
+ else if (strChildName == _T("Objects"))
{
if (Phase > 4)
{
ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE4));
}
- bOK = ReadAttributes(pChild, pCapTree); // Build the tree of XPFCapability derived objects
+ bOK = ReadObjects(pChild, pCapTree); // Build the tree of XPFCapability derived objects
Phase = 5;
}
- else if (strChildName == _T("Colour"))
+ else if (strChildName == _T("Attributes"))
{
if (Phase > 5)
{
ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE5));
}
- bOK = ReadColour(pChild, pCapTree); // Build the tree of XPFColour objects
+ bOK = ReadAttributes(pChild, pCapTree); // Build the tree of XPFCapability derived objects
Phase = 6;
}
+ else if (strChildName == _T("Colour"))
+ {
+ if (Phase > 6)
+ {
+ ERROR1(FALSE, _R(IDE_XPF_BADXML_PHASE6));
+ }
+ bOK = ReadColour(pChild, pCapTree); // Build the tree of XPFColour objects
+ Phase = 7;
+ }
else
{
ERROR1(FALSE, _R(IDE_XPF_BADXML_UNEXPECTED_PHASE));
@@ -816,6 +828,8 @@
{
double DPI = 96.0;
BOOL bAlpha = TRUE;
+ long Compression = 200;
+ String_256 CommonTrans;
wxString str;
str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"dpi"));
@@ -830,8 +844,20 @@
bAlpha = (str == _T("true"));
}
- pCapTree->SetRasterise(DPI, bAlpha);
+ str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"compression"));
+ if (!str.IsEmpty())
+ {
+ str.ToLong(&Compression);
+ }
+ str = CXMLUtils::ConvertToWXString(xmlGetProp(pNode, (xmlChar*)"commontrans"));
+ if (!str.IsEmpty())
+ {
+ CommonTrans = str;
+ }
+
+ pCapTree->SetRasterise(DPI, bAlpha, (INT32)Compression, CommonTrans);
+
return TRUE;
}
@@ -1203,7 +1229,9 @@
bOK = GetXPFBOOL(pNode, _T("background"), &bBackground);
XPFBOOL bGuide = XPFB_UNKNOWN;
bOK = GetXPFBOOL(pNode, _T("guide"), &bGuide);
- pCap = new XPFCLayer(AsType, bVisible, bLocked, bPrintable, bActive, bBackground, bGuide);
+ XPFProp ContentOnly = XPFP_UNKNOWN;
+ bOK = GetXPFProp(pNode, _T("onlycontent"), aContentOnly, &ContentOnly);
+ pCap = new XPFCLayer(AsType, bVisible, bLocked, bPrintable, bActive, bBackground, bGuide, ContentOnly);
}
else if (strName == _T("Contour"))
{
Index: Trunk/XaraLX/wxOil/oilbitmap.h
===================================================================
--- Trunk/XaraLX/wxOil/oilbitmap.h (revision 1365)
+++ Trunk/XaraLX/wxOil/oilbitmap.h (revision 1366)
@@ -235,6 +235,8 @@
virtual UINT32 GetHorizontalDPI();
virtual UINT32 GetVerticalDPI();
+ virtual void CopyFullyTransparentFrom(OILBitmap* pBitmap);
+
// these are public but MUST NOT be used from kernel code
LPBITMAPINFO BMInfo; // The information on the bitmap
Index: Trunk/XaraLX/wxOil/xrc/EN/xpfres-strings.xrc
===================================================================
--- Trunk/XaraLX/wxOil/xrc/EN/xpfres-strings.xrc (revision 1365)
+++ Trunk/XaraLX/wxOil/xrc/EN/xpfres-strings.xrc (revision 1366)
@@ -13,43 +13,49 @@
<object class="sizeritem">
<flag>wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE</flag>
<object class="wxStaticText" name="IDE_XPF_BADXML_PHASE0">
- <label>Expected Options node</label>
+ <label>Unexpected Private node</label>
</object>
</object>
<object class="sizeritem">
<flag>wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE</flag>
<object class="wxStaticText" name="IDE_XPF_BADXML_PHASE1">
- <label>Expected Rasterise node</label>
+ <label>Unexpected Options node</label>
</object>
</object>
<object class="sizeritem">
<flag>wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE</flag>
<object class="wxStaticText" name="IDE_XPF_BADXML_PHASE2">
- <label>Expected Spread node</label>
+ <label>Unexpected Rasterise node</label>
</object>
</object>
<object class="sizeritem">
<flag>wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE</flag>
<object class="wxStaticText" name="IDE_XPF_BADXML_PHASE3">
- <label>Expected Objects node</label>
+ <label>Unexpected Spread node</label>
</object>
</object>
<object class="sizeritem">
<flag>wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE</flag>
<object class="wxStaticText" name="IDE_XPF_BADXML_PHASE4">
- <label>Expected Attributes node</label>
+ <label>Unexpected Objects node</label>
</object>
</object>
<object class="sizeritem">
<flag>wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE</flag>
<object class="wxStaticText" name="IDE_XPF_BADXML_PHASE5">
- <label>Expected Colours node</label>
+ <label>Unexpected Attributes node</label>
</object>
</object>
<object class="sizeritem">
<flag>wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE</flag>
+ <object class="wxStaticText" name="IDE_XPF_BADXML_PHASE6">
+ <label>Unexpected Colours node</label>
+ </object>
+ </object>
+ <object class="sizeritem">
+ <flag>wxALIGN_LEFT|wxALL|wxADJUST_MINSIZE</flag>
<object class="wxStaticText" name="IDE_XPF_UNEXPECTED_PHASE">
- <label>Unexpected phase node</label>
+ <label>Unexpected element</label>
</object>
</object>
<object class="sizeritem">
Index: Trunk/XaraLX/PreComp/camtypes.h
===================================================================
--- Trunk/XaraLX/PreComp/camtypes.h (revision 1365)
+++ Trunk/XaraLX/PreComp/camtypes.h (revision 1366)
@@ -140,10 +140,17 @@
#include "ccobject.h"
#include "errors.h"
#include "camstring.h"
+
+#include "ccfile.h"
+#include "list.h"
+#include "listitem.h"
+#include "fixmem.h"
+#include "memblk.h"
+
+#if !defined(EXCLUDE_FROM_XARLIB)
+
#include "paldefs.h"
-#if !defined(EXCLUDE_FROM_XARLIB)
#include "app.h"
-
#include "document.h"
#include "docview.h"
#include "range.h"
@@ -153,14 +160,20 @@
#include "ink.h"
#include "nodeattr.h"
#include "attrval.h"
-#include "paths.h"
#include "undoop.h"
#include "bars.h"
#include "sgallery.h"
+#endif
+
+#include "paths.h"
+#include "cxfdefs.h"
+#include "cxfrech.h"
+#include "cxfrec.h"
+
+#if !defined(EXCLUDE_FROM_XARLIB)
// Alex added these which are included by more than 100 files
#include "camfiltr.h"
-#include "cxfrech.h"
#include "npaper.h"
#include "iprofile.h"
#include "biasgain.h"
@@ -170,13 +183,13 @@
#include "nodecomp.h"
#include "rrcaps.h"
#include "fillval.h"
-#include "cxfdefs.h"
#include "becomea.h"
-#include "cxfrec.h"
#include "group.h"
#endif
+
+
//-----------------------------------------------------------------------------------------//
// Some globally useful coordinate values...
Xara