|
skia
2DGraphicsLibrary
|
00001 00002 00003 /* 00004 * Copyright 2006 The Android Open Source Project 00005 * 00006 * Use of this source code is governed by a BSD-style license that can be 00007 * found in the LICENSE file. 00008 */ 00009 00010 00011 #ifndef SkPaint_DEFINED 00012 #define SkPaint_DEFINED 00013 00014 #include "SkColor.h" 00015 #include "SkDrawLooper.h" 00016 #include "SkXfermode.h" 00017 #ifdef SK_BUILD_FOR_ANDROID 00018 #include "SkPaintOptionsAndroid.h" 00019 #endif 00020 00021 class SkAnnotation; 00022 class SkAutoGlyphCache; 00023 class SkColorFilter; 00024 class SkDescriptor; 00025 struct SkDeviceProperties; 00026 class SkFlattenableReadBuffer; 00027 class SkFlattenableWriteBuffer; 00028 struct SkGlyph; 00029 struct SkRect; 00030 class SkGlyphCache; 00031 class SkImageFilter; 00032 class SkMaskFilter; 00033 class SkMatrix; 00034 class SkPath; 00035 class SkPathEffect; 00036 struct SkPoint; 00037 class SkRasterizer; 00038 class SkShader; 00039 class SkTypeface; 00040 00041 typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**, 00042 SkFixed x, SkFixed y); 00043 00044 typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**); 00045 00051 class SK_API SkPaint { 00052 public: 00053 SkPaint(); 00054 SkPaint(const SkPaint& paint); 00055 ~SkPaint(); 00056 00057 SkPaint& operator=(const SkPaint&); 00058 00059 SK_API friend bool operator==(const SkPaint& a, const SkPaint& b); 00060 friend bool operator!=(const SkPaint& a, const SkPaint& b) { 00061 return !(a == b); 00062 } 00063 00064 void flatten(SkFlattenableWriteBuffer&) const; 00065 void unflatten(SkFlattenableReadBuffer&); 00066 00069 void reset(); 00070 00081 enum Hinting { 00082 kNo_Hinting = 0, 00083 kSlight_Hinting = 1, 00084 kNormal_Hinting = 2, 00085 kFull_Hinting = 3 00086 }; 00087 00088 Hinting getHinting() const { 00089 return static_cast<Hinting>(fHinting); 00090 } 00091 00092 void setHinting(Hinting hintingLevel); 00093 00096 enum Flags { 00097 kAntiAlias_Flag = 0x01, 00098 kFilterBitmap_Flag = 0x02, 00099 kDither_Flag = 0x04, 00100 kUnderlineText_Flag = 0x08, 00101 kStrikeThruText_Flag = 0x10, 00102 kFakeBoldText_Flag = 0x20, 00103 kLinearText_Flag = 0x40, 00104 kSubpixelText_Flag = 0x80, 00105 kDevKernText_Flag = 0x100, 00106 kLCDRenderText_Flag = 0x200, 00107 kEmbeddedBitmapText_Flag = 0x400, 00108 kAutoHinting_Flag = 0x800, 00109 kVerticalText_Flag = 0x1000, 00110 kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it 00111 00112 // when adding extra flags, note that the fFlags member is specified 00113 // with a bit-width and you'll have to expand it. 00114 00115 kAllFlags = 0x3FFF 00116 }; 00117 00121 uint32_t getFlags() const { return fFlags; } 00122 00126 void setFlags(uint32_t flags); 00127 00131 bool isAntiAlias() const { 00132 return SkToBool(this->getFlags() & kAntiAlias_Flag); 00133 } 00134 00138 void setAntiAlias(bool aa); 00139 00143 bool isDither() const { 00144 return SkToBool(this->getFlags() & kDither_Flag); 00145 } 00146 00150 void setDither(bool dither); 00151 00155 bool isLinearText() const { 00156 return SkToBool(this->getFlags() & kLinearText_Flag); 00157 } 00158 00163 void setLinearText(bool linearText); 00164 00168 bool isSubpixelText() const { 00169 return SkToBool(this->getFlags() & kSubpixelText_Flag); 00170 } 00171 00177 void setSubpixelText(bool subpixelText); 00178 00179 bool isLCDRenderText() const { 00180 return SkToBool(this->getFlags() & kLCDRenderText_Flag); 00181 } 00182 00189 void setLCDRenderText(bool lcdText); 00190 00191 bool isEmbeddedBitmapText() const { 00192 return SkToBool(this->getFlags() & kEmbeddedBitmapText_Flag); 00193 } 00194 00199 void setEmbeddedBitmapText(bool useEmbeddedBitmapText); 00200 00201 bool isAutohinted() const { 00202 return SkToBool(this->getFlags() & kAutoHinting_Flag); 00203 } 00204 00210 void setAutohinted(bool useAutohinter); 00211 00212 bool isVerticalText() const { 00213 return SkToBool(this->getFlags() & kVerticalText_Flag); 00214 } 00215 00224 void setVerticalText(bool); 00225 00229 bool isUnderlineText() const { 00230 return SkToBool(this->getFlags() & kUnderlineText_Flag); 00231 } 00232 00237 void setUnderlineText(bool underlineText); 00238 00242 bool isStrikeThruText() const { 00243 return SkToBool(this->getFlags() & kStrikeThruText_Flag); 00244 } 00245 00250 void setStrikeThruText(bool strikeThruText); 00251 00255 bool isFakeBoldText() const { 00256 return SkToBool(this->getFlags() & kFakeBoldText_Flag); 00257 } 00258 00263 void setFakeBoldText(bool fakeBoldText); 00264 00268 bool isDevKernText() const { 00269 return SkToBool(this->getFlags() & kDevKernText_Flag); 00270 } 00271 00276 void setDevKernText(bool devKernText); 00277 00278 bool isFilterBitmap() const { 00279 return SkToBool(this->getFlags() & kFilterBitmap_Flag); 00280 } 00281 00282 void setFilterBitmap(bool filterBitmap); 00283 00293 enum Style { 00294 kFill_Style, 00295 kStroke_Style, 00296 kStrokeAndFill_Style, 00297 }; 00298 enum { 00299 kStyleCount = kStrokeAndFill_Style + 1 00300 }; 00301 00307 Style getStyle() const { return (Style)fStyle; } 00308 00314 void setStyle(Style style); 00315 00322 SkColor getColor() const { return fColor; } 00323 00329 void setColor(SkColor color); 00330 00334 uint8_t getAlpha() const { return SkToU8(SkColorGetA(fColor)); } 00335 00340 void setAlpha(U8CPU a); 00341 00349 void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b); 00350 00358 SkScalar getStrokeWidth() const { return fWidth; } 00359 00366 void setStrokeWidth(SkScalar width); 00367 00373 SkScalar getStrokeMiter() const { return fMiterLimit; } 00374 00381 void setStrokeMiter(SkScalar miter); 00382 00387 enum Cap { 00388 kButt_Cap, 00389 kRound_Cap, 00390 kSquare_Cap, 00391 00392 kCapCount, 00393 kDefault_Cap = kButt_Cap 00394 }; 00395 00399 enum Join { 00400 kMiter_Join, 00401 kRound_Join, 00402 kBevel_Join, 00403 00404 kJoinCount, 00405 kDefault_Join = kMiter_Join 00406 }; 00407 00413 Cap getStrokeCap() const { return (Cap)fCapType; } 00414 00419 void setStrokeCap(Cap cap); 00420 00425 Join getStrokeJoin() const { return (Join)fJoinType; } 00426 00431 void setStrokeJoin(Join join); 00432 00445 bool getFillPath(const SkPath& src, SkPath* dst, 00446 const SkRect* cullRect = NULL) const; 00447 00453 SkShader* getShader() const { return fShader; } 00454 00471 SkShader* setShader(SkShader* shader); 00472 00477 SkColorFilter* getColorFilter() const { return fColorFilter; } 00478 00486 SkColorFilter* setColorFilter(SkColorFilter* filter); 00487 00493 SkXfermode* getXfermode() const { return fXfermode; } 00494 00505 SkXfermode* setXfermode(SkXfermode* xfermode); 00506 00511 SkXfermode* setXfermodeMode(SkXfermode::Mode); 00512 00518 SkPathEffect* getPathEffect() const { return fPathEffect; } 00519 00530 SkPathEffect* setPathEffect(SkPathEffect* effect); 00531 00537 SkMaskFilter* getMaskFilter() const { return fMaskFilter; } 00538 00549 SkMaskFilter* setMaskFilter(SkMaskFilter* maskfilter); 00550 00551 // These attributes are for text/fonts 00552 00559 SkTypeface* getTypeface() const { return fTypeface; } 00560 00571 SkTypeface* setTypeface(SkTypeface* typeface); 00572 00578 SkRasterizer* getRasterizer() const { return fRasterizer; } 00579 00591 SkRasterizer* setRasterizer(SkRasterizer* rasterizer); 00592 00593 SkImageFilter* getImageFilter() const { return fImageFilter; } 00594 SkImageFilter* setImageFilter(SkImageFilter*); 00595 00596 SkAnnotation* getAnnotation() const { return fAnnotation; } 00597 SkAnnotation* setAnnotation(SkAnnotation*); 00598 00603 bool isNoDrawAnnotation() const { 00604 return SkToBool(fPrivFlags & kNoDrawAnnotation_PrivFlag); 00605 } 00606 00611 SkDrawLooper* getLooper() const { return fLooper; } 00612 00624 SkDrawLooper* setLooper(SkDrawLooper* looper); 00625 00626 enum Align { 00627 kLeft_Align, 00628 kCenter_Align, 00629 kRight_Align, 00630 00631 kAlignCount 00632 }; 00633 00637 Align getTextAlign() const { return (Align)fTextAlign; } 00638 00642 void setTextAlign(Align align); 00643 00647 SkScalar getTextSize() const { return fTextSize; } 00648 00652 void setTextSize(SkScalar textSize); 00653 00658 SkScalar getTextScaleX() const { return fTextScaleX; } 00659 00666 void setTextScaleX(SkScalar scaleX); 00667 00672 SkScalar getTextSkewX() const { return fTextSkewX; } 00673 00678 void setTextSkewX(SkScalar skewX); 00679 00680 #ifdef SK_SUPPORT_HINTING_SCALE_FACTOR 00681 00685 SkScalar getHintingScaleFactor() const { return fHintingScaleFactor; } 00686 00691 void setHintingScaleFactor(SkScalar hintingScaleFactor); 00692 #endif 00693 00697 enum TextEncoding { 00698 kUTF8_TextEncoding, 00699 kUTF16_TextEncoding, 00700 kUTF32_TextEncoding, 00701 kGlyphID_TextEncoding 00702 }; 00703 00704 TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; } 00705 00706 void setTextEncoding(TextEncoding encoding); 00707 00708 struct FontMetrics { 00709 SkScalar fTop; 00710 SkScalar fAscent; 00711 SkScalar fDescent; 00712 SkScalar fBottom; 00713 SkScalar fLeading; 00714 SkScalar fAvgCharWidth; 00715 SkScalar fXMin; 00716 SkScalar fXMax; 00717 SkScalar fXHeight; 00718 }; 00719 00731 SkScalar getFontMetrics(FontMetrics* metrics, SkScalar scale = 0) const; 00732 00736 SkScalar getFontSpacing() const { return this->getFontMetrics(NULL, 0); } 00737 00742 int textToGlyphs(const void* text, size_t byteLength, 00743 uint16_t glyphs[]) const; 00744 00752 bool containsText(const void* text, size_t byteLength) const; 00753 00758 void glyphsToUnichars(const uint16_t glyphs[], int count, 00759 SkUnichar text[]) const; 00760 00766 int countText(const void* text, size_t byteLength) const { 00767 return this->textToGlyphs(text, byteLength, NULL); 00768 } 00769 00782 SkScalar measureText(const void* text, size_t length, 00783 SkRect* bounds, SkScalar scale = 0) const; 00784 00793 SkScalar measureText(const void* text, size_t length) const { 00794 return this->measureText(text, length, NULL, 0); 00795 } 00796 00799 enum TextBufferDirection { 00803 kForward_TextBufferDirection, 00807 kBackward_TextBufferDirection 00808 }; 00809 00825 size_t breakText(const void* text, size_t length, SkScalar maxWidth, 00826 SkScalar* measuredWidth = NULL, 00827 TextBufferDirection tbd = kForward_TextBufferDirection) 00828 const; 00829 00842 int getTextWidths(const void* text, size_t byteLength, SkScalar widths[], 00843 SkRect bounds[] = NULL) const; 00844 00849 void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y, 00850 SkPath* path) const; 00851 00852 void getPosTextPath(const void* text, size_t length, 00853 const SkPoint pos[], SkPath* path) const; 00854 00855 #ifdef SK_BUILD_FOR_ANDROID 00856 const SkGlyph& getUnicharMetrics(SkUnichar, const SkMatrix*); 00857 const SkGlyph& getGlyphMetrics(uint16_t, const SkMatrix*); 00858 const void* findImage(const SkGlyph&, const SkMatrix*); 00859 00860 uint32_t getGenerationID() const; 00861 void setGenerationID(uint32_t generationID); 00862 00865 unsigned getBaseGlyphCount(SkUnichar text) const; 00866 00867 const SkPaintOptionsAndroid& getPaintOptionsAndroid() const { 00868 return fPaintOptionsAndroid; 00869 } 00870 void setPaintOptionsAndroid(const SkPaintOptionsAndroid& options); 00871 #endif 00872 00873 // returns true if the paint's settings (e.g. xfermode + alpha) resolve to 00874 // mean that we need not draw at all (e.g. SrcOver + 0-alpha) 00875 bool nothingToDraw() const; 00876 00878 // would prefer to make these private... 00879 00884 bool canComputeFastBounds() const { 00885 if (this->getLooper()) { 00886 return this->getLooper()->canComputeFastBounds(*this); 00887 } 00888 return !this->getRasterizer(); 00889 } 00890 00912 const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const { 00913 SkPaint::Style style = this->getStyle(); 00914 // ultra fast-case: filling with no effects that affect geometry 00915 if (kFill_Style == style) { 00916 uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper()); 00917 effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter()); 00918 effects |= reinterpret_cast<uintptr_t>(this->getPathEffect()); 00919 if (!effects) { 00920 return orig; 00921 } 00922 } 00923 00924 return this->doComputeFastBounds(orig, storage, style); 00925 } 00926 00927 const SkRect& computeFastStrokeBounds(const SkRect& orig, 00928 SkRect* storage) const { 00929 return this->doComputeFastBounds(orig, storage, kStroke_Style); 00930 } 00931 00932 // Take the style explicitly, so the caller can force us to be stroked 00933 // without having to make a copy of the paint just to change that field. 00934 const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage, 00935 Style) const; 00936 00937 SkDEVCODE(void toString(SkString*) const;) 00938 00939 private: 00940 SkTypeface* fTypeface; 00941 SkScalar fTextSize; 00942 SkScalar fTextScaleX; 00943 SkScalar fTextSkewX; 00944 #ifdef SK_SUPPORT_HINTING_SCALE_FACTOR 00945 SkScalar fHintingScaleFactor; 00946 #endif 00947 00948 SkPathEffect* fPathEffect; 00949 SkShader* fShader; 00950 SkXfermode* fXfermode; 00951 SkMaskFilter* fMaskFilter; 00952 SkColorFilter* fColorFilter; 00953 SkRasterizer* fRasterizer; 00954 SkDrawLooper* fLooper; 00955 SkImageFilter* fImageFilter; 00956 SkAnnotation* fAnnotation; 00957 00958 SkColor fColor; 00959 SkScalar fWidth; 00960 SkScalar fMiterLimit; 00961 // all of these bitfields should add up to 32 00962 unsigned fFlags : 16; 00963 unsigned fTextAlign : 2; 00964 unsigned fCapType : 2; 00965 unsigned fJoinType : 2; 00966 unsigned fStyle : 2; 00967 unsigned fTextEncoding : 2; // 3 values 00968 unsigned fHinting : 2; 00969 unsigned fPrivFlags : 4; // these are not flattened/unflattened 00970 00971 enum PrivFlags { 00972 kNoDrawAnnotation_PrivFlag = 1 << 0, 00973 }; 00974 00975 SkDrawCacheProc getDrawCacheProc() const; 00976 SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir, 00977 bool needFullMetrics) const; 00978 00979 SkScalar measure_text(SkGlyphCache*, const char* text, size_t length, 00980 int* count, SkRect* bounds) const; 00981 00982 SkGlyphCache* detachCache(const SkDeviceProperties* deviceProperties, const SkMatrix*) const; 00983 00984 void descriptorProc(const SkDeviceProperties* deviceProperties, const SkMatrix* deviceMatrix, 00985 void (*proc)(SkTypeface*, const SkDescriptor*, void*), 00986 void* context, bool ignoreGamma = false) const; 00987 00988 static void Term(); 00989 00990 enum { 00991 kCanonicalTextSizeForPaths = 64 00992 }; 00993 friend class SkAutoGlyphCache; 00994 friend class SkCanvas; 00995 friend class SkDraw; 00996 friend class SkGraphics; // So Term() can be called. 00997 friend class SkPDFDevice; 00998 friend class SkTextToPathIter; 00999 01000 #ifdef SK_BUILD_FOR_ANDROID 01001 SkPaintOptionsAndroid fPaintOptionsAndroid; 01002 01003 // In order for the == operator to work properly this must be the last field 01004 // in the struct so that we can do a memcmp to this field's offset. 01005 uint32_t fGenerationID; 01006 #endif 01007 }; 01008 01009 #endif