Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement GlyphFace rendering capabilities #371

Merged
merged 22 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drawers/src/layertree/CustomLayerTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "CustomLayer.h"
#include "base/LayerTreeDrawers.h"
#include "drawers/AppHost.h"
#include "tgfx/core/GlyphRun.h"
#include "tgfx/core/UTF.h"

namespace drawers {
Expand Down
13 changes: 13 additions & 0 deletions include/tgfx/core/Canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <stack>
#include "tgfx/core/Font.h"
#include "tgfx/core/GlyphFace.h"
#include "tgfx/core/Image.h"
#include "tgfx/core/Paint.h"
#include "tgfx/core/Path.h"
Expand Down Expand Up @@ -279,6 +280,18 @@ class Canvas {
void drawGlyphs(const GlyphID glyphs[], const Point positions[], size_t glyphCount,
const Font& font, const Paint& paint);

/**
* Draws an array of glyphs from glyphIDs at positions using clip, matrix, glyphFace, and paint.
* @param glyphs The array of GlyphID to draw.
* @param positions Where to draw each glyph.
* @param glyphCount number of glyphs to draw.
* @param glyphFace custom `GlyphFace` used for rendering glyphs.
* @param paint blend, color, and so on, used to draw.
* @note The lengths of `glyphs` and `positions` must be the same.
*/
void drawGlyphs(const GlyphID glyphs[], const Point positions[], size_t glyphCount,
std::shared_ptr<GlyphFace> glyphFace, const Paint& paint) const;

/**
* Draws a TextBlob at (x, y) using clip, matrix, and paint.
* @param textBlob the text blob to draw.
Expand Down
75 changes: 75 additions & 0 deletions include/tgfx/core/GlyphFace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Tencent is pleased to support the open source community by making tgfx available.
//
// Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// unless required by applicable law or agreed to in writing, software distributed under the
// license is distributed on an "as is" basis, without warranties or conditions of any kind,
// either express or implied. see the license for the specific language governing permissions
// and limitations under the license.
//
/////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#include <memory>
#include "tgfx/core/Image.h"
#include "tgfx/core/Path.h"
#include "tgfx/core/Typeface.h"

namespace tgfx {
/**
* GlyphFace is a render-only font that contains only the necessary information to render glyphs. It can be implemented externally to render glyphs from a custom font or used as a wrapper around a Font object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

忘记换行了

*/
class GlyphFace {
public:
GlyphFace() = default;
virtual ~GlyphFace() = default;

/**
* Returns true if the font has color glyphs, for example, color emojis.
*/
virtual bool hasColor() const = 0;

/**
* Returns true if the font has outline glyphs, meaning it can generate paths.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

更新注释里的 the font 为 the glyph face

*/
virtual bool hasOutlines() const = 0;

/**
* Returns a new GlyphFace with the same attributes of this font, but with the specified scale.
*/
virtual std::shared_ptr<GlyphFace> makeScaled(float scale) = 0;

/**
* Creates a path corresponding to glyph outline. If glyph has an outline, copies outline to path
* and returns true. If glyph is described by a bitmap, returns false and ignores path parameter.
*/
virtual bool getPath(GlyphID glyphID, Path* path) const = 0;

/**
* Creates an Image capturing the content of the specified glyph. The returned matrix should apply
* to the glyph image when drawing. Please note that the fauxBold is not supported for this
* method.
*/
virtual std::shared_ptr<Image> getImage(GlyphID glyphID, Matrix* matrix) const = 0;

/**
* Returns the bounding box of the specified glyph.
*/
virtual Rect getBounds(GlyphID glyphID) const = 0;

/**
* Returns the font object represented by this GlyphFace.
* If the GlyphFace is not a font object, returns false and sets the font pointer to null.
* If the GlyphFace is a font object, returns true and sets the font pointer to the font object.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修改注释: Checks if the GlyphFace is backed by a Font object. If so, sets the font pointer to the backing Font object and returns true. Otherwise, returns false and leaves the font pointer unchanged.

*/
virtual bool asFont(Font* font) const = 0;
};
} // namespace tgfx
18 changes: 12 additions & 6 deletions include/tgfx/core/GlyphRun.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
#pragma once

#include "tgfx/core/Font.h"
#include "tgfx/core/GlyphFace.h"

namespace tgfx {
/**
* GlyphRun represents a sequence of glyphs from a single font, along with their positions.
*/
struct GlyphRun {
class GlyphRun {
public:
/**
* Constructs an empty GlyphRun.
*/
Expand All @@ -33,14 +35,18 @@ struct GlyphRun {
/**
* Constructs a GlyphRun using a font, a list of glyph IDs, and their positions.
*/
GlyphRun(Font font, std::vector<GlyphID> glyphIDs, std::vector<Point> positions)
: font(font), glyphs(glyphIDs), positions(positions) {
}
GlyphRun(Font font, std::vector<GlyphID> glyphIDs, std::vector<Point> positions);

/**
* Returns the font used to render the glyphs in this run.
* Constructs a GlyphRun using a GlyphFace, a list of glyph IDs, and their positions.
*/
Font font = {};
GlyphRun(std::shared_ptr<GlyphFace> glyphFace, std::vector<GlyphID> glyphIDs,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不要删除原本的Font构造函数,提供两个版本,和Canvas上一样。

std::vector<Point> positions);

/**
* Returns the GlyphFace used to render the glyphs in this run.
*/
std::shared_ptr<GlyphFace> glyphFace = nullptr;

/**
* Returns the sequence of glyph IDs in this run.
Expand Down
3 changes: 3 additions & 0 deletions resources/assets/glyph1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions resources/assets/glyph2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions resources/assets/glyph3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 10 additions & 4 deletions src/core/Canvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@

#include "tgfx/core/Canvas.h"
#include "core/DrawContext.h"
#include "core/FontGlyphFace.h"
#include "core/LayerUnrollContext.h"
#include "core/Records.h"
#include "core/utils/Log.h"
#include "core/utils/Profiling.h"
#include "tgfx/core/PathEffect.h"
#include "tgfx/core/Surface.h"

namespace tgfx {
Expand Down Expand Up @@ -330,10 +329,17 @@ void Canvas::drawSimpleText(const std::string& text, float x, float y, const Fon
void Canvas::drawGlyphs(const GlyphID glyphs[], const Point positions[], size_t glyphCount,
const Font& font, const Paint& paint) {
TRACE_EVENT;
if (glyphCount == 0 || paint.nothingToDraw()) {
drawGlyphs(glyphs, positions, glyphCount, FontGlyphFace::Make(font), paint);
}

void Canvas::drawGlyphs(const GlyphID glyphs[], const Point positions[], size_t glyphCount,
std::shared_ptr<GlyphFace> glyphFace, const Paint& paint) const {
TRACE_EVENT;
if (glyphCount == 0 || glyphFace == nullptr || paint.nothingToDraw()) {
return;
}
GlyphRun glyphRun(font, {glyphs, glyphs + glyphCount}, {positions, positions + glyphCount});

GlyphRun glyphRun(glyphFace, {glyphs, glyphs + glyphCount}, {positions, positions + glyphCount});
auto glyphRunList = std::make_shared<GlyphRunList>(std::move(glyphRun));
auto style = CreateFillStyle(paint);
drawContext->drawGlyphRunList(std::move(glyphRunList), *mcState, style, paint.getStroke());
Expand Down
65 changes: 65 additions & 0 deletions src/core/FontGlyphFace.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Tencent is pleased to support the open source community by making tgfx available.
//
// Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// unless required by applicable law or agreed to in writing, software distributed under the
// license is distributed on an "as is" basis, without warranties or conditions of any kind,
// either express or implied. see the license for the specific language governing permissions
// and limitations under the license.
//
/////////////////////////////////////////////////////////////////////////////////////////////////

#include "core/FontGlyphFace.h"
#include "utils/MathExtra.h"

namespace tgfx {
std::shared_ptr<FontGlyphFace> FontGlyphFace::Make(const Font& font) {
if (font.getTypeface() == nullptr) {
return nullptr;
}
return std::shared_ptr<FontGlyphFace>(new FontGlyphFace(font));
}

bool FontGlyphFace::hasColor() const {
return _font.hasColor();
}

bool FontGlyphFace::hasOutlines() const {
return _font.hasOutlines();
}

std::shared_ptr<GlyphFace> FontGlyphFace::makeScaled(float scale) {
if (FloatNearlyZero(scale)) {
return nullptr;
}
auto size = _font.getSize() * scale;
return FontGlyphFace::Make(_font.makeWithSize(size));
}

bool FontGlyphFace::getPath(GlyphID glyphID, Path* path) const {
return _font.getPath(glyphID, path);
}

std::shared_ptr<Image> FontGlyphFace::getImage(GlyphID glyphID, Matrix* matrix) const {
return _font.getImage(glyphID, matrix);
}

Rect FontGlyphFace::getBounds(GlyphID glyphID) const {
return _font.getBounds(glyphID);
}

bool FontGlyphFace::asFont(Font* font) const {
if (font == nullptr) {
return false;
}
*font = _font;
return true;
}
} // namespace tgfx
48 changes: 48 additions & 0 deletions src/core/FontGlyphFace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Tencent is pleased to support the open source community by making tgfx available.
//
// Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// unless required by applicable law or agreed to in writing, software distributed under the
// license is distributed on an "as is" basis, without warranties or conditions of any kind,
// either express or implied. see the license for the specific language governing permissions
// and limitations under the license.
//
/////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#include "tgfx/core/Font.h"
#include "tgfx/core/GlyphFace.h"

namespace tgfx {
class FontGlyphFace final : public GlyphFace {
public:
static std::shared_ptr<FontGlyphFace> Make(const Font& font);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个方法重命名为Wrap,移动到父类GlyphFace上作为公开API,之前GlyphRun的修改可以还原回去。


bool hasColor() const override;

bool hasOutlines() const override;

std::shared_ptr<GlyphFace> makeScaled(float scale) override;

bool getPath(GlyphID glyphID, Path* path) const override;

std::shared_ptr<Image> getImage(GlyphID glyphID, Matrix* matrix) const override;

Rect getBounds(GlyphID glyphID) const override;

bool asFont(Font* font) const override;

private:
explicit FontGlyphFace(const Font& font) : _font(font) {
}

Font _font = {};
};
} // namespace tgfx
31 changes: 31 additions & 0 deletions src/core/GlyphRun.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Tencent is pleased to support the open source community by making tgfx available.
//
// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// unless required by applicable law or agreed to in writing, software distributed under the
// license is distributed on an "as is" basis, without warranties or conditions of any kind,
// either express or implied. see the license for the specific language governing permissions
// and limitations under the license.
//
/////////////////////////////////////////////////////////////////////////////////////////////////
#include "tgfx/core/GlyphRun.h"
#include "core/FontGlyphFace.h"

namespace tgfx {
GlyphRun::GlyphRun(Font font, std::vector<GlyphID> glyphIDs, std::vector<Point> positions)
: GlyphRun(FontGlyphFace::Make(font), glyphIDs, positions) {
}

GlyphRun::GlyphRun(std::shared_ptr<GlyphFace> glyphFace, std::vector<GlyphID> glyphIDs,
std::vector<Point> positions)
: glyphFace(glyphFace), glyphs(glyphIDs), positions(positions) {
}

} // namespace tgfx
Loading
Loading