2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/devel-api/text-abstraction/font-client.h>
22 #include <dali/internal/imaging/common/image-operations.h>
23 #include <dali/internal/text/text-abstraction/font-client-impl.h>
27 namespace TextAbstraction
29 const PointSize26Dot6 FontClient::DEFAULT_POINT_SIZE = 768u; // 12*64
30 const float FontClient::DEFAULT_ITALIC_ANGLE = 12.f * Dali::Math::PI_OVER_180; // FreeType documentation states the software italic is done by doing a horizontal shear of 12 degrees (file ftsynth.h).
33 const bool FontClient::DEFAULT_ATLAS_LIMITATION_ENABLED = true;
34 const uint32_t FontClient::DEFAULT_TEXT_ATLAS_WIDTH = 512u;
35 const uint32_t FontClient::DEFAULT_TEXT_ATLAS_HEIGHT = 512u;
36 const Size FontClient::DEFAULT_TEXT_ATLAS_SIZE(DEFAULT_TEXT_ATLAS_WIDTH, DEFAULT_TEXT_ATLAS_HEIGHT);
39 const uint32_t FontClient::MAX_TEXT_ATLAS_WIDTH = 1024u;
40 const uint32_t FontClient::MAX_TEXT_ATLAS_HEIGHT = 1024u;
41 const Size FontClient::MAX_TEXT_ATLAS_SIZE(MAX_TEXT_ATLAS_WIDTH, MAX_TEXT_ATLAS_HEIGHT);
43 //MAX_WIDTH_FIT_IN_ATLAS: blockWidth + 2 * DOUBLE_PIXEL_PADDING + 1u <= atlasWidth
44 //MAX_HEIGHT_FIT_IN_ATLAS: blockHeight + 2 * DOUBLE_PIXEL_PADDING + 1u <= atlasHeight
45 const uint16_t FontClient::PADDING_TEXT_ATLAS_BLOCK = 5u; // 2 * DOUBLE_PIXEL_PADDING + 1u
47 //Maximum block size to fit into atlas block
48 const Size FontClient::MAX_SIZE_FIT_IN_ATLAS(MAX_TEXT_ATLAS_WIDTH - PADDING_TEXT_ATLAS_BLOCK, MAX_TEXT_ATLAS_HEIGHT - PADDING_TEXT_ATLAS_BLOCK);
50 const uint32_t FontClient::NUMBER_OF_POINTS_PER_ONE_UNIT_OF_POINT_SIZE = 64u; //Found this value from toolkit
52 // FontClient::GlyphBufferData
54 FontClient::GlyphBufferData::GlyphBufferData()
61 compressType(CompressType::NO_COMPRESS),
68 FontClient::GlyphBufferData::~GlyphBufferData()
76 size_t FontClient::GlyphBufferData::Compress(const uint8_t* const __restrict__ inBuffer, GlyphBufferData& __restrict__ outBufferData)
78 size_t bufferSize = 0u;
79 uint8_t*& __restrict__ compressedBuffer = outBufferData.buffer;
80 switch(outBufferData.compressType)
82 case TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS:
84 bufferSize = outBufferData.width * outBufferData.height * Pixel::GetBytesPerPixel(outBufferData.format);
86 compressedBuffer = (uint8_t*)malloc(bufferSize);
87 if(DALI_UNLIKELY(compressedBuffer == nullptr))
91 outBufferData.isBufferOwned = true;
93 // Copy buffer without compress
94 memcpy(compressedBuffer, inBuffer, bufferSize);
97 case TextAbstraction::FontClient::GlyphBufferData::CompressType::BIT_PER_PIXEL_4:
99 const uint32_t widthByte = outBufferData.width * Pixel::GetBytesPerPixel(outBufferData.format);
100 const uint32_t componentCount = (widthByte >> 1);
101 const bool considerPadding = (widthByte & 1) ? true : false;
103 // For BIT_PER_PIXEL_4 type, we can know final compressed buffer size immediatly.
104 bufferSize = outBufferData.height * (componentCount + (considerPadding ? 1 : 0));
105 compressedBuffer = (uint8_t*)malloc(bufferSize);
106 if(DALI_UNLIKELY(compressedBuffer == nullptr))
110 outBufferData.isBufferOwned = true;
112 uint8_t* __restrict__ outBufferPtr = compressedBuffer;
113 const uint8_t* __restrict__ inBufferPtr = inBuffer;
115 // Compress for each line
116 for(uint32_t y = 0; y < outBufferData.height; ++y)
118 for(uint32_t x = 0; x < componentCount; ++x)
120 const uint8_t v0 = Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++));
121 const uint8_t v1 = Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++));
123 *(outBufferPtr++) = (v0 << 4) | v1;
127 *(outBufferPtr++) = Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++));
132 case TextAbstraction::FontClient::GlyphBufferData::CompressType::COMPRESS_RLE4:
134 const uint32_t widthByte = outBufferData.width * Pixel::GetBytesPerPixel(outBufferData.format);
136 // Allocate temperal buffer. Note that RLE4 can be bigger than original buffer.
137 uint8_t* __restrict__ tempBuffer = (uint8_t*)malloc(outBufferData.height * (widthByte + 1));
138 if(DALI_UNLIKELY(tempBuffer == nullptr))
143 uint8_t* __restrict__ outBufferPtr = tempBuffer;
144 const uint8_t* __restrict__ inBufferPtr = inBuffer;
148 // Compress for each line
149 for(uint32_t y = 0; y < outBufferData.height; ++y)
151 uint32_t encodedByte = 0;
152 while(encodedByte < widthByte)
154 // Case 1 : Remain only 1 byte
155 if(DALI_UNLIKELY(encodedByte + 1 == widthByte))
157 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
158 const uint8_t v0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev0) & 0x0f; // Intented underflow
159 *(outBufferPtr++) = v0;
163 // Case 2 : Remain only 2 byte
164 else if(DALI_UNLIKELY(encodedByte + 2 == widthByte))
166 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
167 const uint8_t v0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev0) & 0x0f; // Intented underflow
168 const uint8_t prev1 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
169 const uint8_t v1 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev1) & 0x0f; // Intented underflow
173 *(outBufferPtr++) = 0x80 | v0;
178 *(outBufferPtr++) = 0x10 | v0;
179 *(outBufferPtr++) = v1 << 4;
183 // Case 3 : Normal case. Remain byte bigger or equal than 3.
187 // Read 2 byte as v0 and v1.
188 // - If v0 == v1, We can compress. mark the first bit as 1. and remain 3 bit mark as the "runLength - 2".
189 // runLength can be maximum 9.
190 // - If v0 != v1, We cannot compress. mark the first bit as 0. and remain 3 bit mark as the "(nonRunLength - 1) / 2"
191 // Due to the BitPerPixel is 4, nonRunLength should be odd value.
192 // nonRunLength cutted if v0 == v1.
193 // nonRunLength can be maximum 15.
195 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
196 const uint8_t v0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev0) & 0x0f; // Intented underflow
197 const uint8_t prev1 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
198 const uint8_t v1 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev1) & 0x0f; // Intented underflow
200 // We can compress by RLE
203 uint8_t runLength = 2;
204 while(encodedByte < widthByte && runLength < 9)
206 const uint8_t prev2 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
207 const uint8_t v2 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr)) - prev2) & 0x0f; // Intented underflow
220 // Update (runLength - 2) result.
221 *(outBufferPtr++) = ((0x8 | (runLength - 2)) << 4) | v0;
224 // We cannot compress by RLE.
227 // Read one more value.
228 const uint8_t prev2 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
229 const uint8_t v2 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr++)) - prev2) & 0x0f; // Intented underflow
232 uint8_t nonRunLength = 3;
233 uint8_t* nonRunLengthHeaderPtr = outBufferPtr;
234 *(outBufferPtr++) = v0;
235 *(outBufferPtr++) = (v1 << 4) | v2;
237 while(encodedByte < widthByte && nonRunLength < 15)
239 if(DALI_LIKELY(encodedByte + 1 < widthByte))
241 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
242 const uint8_t w0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr)) - prew0) & 0x0f; // Intented underflow
243 const uint8_t prew1 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr + 1 - widthByte));
244 const uint8_t w1 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr + 1)) - prew1) & 0x0f; // Intented underflow
247 // Stop non-compress logic.
253 *(outBufferPtr++) = (w0 << 4) | w1;
261 // Edge case. There is only one pixel remained.
262 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr - widthByte));
263 const uint8_t w0 = (Dali::Internal::Platform::CompressBitPerPixel8To4(*(inBufferPtr)) - prew0) & 0x0f; // Intented underflow
266 *(outBufferPtr++) = (w0 << 4);
269 // Increase nonRunLength 2 even latest value is invalid.
275 // Update (nonRunLength-1)/2 result into header.
276 *(nonRunLengthHeaderPtr) |= (nonRunLength >> 1) << 4;
282 // Allocate and copy data
283 compressedBuffer = (uint8_t*)malloc(bufferSize);
284 if(DALI_UNLIKELY(compressedBuffer == nullptr))
289 outBufferData.isBufferOwned = true;
291 memcpy(compressedBuffer, tempBuffer, bufferSize);
305 void FontClient::GlyphBufferData::Decompress(const GlyphBufferData& __restrict__ inBufferData, uint8_t* __restrict__ outBuffer)
307 if(DALI_UNLIKELY(outBuffer == nullptr))
312 switch(inBufferData.compressType)
314 case TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS:
316 const auto bufferSize = inBufferData.width * inBufferData.height * Pixel::GetBytesPerPixel(inBufferData.format);
318 // Copy buffer without compress
319 memcpy(outBuffer, inBufferData.buffer, bufferSize);
322 case TextAbstraction::FontClient::GlyphBufferData::CompressType::BIT_PER_PIXEL_4:
324 const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
325 const uint32_t componentCount = (widthByte >> 1);
326 const bool considerPadding = (widthByte & 1) ? true : false;
328 uint8_t* __restrict__ outBufferPtr = outBuffer;
329 const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer;
331 // Compress for each line
332 for(uint32_t y = 0; y < inBufferData.height; ++y)
334 for(uint32_t x = 0; x < componentCount; ++x)
336 const uint8_t v = *(inBufferPtr++);
337 const uint8_t v0 = (v >> 4) & 0x0f;
338 const uint8_t v1 = v & 0x0f;
340 *(outBufferPtr++) = (v0 << 4) | v0;
341 *(outBufferPtr++) = (v1 << 4) | v1;
345 const uint8_t v = *(inBufferPtr++);
346 *(outBufferPtr++) = (v << 4) | v;
351 case TextAbstraction::FontClient::GlyphBufferData::CompressType::COMPRESS_RLE4:
353 const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
355 uint8_t* __restrict__ outBufferPtr = outBuffer;
356 const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer;
357 // Compress for each line
358 for(uint32_t y = 0; y < inBufferData.height; ++y)
361 uint32_t decodedByte = 0;
362 while(decodedByte < widthByte)
364 const uint8_t v = *(inBufferPtr++);
369 const uint8_t runLength = ((v >> 4) & 0x07) + 2u;
370 decodedByte += runLength;
371 const uint8_t repeatValue = v & 0x0f;
372 for(uint8_t iter = 0; iter < runLength; ++iter)
374 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
375 const uint8_t v0 = (prev0 + repeatValue) & 0x0f;
376 *(outBufferPtr++) = (v0 << 4) | v0;
379 // Not compress by RLE
382 const uint8_t nonRunLength = (((v >> 4) & 0x07) << 1u) + 1u;
383 decodedByte += nonRunLength;
385 const uint8_t prev0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
386 const uint8_t v0 = (prev0 + (v & 0x0f)) & 0x0f;
387 *(outBufferPtr++) = (v0 << 4) | v0;
389 const bool ignoreLastValue = decodedByte > widthByte ? true : false;
390 if(DALI_UNLIKELY(ignoreLastValue))
393 for(uint8_t iter = 1; iter + 2 < nonRunLength; iter += 2)
395 const uint8_t w = *(inBufferPtr++);
396 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
397 const uint8_t w0 = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
398 const uint8_t prew1 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte + 1)) & 0x0f;
399 const uint8_t w1 = (prew1 + (w & 0x0f)) & 0x0f;
402 *(outBufferPtr++) = (w0 << 4) | w0;
403 *(outBufferPtr++) = (w1 << 4) | w1;
407 const uint8_t w = ((*(inBufferPtr++)) >> 4) & 0x0f;
408 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
409 const uint8_t w0 = (prew0 + w) & 0x0f;
412 *(outBufferPtr++) = (w0 << 4) | w0;
417 for(uint8_t iter = 1; iter < nonRunLength; iter += 2)
419 const uint8_t w = *(inBufferPtr++);
420 const uint8_t prew0 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte)) & 0x0f;
421 const uint8_t w0 = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
422 const uint8_t prew1 = DALI_UNLIKELY(y == 0) ? 0 : (*(outBufferPtr - widthByte + 1)) & 0x0f;
423 const uint8_t w1 = (prew1 + (w & 0x0f)) & 0x0f;
426 *(outBufferPtr++) = (w0 << 4) | w0;
427 *(outBufferPtr++) = (w1 << 4) | w1;
442 void FontClient::GlyphBufferData::DecompressScanline(const GlyphBufferData& __restrict__ inBufferData, uint8_t* __restrict__ outBuffer, uint32_t& __restrict__ offset)
444 switch(inBufferData.compressType)
446 case TextAbstraction::FontClient::GlyphBufferData::CompressType::NO_COMPRESS:
448 const auto bufferSize = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
450 // Copy buffer without compress
451 memcpy(outBuffer, inBufferData.buffer + offset, bufferSize);
454 offset += bufferSize;
457 case TextAbstraction::FontClient::GlyphBufferData::CompressType::BIT_PER_PIXEL_4:
459 const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
460 const uint32_t componentCount = (widthByte >> 1);
461 const bool considerPadding = (widthByte & 1) ? true : false;
463 uint8_t* __restrict__ outBufferPtr = outBuffer;
464 const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer + offset;
466 // Decompress scanline
467 for(uint32_t x = 0; x < componentCount; ++x)
469 const uint8_t v = *(inBufferPtr++);
470 const uint8_t v0 = (v >> 4) & 0x0f;
471 const uint8_t v1 = v & 0x0f;
473 *(outBufferPtr++) = (v0 << 4) | v0;
474 *(outBufferPtr++) = (v1 << 4) | v1;
478 const uint8_t v = *(inBufferPtr++);
479 *(outBufferPtr++) = (v << 4) | v;
483 offset += (widthByte + 1u) >> 1u;
486 case TextAbstraction::FontClient::GlyphBufferData::CompressType::COMPRESS_RLE4:
488 const uint32_t widthByte = inBufferData.width * Pixel::GetBytesPerPixel(inBufferData.format);
490 uint8_t* __restrict__ outBufferPtr = outBuffer;
491 const uint8_t* __restrict__ inBufferPtr = inBufferData.buffer + offset;
493 // If offset is zero, fill outBuffer as 0 first.
494 if(DALI_UNLIKELY(offset == 0))
496 memset(outBufferPtr, 0, widthByte);
499 // Decompress scanline
500 uint32_t decodedByte = 0;
501 while(decodedByte < widthByte)
503 const uint8_t v = *(inBufferPtr++);
508 const uint8_t runLength = ((v >> 4) & 0x07) + 2u;
509 decodedByte += runLength;
510 const uint8_t repeatValue = (v & 0x0f);
511 for(uint8_t iter = 0; iter < runLength; ++iter)
513 const uint8_t prev0 = (*(outBufferPtr)) & 0x0f;
514 const uint8_t v0 = (prev0 + repeatValue) & 0x0f;
515 *(outBufferPtr++) = (v0 << 4) | v0;
518 // Not compress by RLE
521 const uint8_t nonRunLength = (((v >> 4) & 0x07) << 1u) + 1u;
522 decodedByte += nonRunLength;
524 const uint8_t prev0 = (*(outBufferPtr)) & 0x0f;
525 const uint8_t v0 = (prev0 + (v & 0x0f)) & 0x0f;
526 *(outBufferPtr++) = (v0 << 4) | v0;
528 const bool ignoreLastValue = decodedByte > widthByte ? true : false;
529 if(DALI_UNLIKELY(ignoreLastValue))
532 for(uint8_t iter = 1; iter + 2 < nonRunLength; iter += 2)
534 const uint8_t w = *(inBufferPtr++);
535 const uint8_t prew0 = (*(outBufferPtr)) & 0x0f;
536 const uint8_t w0 = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
537 const uint8_t prew1 = (*(outBufferPtr + 1)) & 0x0f;
538 const uint8_t w1 = (prew1 + (w & 0x0f)) & 0x0f;
541 *(outBufferPtr++) = (w0 << 4) | w0;
542 *(outBufferPtr++) = (w1 << 4) | w1;
546 const uint8_t w = ((*(inBufferPtr++)) >> 4) & 0x0f;
547 const uint8_t prew0 = (*(outBufferPtr)) & 0x0f;
548 const uint8_t w0 = (prew0 + w) & 0x0f;
551 *(outBufferPtr++) = (w0 << 4) | w0;
556 for(uint8_t iter = 1; iter < nonRunLength; iter += 2)
558 const uint8_t w = *(inBufferPtr++);
559 const uint8_t prew0 = (*(outBufferPtr)) & 0x0f;
560 const uint8_t w0 = (prew0 + ((w >> 4) & 0x0f)) & 0x0f;
561 const uint8_t prew1 = (*(outBufferPtr + 1)) & 0x0f;
562 const uint8_t w1 = (prew1 + (w & 0x0f)) & 0x0f;
565 *(outBufferPtr++) = (w0 << 4) | w0;
566 *(outBufferPtr++) = (w1 << 4) | w1;
582 FontClient FontClient::Get()
584 return Internal::FontClient::Get();
587 FontClient::FontClient()
591 FontClient::~FontClient()
595 FontClient::FontClient(const FontClient& handle)
600 FontClient& FontClient::operator=(const FontClient& handle)
602 BaseHandle::operator=(handle);
606 void FontClient::ClearCache()
608 GetImplementation(*this).ClearCache();
611 void FontClient::SetDpi(unsigned int horizontalDpi, unsigned int verticalDpi)
613 GetImplementation(*this).SetDpi(horizontalDpi, verticalDpi);
616 void FontClient::GetDpi(unsigned int& horizontalDpi, unsigned int& verticalDpi)
618 GetImplementation(*this).GetDpi(horizontalDpi, verticalDpi);
621 int FontClient::GetDefaultFontSize()
623 return GetImplementation(*this).GetDefaultFontSize();
626 void FontClient::ResetSystemDefaults()
628 GetImplementation(*this).ResetSystemDefaults();
631 void FontClient::GetDefaultFonts(FontList& defaultFonts)
633 GetImplementation(*this).GetDefaultFonts(defaultFonts);
636 void FontClient::GetDefaultPlatformFontDescription(FontDescription& fontDescription)
638 GetImplementation(*this).GetDefaultPlatformFontDescription(fontDescription);
641 void FontClient::GetSystemFonts(FontList& systemFonts)
643 GetImplementation(*this).GetSystemFonts(systemFonts);
646 void FontClient::GetDescription(FontId id, FontDescription& fontDescription)
648 GetImplementation(*this).GetDescription(id, fontDescription);
651 PointSize26Dot6 FontClient::GetPointSize(FontId id)
653 return GetImplementation(*this).GetPointSize(id);
656 bool FontClient::IsCharacterSupportedByFont(FontId fontId, Character character)
658 return GetImplementation(*this).IsCharacterSupportedByFont(fontId, character);
661 FontId FontClient::FindDefaultFont(Character charcode,
662 PointSize26Dot6 requestedPointSize,
665 return GetImplementation(*this).FindDefaultFont(charcode,
670 FontId FontClient::FindFallbackFont(Character charcode,
671 const FontDescription& preferredFontDescription,
672 PointSize26Dot6 requestedPointSize,
675 return GetImplementation(*this).FindFallbackFont(charcode, preferredFontDescription, requestedPointSize, preferColor);
678 FontId FontClient::GetFontId(const FontPath& path, PointSize26Dot6 requestedPointSize, FaceIndex faceIndex)
680 return GetImplementation(*this).GetFontId(path, requestedPointSize, faceIndex);
683 FontId FontClient::GetFontId(const FontDescription& fontDescription,
684 PointSize26Dot6 requestedPointSize,
687 return GetImplementation(*this).GetFontId(fontDescription,
692 FontId FontClient::GetFontId(const BitmapFont& bitmapFont)
694 return GetImplementation(*this).GetFontId(bitmapFont);
697 bool FontClient::IsScalable(const FontPath& path)
699 return GetImplementation(*this).IsScalable(path);
702 bool FontClient::IsScalable(const FontDescription& fontDescription)
704 return GetImplementation(*this).IsScalable(fontDescription);
707 void FontClient::GetFixedSizes(const FontPath& path, Dali::Vector<PointSize26Dot6>& sizes)
709 GetImplementation(*this).GetFixedSizes(path, sizes);
712 void FontClient::GetFixedSizes(const FontDescription& fontDescription,
713 Dali::Vector<PointSize26Dot6>& sizes)
715 GetImplementation(*this).GetFixedSizes(fontDescription, sizes);
718 bool FontClient::HasItalicStyle(FontId fontId) const
720 return GetImplementation(*this).HasItalicStyle(fontId);
723 void FontClient::GetFontMetrics(FontId fontId, FontMetrics& metrics)
725 GetImplementation(*this).GetFontMetrics(fontId, metrics);
728 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode)
730 return GetImplementation(*this).GetGlyphIndex(fontId, charcode);
733 GlyphIndex FontClient::GetGlyphIndex(FontId fontId, Character charcode, Character variantSelector)
735 return GetImplementation(*this).GetGlyphIndex(fontId, charcode, variantSelector);
738 bool FontClient::GetGlyphMetrics(GlyphInfo* array, uint32_t size, GlyphType type, bool horizontal)
740 return GetImplementation(*this).GetGlyphMetrics(array, size, type, horizontal);
743 void FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, bool isItalicRequired, bool isBoldRequired, GlyphBufferData& data, int outlineWidth)
745 GetImplementation(*this).CreateBitmap(fontId, glyphIndex, isItalicRequired, isBoldRequired, data, outlineWidth);
748 PixelData FontClient::CreateBitmap(FontId fontId, GlyphIndex glyphIndex, int outlineWidth)
750 return GetImplementation(*this).CreateBitmap(fontId, glyphIndex, outlineWidth);
753 void FontClient::CreateVectorBlob(FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob, unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight)
755 GetImplementation(*this).CreateVectorBlob(fontId, glyphIndex, blob, blobLength, nominalWidth, nominalHeight);
758 const GlyphInfo& FontClient::GetEllipsisGlyph(PointSize26Dot6 requestedPointSize)
760 return GetImplementation(*this).GetEllipsisGlyph(requestedPointSize);
763 bool FontClient::IsColorGlyph(FontId fontId, GlyphIndex glyphIndex)
765 return GetImplementation(*this).IsColorGlyph(fontId, glyphIndex);
768 bool FontClient::AddCustomFontDirectory(const FontPath& path)
770 return GetImplementation(*this).AddCustomFontDirectory(path);
773 GlyphIndex FontClient::CreateEmbeddedItem(const EmbeddedItemDescription& description, Pixel::Format& pixelFormat)
775 return GetImplementation(*this).CreateEmbeddedItem(description, pixelFormat);
778 void FontClient::EnableAtlasLimitation(bool enabled)
780 return GetImplementation(*this).EnableAtlasLimitation(enabled);
783 bool FontClient::IsAtlasLimitationEnabled() const
785 return GetImplementation(*this).IsAtlasLimitationEnabled();
788 Size FontClient::GetMaximumTextAtlasSize() const
790 return GetImplementation(*this).GetMaximumTextAtlasSize();
793 Size FontClient::GetDefaultTextAtlasSize() const
795 return GetImplementation(*this).GetDefaultTextAtlasSize();
798 Size FontClient::GetCurrentMaximumBlockSizeFitInAtlas() const
800 return GetImplementation(*this).GetCurrentMaximumBlockSizeFitInAtlas();
803 bool FontClient::SetCurrentMaximumBlockSizeFitInAtlas(const Size& currentMaximumBlockSizeFitInAtlas)
805 return GetImplementation(*this).SetCurrentMaximumBlockSizeFitInAtlas(currentMaximumBlockSizeFitInAtlas);
808 uint32_t FontClient::GetNumberOfPointsPerOneUnitOfPointSize() const
810 return GetImplementation(*this).GetNumberOfPointsPerOneUnitOfPointSize();
813 FontClient::FontClient(Internal::FontClient* internal)
814 : BaseHandle(internal)
818 FontClient FontClientPreInitialize()
820 return Internal::FontClient::PreInitialize();
823 } // namespace TextAbstraction