2022-01-01 01:21:03 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2021 Ola Rinta-Koski
|
2024-01-12 17:04:05 +00:00
|
|
|
* Copyright (C) 2021-2024 Kicad Developers, see AUTHORS.txt for contributors.
|
2022-01-01 01:21:03 +00:00
|
|
|
*
|
|
|
|
* Outline font class
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef OUTLINE_DECOMPOSER_H
|
|
|
|
#define OUTLINE_DECOMPOSER_H
|
|
|
|
|
|
|
|
#include <vector>
|
2022-01-08 17:35:40 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#include <ft2build.h>
|
|
|
|
#else
|
2022-01-01 01:21:03 +00:00
|
|
|
#include <freetype2/ft2build.h>
|
2022-01-08 17:35:40 +00:00
|
|
|
#endif
|
2022-01-01 01:21:03 +00:00
|
|
|
#include FT_FREETYPE_H
|
|
|
|
#include FT_OUTLINE_H
|
|
|
|
#include <math/box2.h>
|
|
|
|
#include <math/vector2d.h>
|
|
|
|
#include <font/glyph.h>
|
|
|
|
|
|
|
|
namespace KIFONT
|
|
|
|
{
|
2022-07-31 16:35:37 +00:00
|
|
|
struct CONTOUR
|
2022-01-01 01:21:03 +00:00
|
|
|
{
|
2024-02-05 15:30:44 +00:00
|
|
|
std::vector<VECTOR2D> m_Points;
|
|
|
|
int m_Winding = 0;
|
|
|
|
FT_Orientation m_Orientation;
|
2022-07-31 16:35:37 +00:00
|
|
|
};
|
2022-01-01 01:21:03 +00:00
|
|
|
|
2024-01-12 17:04:05 +00:00
|
|
|
struct GLYPH_DATA
|
|
|
|
{
|
|
|
|
std::vector<CONTOUR> m_Contours;
|
|
|
|
|
|
|
|
// Cache of the triangulation data. We'll use this as a hint for triangulating the actual
|
|
|
|
// OUTLINE_GLYPHs.
|
|
|
|
std::vector<std::unique_ptr<SHAPE_POLY_SET::TRIANGULATED_POLYGON>> m_TriangulationData;
|
|
|
|
};
|
|
|
|
|
2022-01-01 01:21:03 +00:00
|
|
|
|
|
|
|
class OUTLINE_DECOMPOSER
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
OUTLINE_DECOMPOSER( FT_Outline& aOutline );
|
|
|
|
|
2024-02-05 15:33:03 +00:00
|
|
|
bool OutlineToSegments( std::vector<CONTOUR>* aContours );
|
2022-01-01 01:21:03 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
void newContour();
|
|
|
|
|
|
|
|
void addContourPoint( const VECTOR2D& p );
|
|
|
|
|
2024-02-05 15:30:44 +00:00
|
|
|
bool approximateBezierCurve( std::vector<VECTOR2D>& result,
|
|
|
|
const std::vector<VECTOR2D>& bezier ) const;
|
|
|
|
bool approximateQuadraticBezierCurve( std::vector<VECTOR2D>& result,
|
|
|
|
const std::vector<VECTOR2D>& bezier ) const;
|
|
|
|
bool approximateCubicBezierCurve( std::vector<VECTOR2D>& result,
|
|
|
|
const std::vector<VECTOR2D>& bezier ) const;
|
2022-01-01 01:21:03 +00:00
|
|
|
|
|
|
|
/**
|
2024-01-12 17:09:52 +00:00
|
|
|
* @return 1 if aContour is in clockwise order, -1 if it is in counterclockwise order,
|
|
|
|
* or 0 if the winding can't be determined.
|
2022-01-01 01:21:03 +00:00
|
|
|
*/
|
2024-02-05 15:30:44 +00:00
|
|
|
int winding( const std::vector<VECTOR2D>& aContour ) const;
|
2022-01-01 01:21:03 +00:00
|
|
|
|
2023-05-19 02:05:12 +00:00
|
|
|
inline static unsigned int onCurve( char aTags )
|
2022-01-01 01:21:03 +00:00
|
|
|
{
|
|
|
|
return aTags & 0x1;
|
|
|
|
}
|
|
|
|
|
2023-05-19 02:05:12 +00:00
|
|
|
inline static unsigned int thirdOrderBezierPoint( char aTags )
|
2022-01-01 01:21:03 +00:00
|
|
|
{
|
|
|
|
return onCurve( aTags ) ? 0 : aTags & 0x2;
|
|
|
|
}
|
|
|
|
|
2023-05-19 02:05:12 +00:00
|
|
|
inline static unsigned int secondOrderBezierPoint( char aTags )
|
2022-01-01 01:21:03 +00:00
|
|
|
{
|
|
|
|
return onCurve( aTags ) ? 0 : !thirdOrderBezierPoint( aTags );
|
|
|
|
}
|
|
|
|
|
2023-05-19 02:05:12 +00:00
|
|
|
inline static unsigned int hasDropout( char aTags )
|
2022-01-01 01:21:03 +00:00
|
|
|
{
|
|
|
|
return aTags & 0x4;
|
|
|
|
}
|
|
|
|
|
2023-05-19 02:05:12 +00:00
|
|
|
inline static unsigned int dropoutMode( char aTags )
|
2022-01-01 01:21:03 +00:00
|
|
|
{
|
|
|
|
return hasDropout( aTags ) ? ( aTags & 0x38 ) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FT_Outline_Decompose callbacks
|
|
|
|
static int moveTo( const FT_Vector* aEndPoint, void* aCallbackData );
|
|
|
|
|
|
|
|
static int lineTo( const FT_Vector* aEndPoint, void* aCallbackData );
|
|
|
|
|
|
|
|
static int quadraticTo( const FT_Vector* aControlPoint, const FT_Vector* aEndPoint,
|
|
|
|
void* aCallbackData );
|
|
|
|
|
|
|
|
static int cubicTo( const FT_Vector* aFirstControlPoint, const FT_Vector* aSecondControlPoint,
|
|
|
|
const FT_Vector* aEndPoint, void* aCallbackData );
|
|
|
|
|
|
|
|
private:
|
2024-02-05 15:30:44 +00:00
|
|
|
FT_Outline& m_outline;
|
|
|
|
std::vector<CONTOUR>* m_contours;
|
2022-01-01 01:21:03 +00:00
|
|
|
|
2024-02-05 15:30:44 +00:00
|
|
|
VECTOR2D m_lastEndPoint;
|
2022-01-01 01:21:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} //namespace KIFONT
|
|
|
|
|
|
|
|
#endif // OUTLINE_DECOMPOSER_H
|