MinikinSkia.cpp revision 0627ec08dcc2e87c17e9b85f045dfb27dc4884b3
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <SkTypeface.h> 18#include <SkPaint.h> 19 20#define LOG_TAG "Minikin" 21#include <cutils/log.h> 22 23#include <minikin/MinikinFont.h> 24#include "MinikinSkia.h" 25 26namespace android { 27 28MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) : 29 mTypeface(typeface) { 30} 31 32MinikinFontSkia::~MinikinFontSkia() { 33 SkSafeUnref(mTypeface); 34} 35 36bool MinikinFontSkia::GetGlyph(uint32_t codepoint, uint32_t *glyph) const { 37 SkPaint paint; 38 paint.setTypeface(mTypeface); 39 paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); 40 uint16_t glyph16; 41 paint.textToGlyphs(&codepoint, sizeof(codepoint), &glyph16); 42 *glyph = glyph16; 43 return !!glyph; 44} 45 46static void MinikinFontSkia_SetSkiaPaint(const MinikinFont* font, SkPaint* skPaint, const MinikinPaint& paint) { 47 skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); 48 skPaint->setTextSize(paint.size); 49 skPaint->setTextScaleX(paint.scaleX); 50 skPaint->setTextSkewX(paint.skewX); 51 MinikinFontSkia::unpackPaintFlags(skPaint, paint.paintFlags); 52 // Apply font fakery on top of user-supplied flags. 53 MinikinFontSkia::populateSkPaint(skPaint, font, paint.fakery); 54} 55 56float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id, 57 const MinikinPaint &paint) const { 58 SkPaint skPaint; 59 uint16_t glyph16 = glyph_id; 60 SkScalar skWidth; 61 MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint); 62 skPaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, NULL); 63#ifdef VERBOSE 64 ALOGD("width for typeface %d glyph %d = %f", mTypeface->uniqueID(), glyph_id, skWidth); 65#endif 66 return skWidth; 67} 68 69void MinikinFontSkia::GetBounds(MinikinRect* bounds, uint32_t glyph_id, 70 const MinikinPaint& paint) const { 71 SkPaint skPaint; 72 uint16_t glyph16 = glyph_id; 73 SkRect skBounds; 74 MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint); 75 skPaint.getTextWidths(&glyph16, sizeof(glyph16), NULL, &skBounds); 76 bounds->mLeft = skBounds.fLeft; 77 bounds->mTop = skBounds.fTop; 78 bounds->mRight = skBounds.fRight; 79 bounds->mBottom = skBounds.fBottom; 80} 81 82bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) { 83 if (buf == NULL) { 84 const size_t tableSize = mTypeface->getTableSize(tag); 85 *size = tableSize; 86 return tableSize != 0; 87 } else { 88 const size_t actualSize = mTypeface->getTableData(tag, 0, *size, buf); 89 *size = actualSize; 90 return actualSize != 0; 91 } 92} 93 94SkTypeface *MinikinFontSkia::GetSkTypeface() const { 95 return mTypeface; 96} 97 98int32_t MinikinFontSkia::GetUniqueId() const { 99 return mTypeface->uniqueID(); 100} 101 102uint32_t MinikinFontSkia::packPaintFlags(const SkPaint* paint) { 103 uint32_t flags = paint->getFlags(); 104 SkPaint::Hinting hinting = paint->getHinting(); 105 // select only flags that might affect text layout 106 flags &= (SkPaint::kAntiAlias_Flag | SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag | 107 SkPaint::kSubpixelText_Flag | SkPaint::kDevKernText_Flag | 108 SkPaint::kEmbeddedBitmapText_Flag | SkPaint::kAutoHinting_Flag | 109 SkPaint::kVerticalText_Flag); 110 flags |= (hinting << 16); 111 return flags; 112} 113 114void MinikinFontSkia::unpackPaintFlags(SkPaint* paint, uint32_t paintFlags) { 115 paint->setFlags(paintFlags & SkPaint::kAllFlags); 116 paint->setHinting(static_cast<SkPaint::Hinting>(paintFlags >> 16)); 117} 118 119void MinikinFontSkia::populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery) { 120 paint->setTypeface(reinterpret_cast<const MinikinFontSkia*>(font)->GetSkTypeface()); 121 paint->setFakeBoldText(paint->isFakeBoldText() || fakery.isFakeBold()); 122 if (fakery.isFakeItalic()) { 123 paint->setTextSkewX(paint->getTextSkewX() - 0.25f); 124 } 125} 126 127} 128