mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 09:25:45 +08:00
Merge pull request #18760 from vpisarev:ttf2_1
This commit is contained in:
commit
3268cc46ba
@ -508,6 +508,9 @@ OCV_OPTION(OPENCV_ENABLE_MEMALIGN "Enable posix_memalign or memalign usage"
|
||||
OCV_OPTION(ENABLE_PYLINT "Add target with Pylint checks" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) )
|
||||
OCV_OPTION(ENABLE_FLAKE8 "Add target with Python flake8 checker" (BUILD_DOCS OR BUILD_EXAMPLES) IF (NOT CMAKE_CROSSCOMPILING AND NOT APPLE_FRAMEWORK) )
|
||||
|
||||
OCV_OPTION(WITH_UNIFONT "Build 'uni' font (WQY MicroHei) into OpenCV" (NOT BUILD_opencv_js)
|
||||
VERIFY HAVE_UNIFONT)
|
||||
|
||||
if(ENABLE_IMPL_COLLECTION)
|
||||
add_definitions(-DCV_COLLECT_IMPL_DATA)
|
||||
endif()
|
||||
@ -1238,6 +1241,10 @@ if(WITH_VTK OR HAVE_VTK)
|
||||
status(" VTK support:" HAVE_VTK THEN "YES (ver ${VTK_VERSION})" ELSE NO)
|
||||
endif()
|
||||
|
||||
if(WITH_UNIFONT OR HAVE_UNIFONT)
|
||||
status(" Built-in Unicode font:" HAVE_UNIFONT THEN "YES" ELSE "NO")
|
||||
endif()
|
||||
|
||||
# ========================== MEDIA IO ==========================
|
||||
status("")
|
||||
status(" Media I/O: ")
|
||||
|
@ -1881,3 +1881,28 @@ function(ocv_update_file filepath content)
|
||||
file(WRITE "${filepath}" "${content}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# adopted from https://gist.github.com/amir-saniyan/de99cee82fa9d8d615bb69f3f53b6004
|
||||
function(ocv_blob2hdr blob_filename hdr_filename cpp_variable)
|
||||
if(EXISTS "${hdr_filename}")
|
||||
if("${hdr_filename}" IS_NEWER_THAN "${blob_filename}")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
file(READ "${blob_filename}" hex_content HEX)
|
||||
|
||||
# repeat [0-9a-f] 32 times
|
||||
set(pattern "[0-9a-f][0-9a-f][0-9a-f][0-9a-f]")
|
||||
set(pattern "${pattern}${pattern}")
|
||||
set(pattern "${pattern}${pattern}")
|
||||
set(pattern "${pattern}${pattern}")
|
||||
string(REGEX REPLACE "(${pattern})" "\\1\n" content "${hex_content}")
|
||||
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " content "${content}")
|
||||
string(REGEX REPLACE ", $" "" content "${content}")
|
||||
|
||||
set(array_definition "static const unsigned char ${cpp_variable}[] =\n{\n${content}\n};")
|
||||
set(source "// Auto generated file.\n${array_definition}\n")
|
||||
|
||||
file(WRITE "${hdr_filename}" "${source}")
|
||||
endfunction()
|
||||
|
@ -164,4 +164,7 @@
|
||||
/* Library QR-code decoding */
|
||||
#cmakedefine HAVE_QUIRC
|
||||
|
||||
/* The font "uni" (WQY MicroHei) is available */
|
||||
#cmakedefine HAVE_UNIFONT
|
||||
|
||||
#endif // OPENCV_CVCONFIG_H_INCLUDED
|
||||
|
@ -915,6 +915,14 @@ protected:
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @brief Constructs the 'fourcc' code, used in video codecs and many other places.
|
||||
Simply call it with 4 chars like `CV_FOURCC('I', 'Y', 'U', 'V')`
|
||||
*/
|
||||
CV_INLINE int CV_FOURCC(char c1, char c2, char c3, char c4)
|
||||
{
|
||||
return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24);
|
||||
}
|
||||
|
||||
//! @}
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
@ -21,6 +21,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
CV_EXPORTS @interface Range : NSObject
|
||||
|
||||
#ifdef __cplusplus
|
||||
@property(readonly) cv::Range& nativeRef;
|
||||
#endif
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
@property int start;
|
||||
@ -90,6 +94,10 @@ CV_EXPORTS @interface Range : NSObject
|
||||
*/
|
||||
- (NSString*)description;
|
||||
|
||||
#ifdef __cplusplus
|
||||
+ (instancetype)fromNative:(cv::Range&)range;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
96
modules/core/misc/objc/common/Range.mm
Normal file
96
modules/core/misc/objc/common/Range.mm
Normal file
@ -0,0 +1,96 @@
|
||||
//
|
||||
// Range.m
|
||||
//
|
||||
// Created by Giles Payne on 2019/10/08.
|
||||
//
|
||||
|
||||
#import "Range.h"
|
||||
|
||||
@implementation Range {
|
||||
cv::Range native;
|
||||
}
|
||||
|
||||
- (cv::Range&)nativeRef {
|
||||
return native;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
return [self initWithStart:0 end: 0];
|
||||
}
|
||||
|
||||
- (instancetype)initWithStart:(int)start end:(int)end {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
self.start = start;
|
||||
self.end = end;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithVals:(NSArray<NSNumber*>*)vals {
|
||||
self = [self init];
|
||||
if (self != nil) {
|
||||
[self set:vals];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)set:(NSArray<NSNumber*>*)vals {
|
||||
self.start = (vals != nil && vals.count > 0) ? vals[0].intValue : 0;
|
||||
self.end = (vals != nil && vals.count > 1 ) ? vals[1].intValue : 0;
|
||||
}
|
||||
|
||||
- (int)size {
|
||||
return [self empty] ? 0 : self.end - self.start;
|
||||
}
|
||||
|
||||
- (BOOL)empty {
|
||||
return self.end <= self.start;
|
||||
}
|
||||
|
||||
+ (Range*)all {
|
||||
return [[Range alloc] initWithStart:INT_MIN end:INT_MAX];
|
||||
}
|
||||
|
||||
- (Range*)intersection:(Range*)r1 {
|
||||
Range* out = [[Range alloc] initWithStart:MAX(r1.start, self.start) end:MIN(r1.end, self.end)];
|
||||
out.end = MAX(out.end, out.start);
|
||||
return out;
|
||||
}
|
||||
|
||||
- (Range*)shift:(int)delta {
|
||||
return [[Range alloc] initWithStart:self.start + delta end:self.end + delta];
|
||||
}
|
||||
|
||||
- (Range*)clone {
|
||||
return [[Range alloc] initWithStart:self.start end:self.end];
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)other {
|
||||
if (other == self) {
|
||||
return YES;
|
||||
} else if (![other isKindOfClass:[Range class]]) {
|
||||
return NO;
|
||||
} else {
|
||||
Range* it = (Range*)other;
|
||||
return self.start == it.start && self.end == it.end;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)hash {
|
||||
int prime = 31;
|
||||
uint32_t result = 1;
|
||||
result = prime * result + self.start;
|
||||
result = prime * result + self.end;
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (instancetype)fromNative:(cv::Range&)range {
|
||||
return [[Range alloc] initWithStart:range.start end:range.end];
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"Range {%d, %d}", self.start, self.end];
|
||||
}
|
||||
|
||||
@end
|
@ -147,7 +147,9 @@
|
||||
"from_cpp": "[Point3i fromNative:%(n)s]"
|
||||
},
|
||||
"Range": {
|
||||
"objc_type": "Range*"
|
||||
"objc_type": "Range*",
|
||||
"to_cpp": "%(n)s.nativeRef",
|
||||
"from_cpp": "[Point3i fromNative:%(n)s]"
|
||||
},
|
||||
"Rect": {
|
||||
"objc_type": "Rect2i*",
|
||||
|
@ -12,8 +12,49 @@ ocv_add_dispatched_file(smooth SSE2 SSE4_1 AVX2)
|
||||
ocv_add_dispatched_file(sumpixels SSE2 AVX2 AVX512_SKX)
|
||||
ocv_define_module(imgproc opencv_core WRAP java objc python js)
|
||||
|
||||
ocv_module_include_directories(opencv_imgproc ${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
ocv_check_environment_variables(OPENCV_IPP_GAUSSIAN_BLUR)
|
||||
option(OPENCV_IPP_GAUSSIAN_BLUR "Enable IPP optimizations for GaussianBlur (+8Mb in binary size)" OFF)
|
||||
if(OPENCV_IPP_GAUSSIAN_BLUR)
|
||||
ocv_append_source_file_compile_definitions(${CMAKE_CURRENT_SOURCE_DIR}/src/smooth.dispatch.cpp "ENABLE_IPP_GAUSSIAN_BLUR=1")
|
||||
endif()
|
||||
|
||||
set(UNIFONT_MD5 "fb79cf5b4f4c89414f1233f14c2eb273")
|
||||
set(UNIFONT_NAME "WenQuanYiMicroHei.ttf.gz")
|
||||
set(UNIFONT_COMMIT "cc7d85179d69a704bee209aa37ce8a657f2f8b34")
|
||||
set(UNIFONT_URL "https://raw.githubusercontent.com/vpisarev/opencv_3rdparty/${UNIFONT_COMMIT}/")
|
||||
|
||||
unset(HAVE_UNIFONT)
|
||||
unset(HAVE_UNIFONT CACHE)
|
||||
|
||||
if (WITH_UNIFONT)
|
||||
ocv_download(FILENAME ${UNIFONT_NAME}
|
||||
HASH ${UNIFONT_MD5}
|
||||
URL
|
||||
"${OPENCV_UNIFONT_URL}"
|
||||
"${UNIFONT_URL}"
|
||||
DESTINATION_DIR "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
ID UNIFONT
|
||||
STATUS res
|
||||
RELATIVE_URL)
|
||||
|
||||
if (res)
|
||||
message(STATUS "Unicode font has been downloaded successfully.")
|
||||
set(HAVE_UNIFONT ON CACHE INTERNAL "")
|
||||
else()
|
||||
message(STATUS "Unicode font download failed. Turning it off.")
|
||||
set(HAVE_UNIFONT OFF CACHE INTERNAL "")
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_UNIFONT OFF CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
ocv_blob2hdr("${CMAKE_CURRENT_SOURCE_DIR}/fonts/Rubik.ttf.gz" "${CMAKE_CURRENT_BINARY_DIR}/builtin_font_sans.h" OcvBuiltinFontSans)
|
||||
ocv_blob2hdr("${CMAKE_CURRENT_SOURCE_DIR}/fonts/Rubik-Italic.ttf.gz" "${CMAKE_CURRENT_BINARY_DIR}/builtin_font_italic.h" OcvBuiltinFontItalic)
|
||||
if (HAVE_UNIFONT)
|
||||
ocv_blob2hdr("${CMAKE_CURRENT_BINARY_DIR}/${UNIFONT_NAME}" "${CMAKE_CURRENT_BINARY_DIR}/builtin_font_uni.h" OcvBuiltinFontUni)
|
||||
endif()
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
ocv_target_link_libraries(${the_module} LINK_PRIVATE ${ZLIB_LIBRARIES})
|
||||
ocv_install_3rdparty_licenses(fonts fonts/Rubik_OFL.txt)
|
||||
|
BIN
modules/imgproc/fonts/Rubik-Italic.ttf.gz
Normal file
BIN
modules/imgproc/fonts/Rubik-Italic.ttf.gz
Normal file
Binary file not shown.
BIN
modules/imgproc/fonts/Rubik.ttf.gz
Normal file
BIN
modules/imgproc/fonts/Rubik.ttf.gz
Normal file
Binary file not shown.
93
modules/imgproc/fonts/Rubik_OFL.txt
Normal file
93
modules/imgproc/fonts/Rubik_OFL.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright 2015 The Rubik Project Authors (https://github.com/googlefonts/rubik),
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
@ -4631,6 +4631,113 @@ CV_EXPORTS_W double getFontScaleFromHeight(const int fontFace,
|
||||
const int pixelHeight,
|
||||
const int thickness = 1);
|
||||
|
||||
/** @brief Wrapper on top of a truetype/opentype/etc font, i.e. Freetype's FT_Face.
|
||||
|
||||
The class is used to store the loaded fonts;
|
||||
the font can then be passed to the functions
|
||||
putText and getTextSize.
|
||||
*/
|
||||
class CV_EXPORTS_W_SIMPLE FontFace
|
||||
{
|
||||
public:
|
||||
/** @brief loads default font */
|
||||
CV_WRAP FontFace();
|
||||
/** @brief
|
||||
loads font at the specified path or with specified name.
|
||||
Empty fontPathOrName means the default embedded font.
|
||||
*/
|
||||
CV_WRAP FontFace(const String& fontPathOrName);
|
||||
|
||||
~FontFace();
|
||||
|
||||
/** @brief loads new font face */
|
||||
CV_WRAP bool set(const String& fontPathOrName);
|
||||
CV_WRAP String getName() const;
|
||||
|
||||
/** @brief sets the current variable font instance.
|
||||
@param params The list of pairs key1, value1, key2, value2, ..., e.g.
|
||||
`myfont.setInstance({CV_FOURCC('w','g','h','t'), 400<<16, CV_FOURCC('s','l','n','t'), -(15<<16)});`
|
||||
Note that the parameter values are specified in 16.16 fixed-point format, that is, integer values
|
||||
need to be shifted by 16 (or multiplied by 65536).
|
||||
*/
|
||||
CV_WRAP bool setInstance(const std::vector<int>& params);
|
||||
CV_WRAP bool getInstance(CV_OUT std::vector<int>& params) const;
|
||||
|
||||
struct Impl;
|
||||
|
||||
Impl* operator -> ();
|
||||
static bool getBuiltinFontData(const String& fontName, const uchar*& data, size_t& datasize);
|
||||
|
||||
protected:
|
||||
Ptr<Impl> impl;
|
||||
};
|
||||
|
||||
/** @brief Defines various put text flags */
|
||||
enum PutTextFlags
|
||||
{
|
||||
PUT_TEXT_ALIGN_LEFT=0, // put the text to the right from the origin
|
||||
PUT_TEXT_ALIGN_CENTER=1,// center the text at the origin; not implemented yet
|
||||
PUT_TEXT_ALIGN_RIGHT=2, // put the text to the left of the origin
|
||||
PUT_TEXT_ALIGN_MASK=3, // alignment mask
|
||||
PUT_TEXT_ORIGIN_TL=0,
|
||||
PUT_TEXT_ORIGIN_BL=32, // treat the target image as having bottom-left origin
|
||||
PUT_TEXT_WRAP=128 // wrap text to the next line if it does not fit
|
||||
};
|
||||
|
||||
/** @brief Draws a text string using specified font.
|
||||
|
||||
The function cv::putText renders the specified text string in the image. Symbols that cannot be rendered
|
||||
using the specified font are replaced by question marks. See #getTextSize for a text rendering code
|
||||
example. The function returns the coordinates in pixels from where the text can be continued.
|
||||
|
||||
@param img Image.
|
||||
@param text Text string to be drawn.
|
||||
@param org Bottom-left corner of the first character of the printed text
|
||||
(see PUT_TEXT_ALIGN_... though)
|
||||
@param color Text color.
|
||||
@param fface The font to use for the text
|
||||
@param size Font size in pixels (by default) or pts
|
||||
@param weight Font weight, 100..1000,
|
||||
where 100 is "thin" font, 400 is "regular",
|
||||
600 is "semibold", 800 is "bold" and beyond that is "black".
|
||||
The parameter is ignored if the font is not a variable font or if it does not provide variation along 'wght' axis.
|
||||
If the weight is 0, then the weight, currently set via setInstance(), is used.
|
||||
@param flags Various flags, see PUT_TEXT_...
|
||||
@param wrap The optional text wrapping range:
|
||||
In the case of left-to-right (LTR) text if the printed character would cross wrap.end boundary,
|
||||
the "cursor" is set to wrap.start.
|
||||
In the case of right-to-left (RTL) text it's vice versa.
|
||||
If the parameters is not set,
|
||||
[org.x, img.cols] is used for LTR text and
|
||||
[0, org.x] is for RTL one.
|
||||
*/
|
||||
CV_EXPORTS_W Point putText( InputOutputArray img, const String& text, Point org,
|
||||
Scalar color, FontFace& fface, int size, int weight=0,
|
||||
PutTextFlags flags=PUT_TEXT_ALIGN_LEFT, Range wrap=Range() );
|
||||
|
||||
/** @brief Calculates the bounding rect for the text
|
||||
|
||||
The function cv::getTextSize calculates and returns the size of a box that contains the specified text.
|
||||
That is, the following code renders some text, the tight box surrounding it, and the baseline: :
|
||||
|
||||
@param imgsize Size of the target image, can be empty
|
||||
@param text Text string to be drawn.
|
||||
@param org Bottom-left corner of the first character of the printed text
|
||||
(see PUT_TEXT_ALIGN_... though)
|
||||
@param fface The font to use for the text
|
||||
@param size Font size in pixels (by default) or pts
|
||||
@param weight Font weight, 100..1000,
|
||||
where 100 is "thin" font, 400 is "regular",
|
||||
600 is "semibold", 800 is "bold" and beyond that is "black".
|
||||
The default weight means "400" for variable-weight fonts or
|
||||
whatever "default" weight the used font provides.
|
||||
@param flags Various flags, see PUT_TEXT_...
|
||||
@param wrap The optional text wrapping range; see #putText.
|
||||
*/
|
||||
CV_EXPORTS_W Rect getTextSize( Size imgsize, const String& text, Point org,
|
||||
FontFace& fface, int size, int weight=0,
|
||||
PutTextFlags flags=PUT_TEXT_ALIGN_LEFT, Range wrap=Range() );
|
||||
|
||||
/** @brief Line iterator
|
||||
|
||||
The class is used to iterate over all the pixels on the raster line
|
||||
|
@ -1814,13 +1814,14 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
double fontScale = 2;
|
||||
int thickness = 3;
|
||||
int baseLine[] = new int[1];
|
||||
double EPS=5.0;
|
||||
|
||||
Imgproc.getTextSize(text, Imgproc.FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, thickness, null);
|
||||
Size res = Imgproc.getTextSize(text, Imgproc.FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, thickness, baseLine);
|
||||
|
||||
assertEquals(543.0, res.width);
|
||||
assertEquals(44.0, res.height);
|
||||
assertEquals(20, baseLine[0]);
|
||||
assertEquals(494.0, res.width, EPS);
|
||||
assertEquals(51.0, res.height, EPS);
|
||||
assertEquals(10, baseLine[0], 2.0);
|
||||
}
|
||||
|
||||
public void testCircleMatPointIntScalar() {
|
||||
@ -2032,7 +2033,7 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
|
||||
public void testPutTextMatStringPointIntDoubleScalar() {
|
||||
String text = "Hello World";
|
||||
Size labelSize = new Size(175, 22);
|
||||
Size labelSize = new Size(170, 23);
|
||||
Mat img = new Mat(20 + (int) labelSize.height, 20 + (int) labelSize.width, CvType.CV_8U, colorBlack);
|
||||
Point origin = new Point(10, labelSize.height + 10);
|
||||
|
||||
@ -2040,13 +2041,13 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
|
||||
assertTrue(Core.countNonZero(img) > 0);
|
||||
// check that border is not corrupted
|
||||
Imgproc.rectangle(img, new Point(11, 11), new Point(labelSize.width + 10, labelSize.height + 10), colorBlack, Imgproc.FILLED);
|
||||
Imgproc.rectangle(img, new Point(10, 10), new Point(labelSize.width + 10, labelSize.height + 10), colorBlack, Imgproc.FILLED);
|
||||
assertEquals(0, Core.countNonZero(img));
|
||||
}
|
||||
|
||||
public void testPutTextMatStringPointIntDoubleScalarInt() {
|
||||
String text = "Hello World";
|
||||
Size labelSize = new Size(176, 22);
|
||||
Size labelSize = new Size(170, 23);
|
||||
Mat img = new Mat(20 + (int) labelSize.height, 20 + (int) labelSize.width, CvType.CV_8U, colorBlack);
|
||||
Point origin = new Point(10, labelSize.height + 10);
|
||||
|
||||
@ -2060,7 +2061,7 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
|
||||
public void testPutTextMatStringPointIntDoubleScalarIntIntBoolean() {
|
||||
String text = "Hello World";
|
||||
Size labelSize = new Size(175, 22);
|
||||
Size labelSize = new Size(170, 23);
|
||||
|
||||
Mat img = new Mat(20 + (int) labelSize.height, 20 + (int) labelSize.width, CvType.CV_8U, colorBlack);
|
||||
Point origin = new Point(10, 10);
|
||||
@ -2069,7 +2070,7 @@ public class ImgprocTest extends OpenCVTestCase {
|
||||
|
||||
assertTrue(Core.countNonZero(img) > 0);
|
||||
// check that border is not corrupted
|
||||
Imgproc.rectangle(img, new Point(10, 10), new Point(labelSize.width + 9, labelSize.height + 9), colorBlack, Imgproc.FILLED);
|
||||
Imgproc.rectangle(img, new Point(10, 10), new Point(labelSize.width + 10, labelSize.height + 10), colorBlack, Imgproc.FILLED);
|
||||
assertEquals(0, Core.countNonZero(img));
|
||||
}
|
||||
}
|
||||
|
38
modules/imgproc/misc/objc/common/FontFace.h
Normal file
38
modules/imgproc/misc/objc/common/FontFace.h
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// FontFace.h
|
||||
//
|
||||
// Created by VP in 2020
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
#import "opencv.hpp"
|
||||
#else
|
||||
#define CV_EXPORTS
|
||||
#endif
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
CV_EXPORTS @interface FontFace : NSObject
|
||||
|
||||
@property(readonly) NSString* name;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@property(readonly) cv::FontFace& nativeRef;
|
||||
#endif
|
||||
|
||||
-(instancetype)initWith:(const NSString*)name;
|
||||
-(instancetype)init;
|
||||
|
||||
#ifdef __cplusplus
|
||||
+(instancetype)fromNative:(cv::FontFace&)fface;
|
||||
#endif
|
||||
|
||||
-(NSString *)description;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
43
modules/imgproc/misc/objc/common/FontFace.mm
Normal file
43
modules/imgproc/misc/objc/common/FontFace.mm
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// FontFace.mm
|
||||
//
|
||||
// Created by VP in 2020.
|
||||
//
|
||||
|
||||
#import "FontFace.h"
|
||||
|
||||
@implementation FontFace {
|
||||
cv::FontFace native;
|
||||
}
|
||||
|
||||
-(cv::FontFace&)nativeRef {
|
||||
return native;
|
||||
}
|
||||
|
||||
- (NSString*)name {
|
||||
return [NSString stringWithUTF8String:native.getName().c_str()];
|
||||
}
|
||||
|
||||
-(instancetype)init {
|
||||
return [super init];
|
||||
}
|
||||
|
||||
-(instancetype)initWith:(NSString*)name {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.nativeRef.set(std::string(name.UTF8String));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+(instancetype)fromNative:(cv::FontFace&)fface {
|
||||
FontFace* ff = [[FontFace alloc] init];
|
||||
ff.nativeRef = fface;
|
||||
return ff;
|
||||
}
|
||||
|
||||
- (NSString *)description {
|
||||
return [NSString stringWithFormat:@"FontFace [name=%s]", self.nativeRef.getName().c_str()];
|
||||
}
|
||||
|
||||
@end
|
@ -1,4 +1,7 @@
|
||||
{
|
||||
"class_ignore_list": [
|
||||
"FontFace"
|
||||
],
|
||||
"enum_ignore_list" : [
|
||||
"MorphShapes_c",
|
||||
"SmoothMethod_c"
|
||||
@ -125,5 +128,12 @@
|
||||
"Subdiv2D" : {
|
||||
"(void)insert:(NSArray<Point2f*>*)ptvec" : { "insert" : {"name" : "insertVector"} }
|
||||
}
|
||||
},
|
||||
"type_dict": {
|
||||
"FontFace": {
|
||||
"objc_type": "FontFace*",
|
||||
"to_cpp": "%(n)s.nativeRef",
|
||||
"from_cpp": "[FontFace fromNative:%(n)s]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1490,13 +1490,14 @@ class ImgprocTest: OpenCVTestCase {
|
||||
let fontScale:Int32 = 2
|
||||
let thickness:Int32 = 3
|
||||
var baseLine:Int32 = 0
|
||||
let EPS = 0.0
|
||||
|
||||
Imgproc.getTextSize(text: text, fontFace: .FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale: Double(fontScale), thickness: thickness, baseLine: &baseLine)
|
||||
let res = Imgproc.getTextSize(text: text, fontFace: .FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale: Double(fontScale), thickness: thickness, baseLine: &baseLine)
|
||||
|
||||
XCTAssertEqual(431, res.width)
|
||||
XCTAssertEqual(44, res.height)
|
||||
XCTAssertEqual(20, baseLine)
|
||||
XCTAssertEqual(454, res.width, accuracy:EPS)
|
||||
XCTAssertEqual(51, res.height, accuracy:EPS)
|
||||
XCTAssertEqual(10, baseLine, accuracy:2.0)
|
||||
}
|
||||
|
||||
func testCircleMatPointIntScalar() {
|
||||
@ -1700,7 +1701,7 @@ class ImgprocTest: OpenCVTestCase {
|
||||
|
||||
func testPutTextMatStringPointIntDoubleScalar() {
|
||||
let text = "Hello World"
|
||||
let labelSize = Size(width: 175, height: 22)
|
||||
let labelSize = Size(width: 170, height: 23)
|
||||
let img = Mat(rows: 20 + labelSize.height, cols: 20 + labelSize.width, type: CvType.CV_8U, scalar: colorBlack)
|
||||
let origin = Point(x: 10, y: labelSize.height + 10)
|
||||
|
||||
@ -1708,13 +1709,13 @@ class ImgprocTest: OpenCVTestCase {
|
||||
|
||||
XCTAssert(Core.countNonZero(src: img) > 0)
|
||||
// check that border is not corrupted
|
||||
Imgproc.rectangle(img: img, pt1: Point(x: 11, y: 11), pt2: Point(x: labelSize.width + 10, y: labelSize.height + 10), color: colorBlack, thickness: Core.FILLED)
|
||||
Imgproc.rectangle(img: img, pt1: Point(x: 10, y: 10), pt2: Point(x: labelSize.width + 10, y: labelSize.height + 10), color: colorBlack, thickness: Core.FILLED)
|
||||
XCTAssertEqual(0, Core.countNonZero(src: img))
|
||||
}
|
||||
|
||||
func testPutTextMatStringPointIntDoubleScalarInt() {
|
||||
let text = "Hello World"
|
||||
let labelSize = Size(width: 176, height: 22)
|
||||
let labelSize = Size(width: 170, height: 23)
|
||||
let img = Mat(rows: 20 + labelSize.height, cols: 20 + labelSize.width, type: CvType.CV_8U, scalar: colorBlack)
|
||||
let origin = Point(x: 10, y: labelSize.height + 10)
|
||||
|
||||
@ -1728,7 +1729,7 @@ class ImgprocTest: OpenCVTestCase {
|
||||
|
||||
func testPutTextMatStringPointIntDoubleScalarIntIntBoolean() {
|
||||
let text = "Hello World"
|
||||
let labelSize = Size(width: 175, height: 22)
|
||||
let labelSize = Size(width: 170, height: 23)
|
||||
|
||||
let img = Mat(rows: 20 + labelSize.height, cols: 20 + labelSize.width, type: CvType.CV_8U, scalar: colorBlack)
|
||||
let origin = Point(x: 10, y: 10)
|
||||
|
@ -2037,331 +2037,6 @@ void polylines( InputOutputArray _img, const Point* const* pts, const int* npts,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum { FONT_SIZE_SHIFT=8, FONT_ITALIC_ALPHA=(1 << 8),
|
||||
FONT_ITALIC_DIGIT=(2 << 8), FONT_ITALIC_PUNCT=(4 << 8),
|
||||
FONT_ITALIC_BRACES=(8 << 8), FONT_HAVE_GREEK=(16 << 8),
|
||||
FONT_HAVE_CYRILLIC=(32 << 8) };
|
||||
|
||||
static const int HersheyPlain[] = {
|
||||
(5 + 4*16) + FONT_HAVE_GREEK,
|
||||
199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
|
||||
200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
|
||||
215, 190, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 193, 84,
|
||||
194, 85, 86, 87, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
||||
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
|
||||
195, 223, 196, 88 };
|
||||
|
||||
static const int HersheyPlainItalic[] = {
|
||||
(5 + 4*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
|
||||
199, 214, 217, 233, 219, 197, 234, 216, 221, 222, 228, 225, 211, 224, 210, 220,
|
||||
200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 212, 213, 191, 226, 192,
|
||||
215, 190, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 193, 84,
|
||||
194, 85, 86, 87, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161,
|
||||
162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176,
|
||||
195, 223, 196, 88 };
|
||||
|
||||
static const int HersheyComplexSmall[] = {
|
||||
(6 + 7*16) + FONT_HAVE_GREEK,
|
||||
1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
|
||||
1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 2213, 1241, 1238, 1242,
|
||||
1215, 1273, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013,
|
||||
1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1223, 1084,
|
||||
1224, 1247, 586, 1249, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111,
|
||||
1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126,
|
||||
1225, 1229, 1226, 1246 };
|
||||
|
||||
static const int HersheyComplexSmallItalic[] = {
|
||||
(6 + 7*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
|
||||
1199, 1214, 1217, 1275, 1274, 1271, 1272, 1216, 1221, 1222, 1219, 1232, 1211, 1231, 1210, 1220,
|
||||
1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1212, 1213, 1241, 1238, 1242,
|
||||
1215, 1273, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
|
||||
1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1223, 1084,
|
||||
1224, 1247, 586, 1249, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161,
|
||||
1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176,
|
||||
1225, 1229, 1226, 1246 };
|
||||
|
||||
static const int HersheySimplex[] = {
|
||||
(9 + 12*16) + FONT_HAVE_GREEK,
|
||||
2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
|
||||
700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
|
||||
715, 690, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513,
|
||||
514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 693, 584,
|
||||
694, 2247, 586, 2249, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611,
|
||||
612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626,
|
||||
695, 723, 696, 2246 };
|
||||
|
||||
static const int HersheyDuplex[] = {
|
||||
(9 + 12*16) + FONT_HAVE_GREEK,
|
||||
2199, 2714, 2728, 2732, 2719, 2733, 2718, 2727, 2721, 2722, 2723, 2725, 2711, 2724, 2710, 2720,
|
||||
2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2712, 2713, 2730, 2726, 2731,
|
||||
2715, 2734, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513,
|
||||
2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2223, 2084,
|
||||
2224, 2247, 587, 2249, 2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611,
|
||||
2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619, 2620, 2621, 2622, 2623, 2624, 2625, 2626,
|
||||
2225, 2229, 2226, 2246 };
|
||||
|
||||
static const int HersheyComplex[] = {
|
||||
(9 + 12*16) + FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC,
|
||||
2199, 2214, 2217, 2275, 2274, 2271, 2272, 2216, 2221, 2222, 2219, 2232, 2211, 2231, 2210, 2220,
|
||||
2200, 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2212, 2213, 2241, 2238, 2242,
|
||||
2215, 2273, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
|
||||
2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2223, 2084,
|
||||
2224, 2247, 587, 2249, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111,
|
||||
2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126,
|
||||
2225, 2229, 2226, 2246, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811,
|
||||
2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826,
|
||||
2827, 2828, 2829, 2830, 2831, 2832, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909,
|
||||
2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924,
|
||||
2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932};
|
||||
|
||||
static const int HersheyComplexItalic[] = {
|
||||
(9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT +
|
||||
FONT_HAVE_GREEK + FONT_HAVE_CYRILLIC,
|
||||
2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
|
||||
2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
|
||||
2765, 2273, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063,
|
||||
2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2223, 2084,
|
||||
2224, 2247, 587, 2249, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160, 2161,
|
||||
2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176,
|
||||
2225, 2229, 2226, 2246 };
|
||||
|
||||
static const int HersheyTriplex[] = {
|
||||
(9 + 12*16) + FONT_HAVE_GREEK,
|
||||
2199, 3214, 3228, 3232, 3219, 3233, 3218, 3227, 3221, 3222, 3223, 3225, 3211, 3224, 3210, 3220,
|
||||
3200, 3201, 3202, 3203, 3204, 3205, 3206, 3207, 3208, 3209, 3212, 3213, 3230, 3226, 3231,
|
||||
3215, 3234, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3008, 3009, 3010, 3011, 3012, 3013,
|
||||
2014, 3015, 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023, 3024, 3025, 3026, 2223, 2084,
|
||||
2224, 2247, 587, 2249, 3101, 3102, 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110, 3111,
|
||||
3112, 3113, 3114, 3115, 3116, 3117, 3118, 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126,
|
||||
2225, 2229, 2226, 2246 };
|
||||
|
||||
static const int HersheyTriplexItalic[] = {
|
||||
(9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT +
|
||||
FONT_ITALIC_PUNCT + FONT_HAVE_GREEK,
|
||||
2199, 3264, 3278, 3282, 3269, 3233, 3268, 3277, 3271, 3272, 3223, 3225, 3261, 3224, 3260, 3270,
|
||||
3250, 3251, 3252, 3253, 3254, 3255, 3256, 3257, 3258, 3259, 3262, 3263, 3230, 3226, 3231,
|
||||
3265, 3234, 3051, 3052, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063,
|
||||
2064, 3065, 3066, 3067, 3068, 3069, 3070, 3071, 3072, 3073, 3074, 3075, 3076, 2223, 2084,
|
||||
2224, 2247, 587, 2249, 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158, 3159, 3160, 3161,
|
||||
3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3175, 3176,
|
||||
2225, 2229, 2226, 2246 };
|
||||
|
||||
static const int HersheyScriptSimplex[] = {
|
||||
(9 + 12*16) + FONT_ITALIC_ALPHA + FONT_HAVE_GREEK,
|
||||
2199, 714, 717, 733, 719, 697, 734, 716, 721, 722, 728, 725, 711, 724, 710, 720,
|
||||
700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 712, 713, 691, 726, 692,
|
||||
715, 690, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
|
||||
564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 693, 584,
|
||||
694, 2247, 586, 2249, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661,
|
||||
662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676,
|
||||
695, 723, 696, 2246 };
|
||||
|
||||
static const int HersheyScriptComplex[] = {
|
||||
(9 + 12*16) + FONT_ITALIC_ALPHA + FONT_ITALIC_DIGIT + FONT_ITALIC_PUNCT + FONT_HAVE_GREEK,
|
||||
2199, 2764, 2778, 2782, 2769, 2783, 2768, 2777, 2771, 2772, 2219, 2232, 2211, 2231, 2210, 2220,
|
||||
2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2212, 2213, 2241, 2238, 2242,
|
||||
2215, 2273, 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563,
|
||||
2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571, 2572, 2573, 2574, 2575, 2576, 2223, 2084,
|
||||
2224, 2247, 586, 2249, 2651, 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659, 2660, 2661,
|
||||
2662, 2663, 2664, 2665, 2666, 2667, 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675, 2676,
|
||||
2225, 2229, 2226, 2246 };
|
||||
|
||||
|
||||
static const int* getFontData(int fontFace)
|
||||
{
|
||||
bool isItalic = (fontFace & FONT_ITALIC) != 0;
|
||||
const int* ascii = 0;
|
||||
|
||||
switch( fontFace & 15 )
|
||||
{
|
||||
case FONT_HERSHEY_SIMPLEX:
|
||||
ascii = HersheySimplex;
|
||||
break;
|
||||
case FONT_HERSHEY_PLAIN:
|
||||
ascii = !isItalic ? HersheyPlain : HersheyPlainItalic;
|
||||
break;
|
||||
case FONT_HERSHEY_DUPLEX:
|
||||
ascii = HersheyDuplex;
|
||||
break;
|
||||
case FONT_HERSHEY_COMPLEX:
|
||||
ascii = !isItalic ? HersheyComplex : HersheyComplexItalic;
|
||||
break;
|
||||
case FONT_HERSHEY_TRIPLEX:
|
||||
ascii = !isItalic ? HersheyTriplex : HersheyTriplexItalic;
|
||||
break;
|
||||
case FONT_HERSHEY_COMPLEX_SMALL:
|
||||
ascii = !isItalic ? HersheyComplexSmall : HersheyComplexSmallItalic;
|
||||
break;
|
||||
case FONT_HERSHEY_SCRIPT_SIMPLEX:
|
||||
ascii = HersheyScriptSimplex;
|
||||
break;
|
||||
case FONT_HERSHEY_SCRIPT_COMPLEX:
|
||||
ascii = HersheyScriptComplex;
|
||||
break;
|
||||
default:
|
||||
CV_Error( CV_StsOutOfRange, "Unknown font type" );
|
||||
}
|
||||
return ascii;
|
||||
}
|
||||
|
||||
inline void readCheck(int &c, int &i, const String &text, int fontFace)
|
||||
{
|
||||
|
||||
int leftBoundary = ' ', rightBoundary = 127;
|
||||
|
||||
if(c >= 0x80 && fontFace == FONT_HERSHEY_COMPLEX)
|
||||
{
|
||||
if(c == 0xD0 && (uchar)text[i + 1] >= 0x90 && (uchar)text[i + 1] <= 0xBF)
|
||||
{
|
||||
c = (uchar)text[++i] - 17;
|
||||
leftBoundary = 127;
|
||||
rightBoundary = 175;
|
||||
}
|
||||
else if(c == 0xD1 && (uchar)text[i + 1] >= 0x80 && (uchar)text[i + 1] <= 0x8F)
|
||||
{
|
||||
c = (uchar)text[++i] + 47;
|
||||
leftBoundary = 175;
|
||||
rightBoundary = 191;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(c >= 0xC0 && text[i+1] != 0) //2 bytes utf
|
||||
i++;
|
||||
|
||||
if(c >= 0xE0 && text[i+1] != 0) //3 bytes utf
|
||||
i++;
|
||||
|
||||
if(c >= 0xF0 && text[i+1] != 0) //4 bytes utf
|
||||
i++;
|
||||
|
||||
if(c >= 0xF8 && text[i+1] != 0) //5 bytes utf
|
||||
i++;
|
||||
|
||||
if(c >= 0xFC && text[i+1] != 0) //6 bytes utf
|
||||
i++;
|
||||
|
||||
c = '?';
|
||||
}
|
||||
}
|
||||
|
||||
if(c >= rightBoundary || c < leftBoundary)
|
||||
c = '?';
|
||||
}
|
||||
|
||||
extern const char* g_HersheyGlyphs[];
|
||||
|
||||
void putText( InputOutputArray _img, const String& text, Point org,
|
||||
int fontFace, double fontScale, Scalar color,
|
||||
int thickness, int line_type, bool bottomLeftOrigin )
|
||||
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
if ( text.empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
Mat img = _img.getMat();
|
||||
const int* ascii = getFontData(fontFace);
|
||||
|
||||
double buf[4];
|
||||
scalarToRawData(color, buf, img.type(), 0);
|
||||
|
||||
int base_line = -(ascii[0] & 15);
|
||||
int hscale = cvRound(fontScale*XY_ONE), vscale = hscale;
|
||||
|
||||
if( line_type == CV_AA && img.depth() != CV_8U )
|
||||
line_type = 8;
|
||||
|
||||
if( bottomLeftOrigin )
|
||||
vscale = -vscale;
|
||||
|
||||
int64 view_x = (int64)org.x << XY_SHIFT;
|
||||
int64 view_y = ((int64)org.y << XY_SHIFT) + base_line*vscale;
|
||||
std::vector<Point2l> pts;
|
||||
pts.reserve(1 << 10);
|
||||
const char **faces = cv::g_HersheyGlyphs;
|
||||
|
||||
for( int i = 0; i < (int)text.size(); i++ )
|
||||
{
|
||||
int c = (uchar)text[i];
|
||||
Point2l p;
|
||||
|
||||
readCheck(c, i, text, fontFace);
|
||||
|
||||
const char* ptr = faces[ascii[(c-' ')+1]];
|
||||
p.x = (uchar)ptr[0] - 'R';
|
||||
p.y = (uchar)ptr[1] - 'R';
|
||||
int64 dx = p.y*hscale;
|
||||
view_x -= p.x*hscale;
|
||||
pts.resize(0);
|
||||
|
||||
for( ptr += 2;; )
|
||||
{
|
||||
if( *ptr == ' ' || !*ptr )
|
||||
{
|
||||
if( pts.size() > 1 )
|
||||
PolyLine( img, &pts[0], (int)pts.size(), false, buf, thickness, line_type, XY_SHIFT );
|
||||
if( !*ptr++ )
|
||||
break;
|
||||
pts.resize(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.x = (uchar)ptr[0] - 'R';
|
||||
p.y = (uchar)ptr[1] - 'R';
|
||||
ptr += 2;
|
||||
pts.push_back(Point2l(p.x*hscale + view_x, p.y*vscale + view_y));
|
||||
}
|
||||
}
|
||||
view_x += dx;
|
||||
}
|
||||
}
|
||||
|
||||
Size getTextSize( const String& text, int fontFace, double fontScale, int thickness, int* _base_line)
|
||||
{
|
||||
Size size;
|
||||
double view_x = 0;
|
||||
const char **faces = cv::g_HersheyGlyphs;
|
||||
const int* ascii = getFontData(fontFace);
|
||||
|
||||
int base_line = (ascii[0] & 15);
|
||||
int cap_line = (ascii[0] >> 4) & 15;
|
||||
size.height = cvRound((cap_line + base_line)*fontScale + (thickness+1)/2);
|
||||
|
||||
for( int i = 0; i < (int)text.size(); i++ )
|
||||
{
|
||||
int c = (uchar)text[i];
|
||||
Point p;
|
||||
|
||||
readCheck(c, i, text, fontFace);
|
||||
|
||||
const char* ptr = faces[ascii[(c-' ')+1]];
|
||||
p.x = (uchar)ptr[0] - 'R';
|
||||
p.y = (uchar)ptr[1] - 'R';
|
||||
view_x += (p.y - p.x)*fontScale;
|
||||
}
|
||||
|
||||
size.width = cvRound(view_x + thickness);
|
||||
if( _base_line )
|
||||
*_base_line = cvRound(base_line*fontScale + thickness*0.5);
|
||||
return size;
|
||||
}
|
||||
|
||||
double getFontScaleFromHeight(const int fontFace, const int pixelHeight, const int thickness)
|
||||
{
|
||||
// By https://stackoverflow.com/a/27898487/1531708
|
||||
const int* ascii = getFontData(fontFace);
|
||||
|
||||
int base_line = (ascii[0] & 15);
|
||||
int cap_line = (ascii[0] >> 4) & 15;
|
||||
|
||||
return static_cast<double>(pixelHeight - static_cast<double>((thickness + 1)) / 2.0) / static_cast<double>(cap_line + base_line);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cv::fillConvexPoly(InputOutputArray img, InputArray _points,
|
||||
@ -2861,7 +2536,7 @@ cvInitFont( CvFont *font, int font_face, double hscale, double vscale,
|
||||
{
|
||||
CV_Assert( font != 0 && hscale > 0 && vscale > 0 && thickness >= 0 );
|
||||
|
||||
font->ascii = cv::getFontData(font_face);
|
||||
font->ascii = 0;
|
||||
font->font_face = font_face;
|
||||
font->hscale = (float)hscale;
|
||||
font->vscale = (float)vscale;
|
||||
|
1547
modules/imgproc/src/drawing_text.cpp
Normal file
1547
modules/imgproc/src/drawing_text.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
4864
modules/imgproc/src/stb_truetype.cpp
Normal file
4864
modules/imgproc/src/stb_truetype.cpp
Normal file
File diff suppressed because it is too large
Load Diff
692
modules/imgproc/src/stb_truetype.hpp
Normal file
692
modules/imgproc/src/stb_truetype.hpp
Normal file
@ -0,0 +1,692 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
// This is refactored (and split into 2 files) version of stb_truetype.h
|
||||
// from https://github.com/nothings/stb.
|
||||
// Support for variable fonts has been added and
|
||||
// a few other modifications & optimizations have been done.
|
||||
|
||||
//////////////// Below is the original copyright information /////////////////
|
||||
///////// (btw, OpenCV chooses the option A (MIT) for the license) ///////////
|
||||
|
||||
// Authored from 2009-2020 by Sean Barrett / RAD Game Tools.
|
||||
// See stb_truetype.cpp for the details
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
////
|
||||
//// INTERFACE
|
||||
////
|
||||
////
|
||||
|
||||
#ifndef __STB_INCLUDE_STB_TRUETYPE_HPP__
|
||||
#define __STB_INCLUDE_STB_TRUETYPE_HPP__
|
||||
|
||||
#if 0 //def STBTT_STATIC
|
||||
#define STBTT_DEF static
|
||||
#else
|
||||
#define STBTT_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define STBTT_FOURCC(a, b, c, d) \
|
||||
(unsigned)((((unsigned char)(a)) << 24) | \
|
||||
(((unsigned char)(b)) << 16) | \
|
||||
(((unsigned char)(c)) << 8) | \
|
||||
((unsigned char)(d)))
|
||||
|
||||
// private structure
|
||||
typedef struct
|
||||
{
|
||||
unsigned char *data;
|
||||
int cursor;
|
||||
int size;
|
||||
} stbtt__buf;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTURE BAKING API
|
||||
//
|
||||
// If you use this API, you only have to call two functions ever.
|
||||
//
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
|
||||
float xoff,yoff,xadvance;
|
||||
} stbtt_bakedchar;
|
||||
|
||||
STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
|
||||
float pixel_height, // height of font in pixels
|
||||
unsigned char *pixels, int pw, int ph, // bitmap to be filled in
|
||||
int first_char, int num_chars, // characters to bake
|
||||
stbtt_bakedchar *chardata); // you allocate this, it's num_chars long
|
||||
// if return is positive, the first unused row of the bitmap
|
||||
// if return is negative, returns the negative of the number of characters that fit
|
||||
// if return is 0, no characters fit and no rows were used
|
||||
// This uses a very crappy packing.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x0,y0,s0,t0; // top-left
|
||||
float x1,y1,s1,t1; // bottom-right
|
||||
} stbtt_aligned_quad;
|
||||
|
||||
STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above
|
||||
int char_index, // character to display
|
||||
float *xpos, float *ypos, // pointers to current position in screen pixel space
|
||||
stbtt_aligned_quad *q, // output: quad to draw
|
||||
int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier
|
||||
// Call GetBakedQuad with char_index = 'character - first_char', and it
|
||||
// creates the quad you need to draw and advances the current position.
|
||||
//
|
||||
// The coordinate system used assumes y increases downwards.
|
||||
//
|
||||
// Characters will extend both above and below the current position;
|
||||
// see discussion of "BASELINE" above.
|
||||
//
|
||||
// It's inefficient; you might want to c&p it and optimize it.
|
||||
|
||||
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap);
|
||||
// Query the font vertical metrics without having to create a font first.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// NEW TEXTURE BAKING API
|
||||
//
|
||||
// This provides options for packing multiple fonts into one atlas, not
|
||||
// perfectly but better than nothing.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
|
||||
float xoff,yoff,xadvance;
|
||||
float xoff2,yoff2;
|
||||
} stbtt_packedchar;
|
||||
|
||||
typedef struct stbtt_pack_context stbtt_pack_context;
|
||||
typedef struct stbtt_fontinfo stbtt_fontinfo;
|
||||
#ifndef STB_RECT_PACK_VERSION
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
#endif
|
||||
|
||||
STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context);
|
||||
// Initializes a packing context stored in the passed-in stbtt_pack_context.
|
||||
// Future calls using this context will pack characters into the bitmap passed
|
||||
// in here: a 1-channel bitmap that is width * height. stride_in_bytes is
|
||||
// the distance from one row to the next (or 0 to mean they are packed tightly
|
||||
// together). "padding" is the amount of padding to leave between each
|
||||
// character (normally you want '1' for bitmaps you'll use as textures with
|
||||
// bilinear filtering).
|
||||
//
|
||||
// Returns 0 on failure, 1 on success.
|
||||
|
||||
STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc);
|
||||
// Cleans up the packing context and frees all memory.
|
||||
|
||||
#define STBTT_POINT_SIZE(x) (-(x))
|
||||
|
||||
STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size,
|
||||
int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
|
||||
// Creates character bitmaps from the font_index'th font found in fontdata (use
|
||||
// font_index=0 if you don't know what that is). It creates num_chars_in_range
|
||||
// bitmaps for characters with unicode values starting at first_unicode_char_in_range
|
||||
// and increasing. Data for how to render them is stored in chardata_for_range;
|
||||
// pass these to stbtt_GetPackedQuad to get back renderable quads.
|
||||
//
|
||||
// font_size is the full height of the character from ascender to descender,
|
||||
// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed
|
||||
// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE()
|
||||
// and pass that result as 'font_size':
|
||||
// ..., 20 , ... // font max minus min y is 20 pixels tall
|
||||
// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float font_size;
|
||||
int first_unicode_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint
|
||||
int *array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints
|
||||
int num_chars;
|
||||
stbtt_packedchar *chardata_for_range; // output
|
||||
unsigned char h_oversample, v_oversample; // don't set these, they're used internally
|
||||
} stbtt_pack_range;
|
||||
|
||||
STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
|
||||
// Creates character bitmaps from multiple ranges of characters stored in
|
||||
// ranges. This will usually create a better-packed bitmap than multiple
|
||||
// calls to stbtt_PackFontRange. Note that you can call this multiple
|
||||
// times within a single PackBegin/PackEnd.
|
||||
|
||||
STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample);
|
||||
// Oversampling a font increases the quality by allowing higher-quality subpixel
|
||||
// positioning, and is especially valuable at smaller text sizes.
|
||||
//
|
||||
// This function sets the amount of oversampling for all following calls to
|
||||
// stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given
|
||||
// pack context. The default (no oversampling) is achieved by h_oversample=1
|
||||
// and v_oversample=1. The total number of pixels required is
|
||||
// h_oversample*v_oversample larger than the default; for example, 2x2
|
||||
// oversampling requires 4x the storage of 1x1. For best results, render
|
||||
// oversampled textures with bilinear filtering. Look at the readme in
|
||||
// stb/tests/oversample for information about oversampled fonts
|
||||
//
|
||||
// To use with PackFontRangesGather etc., you must set it before calls
|
||||
// call to PackFontRangesGatherRects.
|
||||
|
||||
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip);
|
||||
// If skip != 0, this tells stb_truetype to skip any codepoints for which
|
||||
// there is no corresponding glyph. If skip=0, which is the default, then
|
||||
// codepoints without a glyph recived the font's "missing character" glyph,
|
||||
// typically an empty box by convention.
|
||||
|
||||
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
|
||||
int char_index, // character to display
|
||||
float *xpos, float *ypos, // pointers to current position in screen pixel space
|
||||
stbtt_aligned_quad *q, // output: quad to draw
|
||||
int align_to_integer);
|
||||
|
||||
STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
|
||||
STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects);
|
||||
STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
|
||||
// Calling these functions in sequence is roughly equivalent to calling
|
||||
// stbtt_PackFontRanges(). If you more control over the packing of multiple
|
||||
// fonts, or if you want to pack custom data into a font texture, take a look
|
||||
// at the source to of stbtt_PackFontRanges() and create a custom version
|
||||
// using these functions, e.g. call GatherRects multiple times,
|
||||
// building up a single array of rects, then call PackRects once,
|
||||
// then call RenderIntoRects repeatedly. This may result in a
|
||||
// better packing than calling PackFontRanges multiple times
|
||||
// (or it may not).
|
||||
|
||||
// this is an opaque structure that you shouldn't mess with which holds
|
||||
// all the context needed from PackBegin to PackEnd.
|
||||
struct stbtt_pack_context {
|
||||
void *user_allocator_context;
|
||||
void *pack_info;
|
||||
int width;
|
||||
int height;
|
||||
int stride_in_bytes;
|
||||
int padding;
|
||||
int skip_missing;
|
||||
unsigned int h_oversample, v_oversample;
|
||||
unsigned char *pixels;
|
||||
void *nodes;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FONT LOADING
|
||||
//
|
||||
//
|
||||
|
||||
STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data);
|
||||
// This function will determine the number of fonts in a font file. TrueType
|
||||
// collection (.ttc) files may contain multiple fonts, while TrueType font
|
||||
// (.ttf) files only contain one font. The number of fonts can be used for
|
||||
// indexing with the previous function where the index is between zero and one
|
||||
// less than the total fonts. If an error occurs, -1 is returned.
|
||||
|
||||
STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
|
||||
// Each .ttf/.ttc file may have more than one font. Each font has a sequential
|
||||
// index number starting from 0. Call this function to get the font offset for
|
||||
// a given index; it returns -1 if the index is out of range. A regular .ttf
|
||||
// file will only define one font and it always be at offset 0, so it will
|
||||
// return '0' for index 0, and -1 for all other indices.
|
||||
|
||||
#ifndef STBTT_MAX_AXES
|
||||
#define STBTT_MAX_AXES 16
|
||||
#endif
|
||||
|
||||
typedef struct stbtt_axisinfo
|
||||
{
|
||||
int tag;
|
||||
int minval, defval, maxval;
|
||||
int currval;
|
||||
} stbtt_axisinfo;
|
||||
|
||||
// The following structure is defined publicly so you can declare one on
|
||||
// the stack or as a global or etc, but you should treat it as opaque.
|
||||
struct stbtt_fontinfo
|
||||
{
|
||||
void * userdata;
|
||||
unsigned char * data; // pointer to .ttf file
|
||||
unsigned char * dataend; // data + size
|
||||
int fontstart; // offset of start of font
|
||||
unsigned size; // the data buffer size
|
||||
|
||||
int numGlyphs; // number of glyphs, needed for range checking
|
||||
|
||||
int loca,head,glyf,hhea,hmtx,kern,gpos,svg,avar,fvar,gvar,hvar; // table locations as offset from start of .ttf
|
||||
int index_map; // a cmap mapping for our chosen character encoding
|
||||
int indexToLocFormat; // format needed to map from glyph index to glyph
|
||||
int axis_count; // the number of variable font axes
|
||||
stbtt_axisinfo axes[STBTT_MAX_AXES]; // information about each axis
|
||||
short axes_normvalues[STBTT_MAX_AXES]; // normalized (within [-1, 1]) coordinates of
|
||||
// the currently used variation. They are already transformed
|
||||
// using avar (if any)
|
||||
int gvar_shared_count; // the number of shared tuples, used by 'gvar'
|
||||
int gvar_shared_tuples; // offset of the shared tuples
|
||||
int gvar_glob_offset; // the global offset of glyph variations table
|
||||
int gvar_glyph_offsets; // the relative offsets of glyph variations
|
||||
int gvar_off_format; // true if offsets are 32-bit
|
||||
|
||||
stbtt__buf cff; // cff font data
|
||||
stbtt__buf charstrings; // the charstring index
|
||||
stbtt__buf gsubrs; // global charstring subroutines index
|
||||
stbtt__buf subrs; // private charstring subroutines index
|
||||
stbtt__buf fontdicts; // array of font dicts
|
||||
stbtt__buf fdselect; // map from glyph to fontdict
|
||||
};
|
||||
|
||||
|
||||
STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
|
||||
// Given an offset into the file that defines a font, this function builds
|
||||
// the necessary cached info for the rest of the system. You must allocate
|
||||
// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
|
||||
// need to do anything special to free it, because the contents are pure
|
||||
// value data with no additional data structures. Returns 0 on failure.
|
||||
|
||||
STBTT_DEF int stbtt_InitFont2(stbtt_fontinfo *info, const unsigned char *data, unsigned size, int offset);
|
||||
// Same as stbtt_InitFont, but also takes the size of "data" buffer,
|
||||
// in order to control and avoid out of range accesses.
|
||||
|
||||
STBTT_DEF stbtt_fontinfo* stbtt_CreateFont(const unsigned char *data, unsigned size, int offset);
|
||||
// Allocates font structure and initializes it. Returns 0 if there was an error.
|
||||
|
||||
STBTT_DEF void stbtt_ReleaseFont(stbtt_fontinfo **info);
|
||||
// Allocates font structure and initializes it. Returns 0 if there was an error.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHARACTER TO GLYPH-INDEX CONVERSIOn
|
||||
|
||||
STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint);
|
||||
// If you're going to perform multiple operations on the same character
|
||||
// and you want a speed-up, call this function with the character you're
|
||||
// going to process, then use glyph-based functions instead of the
|
||||
// codepoint-based functions.
|
||||
// Returns 0 if the character codepoint is not defined in the font.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHARACTER PROPERTIES
|
||||
//
|
||||
|
||||
STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels);
|
||||
// computes a scale factor to produce a font whose "height" is 'pixels' tall.
|
||||
// Height is measured as the distance from the highest ascender to the lowest
|
||||
// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics
|
||||
// and computing:
|
||||
// scale = pixels / (ascent - descent)
|
||||
// so if you prefer to measure height by the ascent only, use a similar calculation.
|
||||
|
||||
STBTT_DEF float stbtt_ScaleForPixelHeightNoDesc(const stbtt_fontinfo *info, float height);
|
||||
|
||||
STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels);
|
||||
// computes a scale factor to produce a font whose EM size is mapped to
|
||||
// 'pixels' tall. This is probably what traditional APIs compute, but
|
||||
// I'm not positive.
|
||||
|
||||
STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap);
|
||||
// ascent is the coordinate above the baseline the font extends; descent
|
||||
// is the coordinate below the baseline the font extends (i.e. it is typically negative)
|
||||
// lineGap is the spacing between one row's descent and the next row's ascent...
|
||||
// so you should advance the vertical position by "*ascent - *descent + *lineGap"
|
||||
// these are expressed in unscaled coordinates, so you must multiply by
|
||||
// the scale factor for a given size
|
||||
|
||||
STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap);
|
||||
// analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2
|
||||
// table (specific to MS/Windows TTF files).
|
||||
//
|
||||
// Returns 1 on success (table present), 0 on failure.
|
||||
|
||||
STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1);
|
||||
// the bounding box around all possible characters
|
||||
|
||||
STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing);
|
||||
// leftSideBearing is the offset from the current horizontal position to the left edge of the character
|
||||
// advanceWidth is the offset from the current horizontal position to the next horizontal position
|
||||
// these are expressed in unscaled coordinates
|
||||
|
||||
STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
|
||||
// an additional amount to add to the 'advance' value between ch1 and ch2
|
||||
|
||||
STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
|
||||
// Gets the bounding box of the visible part of the glyph, in unscaled coordinates
|
||||
|
||||
STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing);
|
||||
STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2);
|
||||
STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
|
||||
STBTT_DEF void stbtt__ScaleGlyphBox(int ix0, int iy0, int ix1, int iy1,
|
||||
float scale_x, float scale_y, float shift_x, float shift_y,
|
||||
int *out_ix0, int *out_iy0, int *out_ix1, int *out_iy1);
|
||||
// as above, but takes one or more glyph indices for greater efficiency
|
||||
|
||||
typedef struct stbtt_kerningentry
|
||||
{
|
||||
int glyph1; // use stbtt_FindGlyphIndex
|
||||
int glyph2;
|
||||
int advance;
|
||||
} stbtt_kerningentry;
|
||||
|
||||
STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info);
|
||||
STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length);
|
||||
// Retrieves a complete list of all of the kerning pairs provided by the font
|
||||
// stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write.
|
||||
// The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GLYPH SHAPES (you probably don't need these, but they have to go before
|
||||
// the bitmaps for C declaration-order reasons)
|
||||
//
|
||||
|
||||
#ifndef STBTT_vmove // you can predefine these to use different values (but why?)
|
||||
enum {
|
||||
STBTT_vmove=1,
|
||||
STBTT_vline,
|
||||
STBTT_vcurve,
|
||||
STBTT_vcubic
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef stbtt_vertex // you can predefine this to use different values
|
||||
// (we share this with other code at RAD)
|
||||
#define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
|
||||
typedef struct
|
||||
{
|
||||
stbtt_vertex_type x,y,cx,cy,cx1,cy1;
|
||||
unsigned char type,padding;
|
||||
} stbtt_vertex;
|
||||
#endif
|
||||
|
||||
STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index);
|
||||
// returns non-zero if nothing is drawn for this glyph
|
||||
|
||||
STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint,
|
||||
stbtt_vertex **vertices, int* ix0, int* iy0, int* ix1, int* iy1);
|
||||
STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices,
|
||||
int* ix0, int* iy0, int* ix1, int* iy1);
|
||||
// returns # of vertices and fills *vertices with the pointer to them
|
||||
// these are expressed in "unscaled" coordinates
|
||||
//
|
||||
// The shape is a series of contours. Each one starts with
|
||||
// a STBTT_moveto, then consists of a series of mixed
|
||||
// STBTT_lineto and STBTT_curveto segments. A lineto
|
||||
// draws a line from previous endpoint to its x,y; a curveto
|
||||
// draws a quadratic bezier from previous endpoint to
|
||||
// its x,y, using cx,cy as the bezier control point.
|
||||
|
||||
STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
|
||||
// frees the data allocated above
|
||||
|
||||
STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg);
|
||||
STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg);
|
||||
// fills svg with the character's SVG data.
|
||||
// returns data size or 0 if SVG not found.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FONT VARIATIONS
|
||||
//
|
||||
STBTT_DEF int stbtt_GetWeight(const stbtt_fontinfo* info);
|
||||
STBTT_DEF int stbtt_GetInstance(const stbtt_fontinfo* info, stbtt_axisinfo* axes, int max_count);
|
||||
STBTT_DEF int stbtt_SetInstance(stbtt_fontinfo* info, const int* params, int count, int reset_to_defaults);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BITMAP RENDERING
|
||||
//
|
||||
|
||||
STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
|
||||
// frees the bitmap allocated below
|
||||
|
||||
STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
|
||||
// get the bbox of the bitmap centered around the glyph origin; so the
|
||||
// bitmap width is ix1-ix0, height is iy1-iy0, and location to place
|
||||
// the bitmap top left is (leftSideBearing*scale,iy0).
|
||||
// (Note that the bitmap uses y-increases-down, but the shape uses
|
||||
// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
|
||||
|
||||
STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
|
||||
// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel
|
||||
// shift for the character
|
||||
|
||||
// the following functions are equivalent to the above functions, but operate
|
||||
// on glyph indices instead of Unicode codepoints (for efficiency)
|
||||
STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixelRealloc(const stbtt_fontinfo *info, float scale_x, float scale_y,
|
||||
float shift_x, float shift_y,
|
||||
int glyph, int *width, int *height, int* step,
|
||||
int *xoff, int *yoff, float* advx,
|
||||
unsigned char** buf, int* bufsize);
|
||||
STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph);
|
||||
STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph);
|
||||
STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int glyph);
|
||||
STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
|
||||
STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
|
||||
|
||||
|
||||
// @TODO: don't expose this structure
|
||||
typedef struct
|
||||
{
|
||||
int w,h,stride;
|
||||
unsigned char *pixels;
|
||||
} stbtt__bitmap;
|
||||
|
||||
// rasterize a shape with quadratic beziers into a bitmap
|
||||
STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into
|
||||
float flatness_in_pixels, // allowable error of curve in pixels
|
||||
stbtt_vertex *vertices, // array of vertices defining shape
|
||||
int num_verts, // number of vertices in above array
|
||||
float scale_x, float scale_y, // scale applied to input vertices
|
||||
float shift_x, float shift_y, // translation applied to input vertices
|
||||
int x_off, int y_off, // another translation applied to input
|
||||
int invert, // if non-zero, vertically flip shape
|
||||
void *userdata); // context for to STBTT_MALLOC
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Signed Distance Function (or Field) rendering
|
||||
|
||||
STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata);
|
||||
// frees the SDF bitmap allocated below
|
||||
|
||||
STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
|
||||
STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
|
||||
// These functions compute a discretized SDF field for a single character, suitable for storing
|
||||
// in a single-channel texture, sampling with bilinear filtering, and testing against
|
||||
// larger than some threshold to produce scalable fonts.
|
||||
// info -- the font
|
||||
// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
|
||||
// glyph/codepoint -- the character to generate the SDF for
|
||||
// padding -- extra "pixels" around the character which are filled with the distance to the character (not 0),
|
||||
// which allows effects like bit outlines
|
||||
// onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character)
|
||||
// pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale)
|
||||
// if positive, > onedge_value is inside; if negative, < onedge_value is inside
|
||||
// width,height -- output height & width of the SDF bitmap (including padding)
|
||||
// xoff,yoff -- output origin of the character
|
||||
// return value -- a 2D array of bytes 0..255, width*height in size
|
||||
//
|
||||
// pixel_dist_scale & onedge_value are a scale & bias that allows you to make
|
||||
// optimal use of the limited 0..255 for your application, trading off precision
|
||||
// and special effects. SDF values outside the range 0..255 are clamped to 0..255.
|
||||
//
|
||||
// Example:
|
||||
// scale = stbtt_ScaleForPixelHeight(22)
|
||||
// padding = 5
|
||||
// onedge_value = 180
|
||||
// pixel_dist_scale = 180/5.0 = 36.0
|
||||
//
|
||||
// This will create an SDF bitmap in which the character is about 22 pixels
|
||||
// high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled
|
||||
// shape, sample the SDF at each pixel and fill the pixel if the SDF value
|
||||
// is greater than or equal to 180/255. (You'll actually want to antialias,
|
||||
// which is beyond the scope of this example.) Additionally, you can compute
|
||||
// offset outlines (e.g. to stroke the character border inside & outside,
|
||||
// or only outside). For example, to fill outside the character up to 3 SDF
|
||||
// pixels, you would compare against (180-36.0*3)/255 = 72/255. The above
|
||||
// choice of variables maps a range from 5 pixels outside the shape to
|
||||
// 2 pixels inside the shape to 0..255; this is intended primarily for apply
|
||||
// outside effects only (the interior range is needed to allow proper
|
||||
// antialiasing of the font at *smaller* sizes)
|
||||
//
|
||||
// The function computes the SDF analytically at each SDF pixel, not by e.g.
|
||||
// building a higher-res bitmap and approximating it. In theory the quality
|
||||
// should be as high as possible for an SDF of this size & representation, but
|
||||
// unclear if this is true in practice (perhaps building a higher-res bitmap
|
||||
// and computing from that can allow drop-out prevention).
|
||||
//
|
||||
// The algorithm has not been optimized at all, so expect it to be slow
|
||||
// if computing lots of characters or very large sizes.
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Finding the right font...
|
||||
//
|
||||
// You should really just solve this offline, keep your own tables
|
||||
// of what font is what, and don't try to get it out of the .ttf file.
|
||||
// That's because getting it out of the .ttf file is really hard, because
|
||||
// the names in the file can appear in many possible encodings, in many
|
||||
// possible languages, and e.g. if you need a case-insensitive comparison,
|
||||
// the details of that depend on the encoding & language in a complex way
|
||||
// (actually underspecified in truetype, but also gigantic).
|
||||
//
|
||||
// But you can use the provided functions in two possible ways:
|
||||
// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on
|
||||
// unicode-encoded names to try to find the font you want;
|
||||
// you can run this before calling stbtt_InitFont()
|
||||
//
|
||||
// stbtt_GetFontNameString() lets you get any of the various strings
|
||||
// from the file yourself and do your own comparisons on them.
|
||||
// You have to have called stbtt_InitFont() first.
|
||||
|
||||
|
||||
STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags);
|
||||
// returns the offset (not index) of the font that matches, or -1 if none
|
||||
// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
|
||||
// if you use any other flag, use a font name like "Arial"; this checks
|
||||
// the 'macStyle' header field; i don't know if fonts set this consistently
|
||||
#define STBTT_MACSTYLE_DONTCARE 0
|
||||
#define STBTT_MACSTYLE_BOLD 1
|
||||
#define STBTT_MACSTYLE_ITALIC 2
|
||||
#define STBTT_MACSTYLE_UNDERSCORE 4
|
||||
#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0
|
||||
|
||||
STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2);
|
||||
// returns 1/0 whether the first string interpreted as utf8 is identical to
|
||||
// the second string interpreted as big-endian utf16... useful for strings from next func
|
||||
|
||||
STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID);
|
||||
// returns the string (which may be big-endian double byte, e.g. for unicode)
|
||||
// and puts the length in bytes in *length.
|
||||
//
|
||||
// some of the values for the IDs are below; for more see the truetype spec:
|
||||
// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
|
||||
// http://www.microsoft.com/typography/otspec/name.htm
|
||||
|
||||
enum { // platformID
|
||||
STBTT_PLATFORM_ID_UNICODE =0,
|
||||
STBTT_PLATFORM_ID_MAC =1,
|
||||
STBTT_PLATFORM_ID_ISO =2,
|
||||
STBTT_PLATFORM_ID_MICROSOFT =3
|
||||
};
|
||||
|
||||
enum { // encodingID for STBTT_PLATFORM_ID_UNICODE
|
||||
STBTT_UNICODE_EID_UNICODE_1_0 =0,
|
||||
STBTT_UNICODE_EID_UNICODE_1_1 =1,
|
||||
STBTT_UNICODE_EID_ISO_10646 =2,
|
||||
STBTT_UNICODE_EID_UNICODE_2_0_BMP=3,
|
||||
STBTT_UNICODE_EID_UNICODE_2_0_FULL=4
|
||||
};
|
||||
|
||||
enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT
|
||||
STBTT_MS_EID_SYMBOL =0,
|
||||
STBTT_MS_EID_UNICODE_BMP =1,
|
||||
STBTT_MS_EID_SHIFTJIS =2,
|
||||
STBTT_MS_EID_UNICODE_FULL =10
|
||||
};
|
||||
|
||||
enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes
|
||||
STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4,
|
||||
STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5,
|
||||
STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6,
|
||||
STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7
|
||||
};
|
||||
|
||||
enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
|
||||
// problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
|
||||
STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410,
|
||||
STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411,
|
||||
STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412,
|
||||
STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419,
|
||||
STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409,
|
||||
STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D
|
||||
};
|
||||
|
||||
enum { // languageID for STBTT_PLATFORM_ID_MAC
|
||||
STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11,
|
||||
STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23,
|
||||
STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32,
|
||||
STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 ,
|
||||
STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 ,
|
||||
STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33,
|
||||
STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __STB_INCLUDE_STB_TRUETYPE_H__
|
@ -86,6 +86,9 @@ void CV_DrawingTest::run( int )
|
||||
float Eps = 1;
|
||||
if( err > Eps)
|
||||
{
|
||||
//imshow("reference", valImg);
|
||||
//imshow("result", testImg);
|
||||
//waitKey();
|
||||
ts->printf( ts->LOG, "NORM_L1 between testImg and valImg is equal %f (larger than %f)\n", err, Eps );
|
||||
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
|
||||
}
|
||||
@ -619,8 +622,17 @@ TEST(Drawing, putText_no_garbage)
|
||||
|
||||
EXPECT_EQ(0, cv::countNonZero(mat(Rect(0, 0, 10, sz.height))));
|
||||
EXPECT_EQ(0, cv::countNonZero(mat(Rect(sz.width-10, 0, 10, sz.height))));
|
||||
EXPECT_EQ(0, cv::countNonZero(mat(Rect(205, 0, 10, sz.height))));
|
||||
EXPECT_EQ(0, cv::countNonZero(mat(Rect(405, 0, 10, sz.height))));
|
||||
EXPECT_EQ(0, cv::countNonZero(mat(Rect(190, 0, 10, sz.height))));
|
||||
EXPECT_EQ(0, cv::countNonZero(mat(Rect(380, 0, 10, sz.height))));
|
||||
|
||||
#if 0
|
||||
rectangle(mat, Rect(0, 0, 10, sz.height), Scalar::all(255), 1, LINE_8);
|
||||
rectangle(mat, Rect(sz.width-10, 0, 10, sz.height), Scalar::all(255), 1, LINE_8);
|
||||
rectangle(mat, Rect(190, 0, 10, sz.height), Scalar::all(255), 1, LINE_8);
|
||||
rectangle(mat, Rect(380, 0, 10, sz.height), Scalar::all(255), 1, LINE_8);
|
||||
imshow("result", mat);
|
||||
waitKey();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -679,4 +691,169 @@ TEST(Drawing, fillpoly_circle)
|
||||
EXPECT_LT(diff_fp3, 1.);
|
||||
}
|
||||
|
||||
|
||||
TEST(Drawing, fromJava_getTextSize)
|
||||
{
|
||||
String text = "Android all the way";
|
||||
double fontScale = 2;
|
||||
int thickness = 3;
|
||||
int baseLine = 0;
|
||||
|
||||
Size res0 = getTextSize(text, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, thickness, 0);
|
||||
Size res = getTextSize(text, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, thickness, &baseLine);
|
||||
|
||||
#if 0
|
||||
Mat img(200, 700, CV_8UC3, Scalar::all(255));
|
||||
Point org(100, 100);
|
||||
putText(img, text, org, FONT_HERSHEY_SCRIPT_SIMPLEX, fontScale, Scalar(128, 0, 0), thickness);
|
||||
rectangle(img, org, Point(org.x + res0.width, org.y - res0.height), Scalar(0, 0, 128), 2, LINE_AA);
|
||||
imshow("result", img);
|
||||
waitKey();
|
||||
#endif
|
||||
|
||||
EXPECT_EQ(res0.width, res.width);
|
||||
EXPECT_EQ(res0.height, res.height);
|
||||
EXPECT_NEAR(494, res.width, 3.0);
|
||||
EXPECT_NEAR(51, res.height, 3.0);
|
||||
EXPECT_NEAR(10, baseLine, 3.0);
|
||||
}
|
||||
|
||||
TEST(Drawing, fromJava_testPutTextMatStringPointIntDoubleScalarIntIntBoolean)
|
||||
{
|
||||
String text = "Hello World";
|
||||
Size labelSize(170, 23);
|
||||
|
||||
Mat img(20 + (int)labelSize.height, 20 + (int)labelSize.width, CV_8U, Scalar::all(0));
|
||||
Point origin(10, 10);
|
||||
|
||||
putText(img, text, origin, FONT_HERSHEY_SIMPLEX, 1.0, Scalar::all(255), 1, LINE_8, true);
|
||||
|
||||
EXPECT_LT(0, countNonZero(img));
|
||||
// check that border is not corrupted
|
||||
rectangle(img, origin,
|
||||
Point(origin.x + labelSize.width, origin.y + labelSize.height),
|
||||
Scalar::all(0), -1, 8);
|
||||
//imshow("img", img);
|
||||
//waitKey();
|
||||
EXPECT_EQ(0, countNonZero(img));
|
||||
|
||||
origin = Point(10, labelSize.height + 10);
|
||||
|
||||
putText(img, text, origin, FONT_HERSHEY_SIMPLEX, 1.0, Scalar::all(255));
|
||||
EXPECT_LT(0, countNonZero(img));
|
||||
// check that border is not corrupted
|
||||
rectangle(img, Point(10, 10), Point(labelSize.width + 10, labelSize.height + 10), Scalar::all(0), -1);
|
||||
EXPECT_EQ(0, countNonZero(img));
|
||||
}
|
||||
|
||||
typedef struct TextProp
|
||||
{
|
||||
const char* str;
|
||||
bool ralign;
|
||||
int weight;
|
||||
bool italic;
|
||||
} TextProp;
|
||||
|
||||
#ifdef HAVE_UNIFONT // there are other tests for text drawing, so the functionality is tested anyway,
|
||||
// but this test needs concrete unicode font to compare the printed text
|
||||
// (including CJK characters) with the reference picture from the database
|
||||
TEST(Drawing, ttf_text)
|
||||
{
|
||||
string ts_data_path = TS::ptr()->get_data_path();
|
||||
string custom_font_path = ts_data_path + "../highgui/drawing/";
|
||||
|
||||
FontFace sans("sans");
|
||||
FontFace italic("italic");
|
||||
Mat img(600, 1300, CV_8UC3);
|
||||
TextProp text[] =
|
||||
{
|
||||
{"The quick brown fox jumps over lazy dog. Fly, start, finish, shuffle shuttle.", false, 400, false},
|
||||
{"vechicle #5 detected; fps=123.45.\n", false, 600, false},
|
||||
{"Съешь же ещё этих мягких французских булок, да выпей чаю!\n"
|
||||
"Dès Noël où un zéphyr haï me vêt de glaçons würmiens je dîne\nd’exquis rôtis de bœuf au kir à l’aÿ d’âge mûr & cætera!\n"
|
||||
"“Falsches Üben von Xylophonmusik quält jeden größeren Zwerg”.", false, 400, true},
|
||||
|
||||
{"¡Oh tú, sabio encantador, quienquiera que seas,\n"
|
||||
"a quien ha de tocar el ser coronista desta peregrina\n"
|
||||
"historia, ruégote que no te olvides de mi buen Rocinante,\n"
|
||||
"compañero eterno mío en todos mis caminos y carreras!\n", false, 300, false},
|
||||
{"Ταχίστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός.", false, 400, false},
|
||||
{"春眠不觉晓,\n处处闻啼鸟。\n夜来风雨声,\n花落知多少。\n"
|
||||
" あなたはそれが困難見つけた場合 — あなたは正しい方向に向かっている。\n"
|
||||
" 넌 모든 꽃들을 다 꺾어버릴 수는 있겠지만, 봄이 오는 걸 막을 수는 없어。 ", false, 400, false}
|
||||
};
|
||||
Scalar color(150, 80, 0);
|
||||
|
||||
for(int iter = 0; iter < 1; iter++)
|
||||
{
|
||||
//double ts = (double)getTickCount();
|
||||
img.setTo(Scalar::all(255));
|
||||
int sz = 20;
|
||||
int x0 = 50, y0 = 70;
|
||||
Point org(x0, y0);
|
||||
|
||||
int j = 0, column = 1;
|
||||
for(const TextProp& t: text)
|
||||
{
|
||||
PutTextFlags flags = t.ralign ? PUT_TEXT_ALIGN_RIGHT : PUT_TEXT_ALIGN_LEFT;
|
||||
if(t.ralign)
|
||||
{
|
||||
if(j > 0)
|
||||
break;
|
||||
if(column == 1)
|
||||
{
|
||||
column = 2;
|
||||
org.y = y0;
|
||||
}
|
||||
org.x = img.cols - x0;
|
||||
}
|
||||
else
|
||||
{
|
||||
org.x = column == 1 ? x0 : img.cols/2;
|
||||
}
|
||||
FontFace& face = t.italic ? italic : sans;
|
||||
//Rect r = getTextSize(img.size(), t.str, org, face, sz, t.weight, flags);
|
||||
org = putText(img, t.str, org, color, face,
|
||||
sz, t.weight, flags, Range());
|
||||
//rectangle(img, r, Scalar(80, 0, 128), 1, LINE_AA);
|
||||
org.y += sz + 10;
|
||||
}
|
||||
|
||||
Scalar color2(80, 0, 128);
|
||||
|
||||
org = Point(img.cols - 500, 150);
|
||||
putText(img, "Пробуем\n ", org, color2, italic, 80, 300,
|
||||
PUT_TEXT_ALIGN_LEFT, Range());
|
||||
org.x -= 90;
|
||||
org.y += 130;
|
||||
// testing alternative way to set the weight;
|
||||
// in putText we use weight=0
|
||||
italic.setInstance({CV_FOURCC('w','g','h','t'), 800<<16});
|
||||
putText(img, "OpenCV", org, color2, italic, 120, 0,
|
||||
PUT_TEXT_ALIGN_LEFT, Range());
|
||||
org.y += 140;
|
||||
org.x += 60;
|
||||
putText(img, "打印文字", org, color2, sans, 100, 400,
|
||||
PUT_TEXT_ALIGN_LEFT, Range());
|
||||
//ts = (double)getTickCount() - ts;
|
||||
//printf("iter=%d. ts=%.2fms\n", iter, ts*1000./getTickFrequency());
|
||||
}
|
||||
|
||||
#if 0
|
||||
//imwrite(ts_data_path + "../highgui/drawing/text_test.png", img);
|
||||
imshow("test", img);
|
||||
waitKey();
|
||||
#else
|
||||
Mat refimg = imread(ts_data_path + "../highgui/drawing/text_test.png", IMREAD_UNCHANGED);
|
||||
//imshow("ref", refimg);
|
||||
//imshow("actual", img);
|
||||
//absdiff(refimg, img, refimg);
|
||||
//imshow("diff", refimg);
|
||||
//waitKey();
|
||||
EXPECT_EQ(refimg.size(), img.size());
|
||||
EXPECT_LT(cv::norm(refimg, img, NORM_L1), 6500);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
}} // namespace
|
||||
|
@ -413,19 +413,6 @@ enum
|
||||
//! Macro to construct the fourcc code of the codec. Same as CV_FOURCC()
|
||||
#define CV_FOURCC_MACRO(c1, c2, c3, c4) (((c1) & 255) + (((c2) & 255) << 8) + (((c3) & 255) << 16) + (((c4) & 255) << 24))
|
||||
|
||||
/** @brief Constructs the fourcc code of the codec function
|
||||
|
||||
Simply call it with 4 chars fourcc code like `CV_FOURCC('I', 'Y', 'U', 'V')`
|
||||
|
||||
List of codes can be obtained at [Video Codecs by FOURCC](http://www.fourcc.org/codecs.php) page.
|
||||
FFMPEG backend with MP4 container natively uses other values as fourcc code:
|
||||
see [ObjectType](http://mp4ra.org/#/codecs).
|
||||
*/
|
||||
CV_INLINE int CV_FOURCC(char c1, char c2, char c3, char c4)
|
||||
{
|
||||
return CV_FOURCC_MACRO(c1, c2, c3, c4);
|
||||
}
|
||||
|
||||
//! (Windows only) Open Codec Selection Dialog
|
||||
#define CV_FOURCC_PROMPT -1
|
||||
//! (Linux only) Use default codec for specified filename
|
||||
|
@ -36,7 +36,7 @@ import glob, re, os, os.path, shutil, string, sys, argparse, traceback, multipro
|
||||
from subprocess import check_call, check_output, CalledProcessError
|
||||
from distutils.dir_util import copy_tree
|
||||
|
||||
IPHONEOS_DEPLOYMENT_TARGET='8.0' # default, can be changed via command line options or environment variable
|
||||
IPHONEOS_DEPLOYMENT_TARGET='9.0' # default, can be changed via command line options or environment variable
|
||||
|
||||
def execute(cmd, cwd = None):
|
||||
print("Executing: %s in %s" % (cmd, cwd), file=sys.stderr)
|
||||
@ -426,8 +426,8 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--dynamic', default=False, action='store_true', help='build dynamic framework (default is "False" - builds static framework)')
|
||||
parser.add_argument('--disable-bitcode', default=False, dest='bitcodedisabled', action='store_true', help='disable bitcode (enabled by default)')
|
||||
parser.add_argument('--iphoneos_deployment_target', default=os.environ.get('IPHONEOS_DEPLOYMENT_TARGET', IPHONEOS_DEPLOYMENT_TARGET), help='specify IPHONEOS_DEPLOYMENT_TARGET')
|
||||
parser.add_argument('--iphoneos_archs', default='armv7,armv7s,arm64', help='select iPhoneOS target ARCHS')
|
||||
parser.add_argument('--iphonesimulator_archs', default='i386,x86_64', help='select iPhoneSimulator target ARCHS')
|
||||
parser.add_argument('--iphoneos_archs', default='armv7s,arm64', help='select iPhoneOS target ARCHS')
|
||||
parser.add_argument('--iphonesimulator_archs', default='x86_64', help='select iPhoneSimulator target ARCHS')
|
||||
parser.add_argument('--enable_nonfree', default=False, dest='enablenonfree', action='store_true', help='enable non-free modules (disabled by default)')
|
||||
parser.add_argument('--debug', default=False, dest='debug', action='store_true', help='Build "Debug" binaries (disabled by default)')
|
||||
parser.add_argument('--debug_info', default=False, dest='debug_info', action='store_true', help='Build with debug information (useful for Release mode: BUILD_WITH_DEBUG_INFO=ON)')
|
||||
|
@ -7,7 +7,7 @@ from __future__ import print_function
|
||||
import glob, re, os, os.path, shutil, string, sys, argparse, traceback, multiprocessing
|
||||
from subprocess import check_call, check_output, CalledProcessError
|
||||
|
||||
IPHONEOS_DEPLOYMENT_TARGET='8.0' # default, can be changed via command line options or environment variable
|
||||
IPHONEOS_DEPLOYMENT_TARGET='9.0' # default, can be changed via command line options or environment variable
|
||||
|
||||
def execute(cmd, cwd = None):
|
||||
print("Executing: %s in %s" % (cmd, cwd), file=sys.stderr)
|
||||
|
Loading…
Reference in New Issue
Block a user