MinikinUtils.cpp revision 7c93e868825225a270c993ac058687adde682626
11a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien/* 21a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Copyright (C) 2014 The Android Open Source Project 31a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * 41a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Licensed under the Apache License, Version 2.0 (the "License"); 51a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * you may not use this file except in compliance with the License. 61a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * You may obtain a copy of the License at 71a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * 81a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * http://www.apache.org/licenses/LICENSE-2.0 91a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * 101a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * Unless required by applicable law or agreed to in writing, software 111a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * distributed under the License is distributed on an "AS IS" BASIS, 121a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * See the License for the specific language governing permissions and 141a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien * limitations under the License. 151a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien */ 1652eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn 17dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include "MinikinUtils.h" 181a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 1952eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <string> 2052eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn 2152eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <log/log.h> 2252eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn 23afbd0f1fef46ef0ddf633dfde0de724db3da1405Sergei Vasilinetc#include "Paint.h" 24dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include "SkPathMeasure.h" 25bad99183916ba2bac6659efc8a28273e344ba511sergeyv#include "Typeface.h" 261a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 271a73f732f91e97c9c66b808c245ddda36a10e987Raph Leviennamespace android { 281a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 29ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonakaminikin::FontStyle MinikinUtils::prepareMinikinPaint(minikin::MinikinPaint* minikinPaint, 30318ca04079bd6242cb6186d9005b9caeee22e845Seigo Nonaka const Paint* paint, const Typeface* typeface) { 31bad99183916ba2bac6659efc8a28273e344ba511sergeyv const Typeface* resolvedFace = Typeface::resolveDefault(typeface); 32ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka minikin::FontStyle resolved = resolvedFace->fStyle; 335ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod 345ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod /* Prepare minikin FontStyle */ 35ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka minikin::FontVariant minikinVariant = (paint->getFontVariant() == minikin::VARIANT_ELEGANT) ? 36ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka minikin::VARIANT_ELEGANT : minikin::VARIANT_COMPACT; 37cfc607cf57d453f977c9c4bf09b41ac481c4bbecSeigo Nonaka const uint32_t langListId = paint->getMinikinLangListId(); 38ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka minikin::FontStyle minikinStyle(langListId, minikinVariant, resolved.getWeight(), 39ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka resolved.getItalic()); 405ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod 415ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod /* Prepare minikin Paint */ 42a130a6cf4cf9f8294dcd95b94ed6e45bbddbfe40Seigo Nonaka minikinPaint->size = paint->isLinearText() ? 43a130a6cf4cf9f8294dcd95b94ed6e45bbddbfe40Seigo Nonaka paint->getTextSize() : static_cast<int>(paint->getTextSize()); 44c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien minikinPaint->scaleX = paint->getTextScaleX(); 45c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien minikinPaint->skewX = paint->getTextSkewX(); 46c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien minikinPaint->letterSpacing = paint->getLetterSpacing(); 47219e2c79490296b03e58ec36a3a4ff4a2ebf52e3Seigo Nonaka minikinPaint->wordSpacing = paint->getWordSpacing(); 48c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien minikinPaint->paintFlags = MinikinFontSkia::packPaintFlags(paint); 49c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien minikinPaint->fontFeatureSettings = paint->getFontFeatureSettings(); 50ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka minikinPaint->hyphenEdit = minikin::HyphenEdit(paint->getHyphenEdit()); 51c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien return minikinStyle; 52c94f742f7e07a3b86c8f603836c19638472b3e83Raph Levien} 535ec789608bda858a0c6d669bb44a35a5a99abcdbBehdad Esfahbod 547c93e868825225a270c993ac058687adde682626Seigo Nonakaminikin::Layout MinikinUtils::doLayout(const Paint* paint, minikin::Bidi bidiFlags, 557c93e868825225a270c993ac058687adde682626Seigo Nonaka const Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize) { 56ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka minikin::MinikinPaint minikinPaint; 57c7064146f959caec058980ced144942c8044a169Seigo Nonaka minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, paint, typeface); 5851218e80f70601193e43d90aaf1599a7f6d11062Seigo Nonaka minikin::Layout layout; 5951218e80f70601193e43d90aaf1599a7f6d11062Seigo Nonaka layout.doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint, 6051218e80f70601193e43d90aaf1599a7f6d11062Seigo Nonaka Typeface::resolveDefault(typeface)->fFontCollection); 61c7064146f959caec058980ced144942c8044a169Seigo Nonaka return layout; 621a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien} 631a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 647c93e868825225a270c993ac058687adde682626Seigo Nonakafloat MinikinUtils::measureText(const Paint* paint, minikin::Bidi bidiFlags, 657c93e868825225a270c993ac058687adde682626Seigo Nonaka const Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize, 667c93e868825225a270c993ac058687adde682626Seigo Nonaka float *advances) { 67ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka minikin::MinikinPaint minikinPaint; 68c7064146f959caec058980ced144942c8044a169Seigo Nonaka minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, paint, typeface); 69318ca04079bd6242cb6186d9005b9caeee22e845Seigo Nonaka const Typeface* resolvedTypeface = Typeface::resolveDefault(typeface); 70ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka return minikin::Layout::measureText(buf, start, count, bufSize, bidiFlags, minikinStyle, 710aa07a712984a655215f20e664915b67833be709Roozbeh Pournader minikinPaint, resolvedTypeface->fFontCollection, advances, nullptr /* extent */, 720aa07a712984a655215f20e664915b67833be709Roozbeh Pournader nullptr /* overhangs */); 73a3024bd7026deb777556dd75dd34a719ea1c2b39Keisuke Kuroyanagi} 74a3024bd7026deb777556dd75dd34a719ea1c2b39Keisuke Kuroyanagi 75318ca04079bd6242cb6186d9005b9caeee22e845Seigo Nonakabool MinikinUtils::hasVariationSelector(const Typeface* typeface, uint32_t codepoint, uint32_t vs) { 76bad99183916ba2bac6659efc8a28273e344ba511sergeyv const Typeface* resolvedFace = Typeface::resolveDefault(typeface); 77bb1a96647a82df5a134bf631fc9db342e7ef61deSeigo Nonaka return resolvedFace->fFontCollection->hasVariationSelector(codepoint, vs); 78bb1a96647a82df5a134bf631fc9db342e7ef61deSeigo Nonaka} 79bb1a96647a82df5a134bf631fc9db342e7ef61deSeigo Nonaka 80ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonakafloat MinikinUtils::xOffsetForTextAlign(Paint* paint, const minikin::Layout& layout) { 81f2114d5646194100242206b267ddd6e7194b7da9Raph Levien switch (paint->getTextAlign()) { 826ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod case Paint::kCenter_Align: 83f2114d5646194100242206b267ddd6e7194b7da9Raph Levien return layout.getAdvance() * -0.5f; 84f2114d5646194100242206b267ddd6e7194b7da9Raph Levien break; 856ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod case Paint::kRight_Align: 86f2114d5646194100242206b267ddd6e7194b7da9Raph Levien return -layout.getAdvance(); 87f2114d5646194100242206b267ddd6e7194b7da9Raph Levien break; 88f2114d5646194100242206b267ddd6e7194b7da9Raph Levien default: 89f2114d5646194100242206b267ddd6e7194b7da9Raph Levien break; 90f2114d5646194100242206b267ddd6e7194b7da9Raph Levien } 91f2114d5646194100242206b267ddd6e7194b7da9Raph Levien return 0; 92f2114d5646194100242206b267ddd6e7194b7da9Raph Levien} 93f2114d5646194100242206b267ddd6e7194b7da9Raph Levien 94ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonakafloat MinikinUtils::hOffsetForTextAlign(Paint* paint, const minikin::Layout& layout, 95ae1aa85d0c7305bb621f1f8003bd674285aa3b63Seigo Nonaka const SkPath& path) { 969d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien float align = 0; 979d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien switch (paint->getTextAlign()) { 986ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod case Paint::kCenter_Align: 999d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien align = -0.5f; 1009d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien break; 1016ba30b85ddfbe37c338ee8dde3dd33322eb38d47Behdad Esfahbod case Paint::kRight_Align: 1029d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien align = -1; 1039d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien break; 1049d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien default: 1059d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien return 0; 1069d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien } 1079d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien SkPathMeasure measure(path, false); 1089d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien return align * (layout.getAdvance() - measure.getLength()); 1099d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien} 1109d2b5e1930bfc4b1da1c865843c247c708ea1565Raph Levien 111f2114d5646194100242206b267ddd6e7194b7da9Raph Levien} 112