/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Mozilla SVG project. * * The Initial Developer of the Original Code is * Crocodile Clips Ltd.. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Alex Fritze (original author) * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef __NS_SVGGLYPHFRAME_H__ #define __NS_SVGGLYPHFRAME_H__ #include "nsSVGGeometryFrame.h" #include "nsISVGGlyphFragmentLeaf.h" #include "nsISVGChildFrame.h" #include "gfxContext.h" #include "gfxFont.h" #include "gfxRect.h" #include "gfxMatrix.h" #include "nsSVGMatrix.h" class nsSVGTextFrame; class nsSVGGlyphFrame; class CharacterIterator; struct CharacterPosition; typedef nsSVGGeometryFrame nsSVGGlyphFrameBase; class nsSVGGlyphFrame : public nsSVGGlyphFrameBase, public nsISVGGlyphFragmentLeaf, // : nsISVGGlyphFragmentNode public nsISVGChildFrame { friend nsIFrame* NS_NewSVGGlyphFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); protected: nsSVGGlyphFrame(nsStyleContext* aContext) : nsSVGGlyphFrameBase(aContext), mTextRun(nsnull), mWhitespaceHandling(COMPRESS_WHITESPACE) {} ~nsSVGGlyphFrame() { ClearTextRun(); } public: NS_DECL_QUERYFRAME NS_DECL_FRAMEARENA_HELPERS // nsIFrame interface: NS_IMETHOD CharacterDataChanged(CharacterDataChangeInfo* aInfo); virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext); virtual void SetSelected(PRBool aSelected, SelectionType aType); NS_IMETHOD GetSelected(PRBool *aSelected) const; NS_IMETHOD IsSelectable(PRBool* aIsSelectable, PRUint8* aSelectStyle) const; NS_IMETHOD Init(nsIContent* aContent, nsIFrame* aParent, nsIFrame* aPrevInFlow); /** * Get the "type" of the frame * * @see nsGkAtoms::svgGlyphFrame */ virtual nsIAtom* GetType() const; virtual PRBool IsFrameOfType(PRUint32 aFlags) const { // Set the frame state bit for text frames to mark them as replaced. // XXX kipp: temporary return nsSVGGlyphFrameBase::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced)); } #ifdef DEBUG NS_IMETHOD GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("SVGGlyph"), aResult); } #endif // nsISVGChildFrame interface: // These four always use the global transform, even if NS_STATE_NONDISPLAY_CHILD NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, const nsIntRect *aDirtyRect); NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); NS_IMETHOD UpdateCoveredRegion(); virtual gfxRect GetBBoxContribution(const gfxMatrix &aToBBoxUserspace); NS_IMETHOD_(nsRect) GetCoveredRegion(); NS_IMETHOD InitialUpdate(); virtual void NotifySVGChanged(PRUint32 aFlags); NS_IMETHOD NotifyRedrawSuspended(); NS_IMETHOD NotifyRedrawUnsuspended(); NS_IMETHOD SetMatrixPropagation(PRBool aPropagate); virtual PRBool GetMatrixPropagation(); NS_IMETHOD_(PRBool) IsDisplayContainer() { return PR_FALSE; } NS_IMETHOD_(PRBool) HasValidCoveredRect() { return PR_TRUE; } // nsSVGGeometryFrame methods gfxMatrix GetCanvasTM(); // nsISVGGlyphFragmentLeaf interface: // These do not use the global transform if NS_STATE_NONDISPLAY_CHILD NS_IMETHOD GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval); NS_IMETHOD GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval); NS_IMETHOD GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval); NS_IMETHOD GetRotationOfChar(PRUint32 charnum, float *_retval); /** * @param aForceGlobalTransform controls whether to use the * global transform even when NS_STATE_NONDISPLAY_CHILD */ NS_IMETHOD_(float) GetAdvance(PRBool aForceGlobalTransform); NS_IMETHOD_(void) SetGlyphPosition(float x, float y, PRBool aForceGlobalTransform); NS_IMETHOD_(nsSVGTextPathFrame*) FindTextPathParent(); NS_IMETHOD_(PRBool) IsStartOfChunk(); // == is new absolutely positioned chunk. NS_IMETHOD_(void) GetAdjustedPosition(/* inout */ float &x, /* inout */ float &y); NS_IMETHOD_(already_AddRefed) GetX(); NS_IMETHOD_(already_AddRefed) GetY(); NS_IMETHOD_(already_AddRefed) GetDx(); NS_IMETHOD_(already_AddRefed) GetDy(); NS_IMETHOD_(PRUint16) GetTextAnchor(); NS_IMETHOD_(PRBool) IsAbsolutelyPositioned(); // nsISVGGlyphFragmentNode interface: // These do not use the global transform if NS_STATE_NONDISPLAY_CHILD virtual PRUint32 GetNumberOfChars(); virtual float GetComputedTextLength(); virtual float GetSubStringLength(PRUint32 charnum, PRUint32 fragmentChars); virtual PRInt32 GetCharNumAtPosition(nsIDOMSVGPoint *point); NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetFirstGlyphFragment(); NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetNextGlyphFragment(); NS_IMETHOD_(void) SetWhitespaceHandling(PRUint8 aWhitespaceHandling); protected: friend class CharacterIterator; // Use a power of 2 here. It's not so important to match // nsIDeviceContext::AppUnitsPerDevPixel, but since we do a lot of // multiplying by 1/GetTextRunUnitsFactor, it's good for it to be a // power of 2 to avoid accuracy loss. static PRUint32 GetTextRunUnitsFactor() { return 64; } /** * @aParam aDrawScale font drawing must be scaled into user units * by this factor * @param aMetricsScale font metrics must be scaled into user units * by this factor * @param aForceGlobalTransform set to true if we should force use of * the global transform; otherwise we won't use the global transform * if we're a NONDISPLAY_CHILD */ PRBool EnsureTextRun(float *aDrawScale, float *aMetricsScale, PRBool aForceGlobalTransform); void ClearTextRun(); PRBool GetCharacterData(nsAString & aCharacterData); PRBool GetCharacterPositions(nsTArray* aCharacterPositions, float aMetricsScale); void AddCharactersToPath(CharacterIterator *aIter, gfxContext *aContext); void AddBoundingBoxesToPath(CharacterIterator *aIter, gfxContext *aContext); void FillCharacters(CharacterIterator *aIter, gfxContext *aContext); void NotifyGlyphMetricsChange(); PRBool ContainsPoint(const nsPoint &aPoint); PRBool GetGlobalTransform(gfxMatrix *aMatrix); void SetupGlobalTransform(gfxContext *aContext); nsresult GetHighlight(PRUint32 *charnum, PRUint32 *nchars, nscolor *foreground, nscolor *background); float GetSubStringAdvance(PRUint32 charnum, PRUint32 fragmentChars); gfxFloat GetBaselineOffset(PRBool aForceGlobalTransform); const nsTextFragment* GetFragment() const { return !(GetStateBits() & NS_STATE_SVG_PRINTING) ? mContent->GetText() : nsLayoutUtils::GetTextFragmentForPrinting(this); } // Used to support GetBBoxContribution by making GetConvasTM use this as the // parent transform instead of the real CanvasTM. nsCOMPtr mOverrideCanvasTM; // Owning pointer, must call gfxTextRunWordCache::RemoveTextRun before deleting gfxTextRun *mTextRun; gfxPoint mPosition; PRUint8 mWhitespaceHandling; }; #endif