• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 #include "src/core/SkFontScanner.h"
8 #include "src/sfnt/SkOTUtils.h"
9 
10 #include "src/ports/SkFontScanner_fontations.h"
11 #include "src/ports/SkTypeface_fontations_priv.h"
12 #include "src/ports/fontations/src/skpath_bridge.h"
13 
14 using namespace skia_private;
15 
16 namespace {
make_bridge_font_ref(sk_sp<SkData> fontData,uint32_t index)17 rust::Box<::fontations_ffi::BridgeFontRef> make_bridge_font_ref(sk_sp<SkData> fontData,
18                                                                 uint32_t index) {
19     rust::Slice<const uint8_t> slice{fontData->bytes(), fontData->size()};
20     return fontations_ffi::make_font_ref(slice, index);
21 }
22 }
23 
SkFontScanner_Fontations()24 SkFontScanner_Fontations::SkFontScanner_Fontations() {
25 }
26 
~SkFontScanner_Fontations()27 SkFontScanner_Fontations::~SkFontScanner_Fontations() {
28 }
29 
scanFile(SkStreamAsset * stream,int * numFaces) const30 bool SkFontScanner_Fontations::scanFile(SkStreamAsset* stream, int* numFaces) const {
31     sk_sp<SkData> fontData = SkData::MakeFromStream(stream, stream->getLength());
32     stream->rewind();
33     rust::Slice<const uint8_t> slice{fontData->bytes(), fontData->size()};
34     ::std::uint32_t num_fonts;
35     if (!fontations_ffi::font_or_collection(slice, num_fonts)) {
36         return false;
37     }
38     *numFaces = num_fonts == 0 ? 1 : num_fonts;
39     return true;
40 }
41 
scanFace(SkStreamAsset * stream,int faceIndex,int * numInstances) const42 bool SkFontScanner_Fontations::scanFace(SkStreamAsset* stream,
43                                         int faceIndex,
44                                         int* numInstances) const {
45     rust::Box<fontations_ffi::BridgeFontRef> fontRef =
46             make_bridge_font_ref(SkData::MakeFromStream(stream, stream->getLength()), faceIndex);
47     stream->rewind();
48     if (!fontations_ffi::font_ref_is_valid(*fontRef)) {
49         return false;
50     }
51 
52     // TODO: For now assume only the default instance (not variation)
53     *numInstances = 1;
54     return true;
55 }
56 
57 // TODO: For now assume only the default instance (not variation)
scanInstance(SkStreamAsset * stream,int faceIndex,int instanceIndex,SkString * name,SkFontStyle * style,bool * isFixedPitch,AxisDefinitions * axes) const58 bool SkFontScanner_Fontations::scanInstance(SkStreamAsset* stream,
59                                             int faceIndex,
60                                             int instanceIndex,
61                                             SkString* name,
62                                             SkFontStyle* style,
63                                             bool* isFixedPitch,
64                                             AxisDefinitions* axes) const {
65     SkASSERT(instanceIndex == 0);
66     rust::Box<fontations_ffi::BridgeFontRef> fontRef =
67             make_bridge_font_ref(SkData::MakeFromStream(stream, stream->getLength()), faceIndex);
68     if (!fontations_ffi::font_ref_is_valid(*fontRef)) {
69         return false;
70     }
71 
72     if (name != nullptr) {
73         rust::String readFamilyName = fontations_ffi::family_name(*fontRef);
74         *name = SkString(readFamilyName.data(), readFamilyName.size());
75     }
76 
77     if (style != nullptr) {
78         rust::Slice<const fontations_ffi::SkiaDesignCoordinate> coordinates;
79         rust::Box<fontations_ffi::BridgeNormalizedCoords> normalizedCoords =
80             resolve_into_normalized_coords(*fontRef, coordinates);
81         fontations_ffi::BridgeFontStyle fontStyle;
82         if (fontations_ffi::get_font_style(*fontRef, *normalizedCoords, fontStyle)) {
83             *style = SkFontStyle(fontStyle.weight, fontStyle.width,  (SkFontStyle::Slant)fontStyle.slant);
84         } else {
85             *style = SkFontStyle::Normal();
86         }
87     }
88 
89     return true;
90 }
91 
92