summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2014-07-25 17:59:26 -0400
committerBehdad Esfahbod <behdad@behdad.org>2014-07-25 18:07:59 -0400
commitffda7c0e8130eb107ecbb3bdc48043093b12dff9 (patch)
tree4fd4a74e31365df2db5f77b3cf911659238d83a9
parentbf9df5ada77469f57101851f6b4e279a4a5ea087 (diff)
Linearly interpolate weight values
Rest of Part of https://bugs.freedesktop.org/show_bug.cgi?id=81453 Adds new API: FcWeightFromOpenType() FcWeightToOpenType()
-rw-r--r--doc/Makefile.am1
-rw-r--r--doc/fcweight.fncs47
-rw-r--r--fontconfig/fontconfig.h7
-rw-r--r--src/Makefile.am1
-rw-r--r--src/fcfreetype.c27
-rw-r--r--src/fcweight.c84
6 files changed, 141 insertions, 26 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 7503219..9141ab2 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -85,6 +85,7 @@ DOC_FUNCS_FNCS = \
fcstring.fncs \
fcstrset.fncs \
fcvalue.fncs \
+ fcweight.fncs \
$(NULL)
SGML_FILES = \
fontconfig-user.sgml \
diff --git a/doc/fcweight.fncs b/doc/fcweight.fncs
new file mode 100644
index 0000000..2872dd6
--- /dev/null
+++ b/doc/fcweight.fncs
@@ -0,0 +1,47 @@
+/*
+ * fontconfig/doc/fcweight.fncs
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+@RET@ int
+@FUNC@ FcWeightFromOpenType
+@TYPE1@ int @ARG1@ ot_weight
+@PURPOSE@ Convert from OpenType weight values to fontconfig ones
+@DESC@
+<function>FcWeightFromOpenType</function> returns an integer value
+to use with FC_WEIGHT, from an integer in the 1..1000 range, resembling
+the numbers from OpenType specification's OS/2 usWeight numbers, which
+are also similar to CSS font-weight numbers. If input is negative,
+zero, or greater than 1000, returns -1. This function linearly interpolates
+between various FC_WEIGHT_* constants. As such, the returned value does not
+necessarily match any of the predefined constants.
+@SINCE@ 2.11.91
+@@
+
+@RET@ int
+@FUNC@ FcWeightToOpenType
+@TYPE1@ int @ARG1@ ot_weight
+@PURPOSE@ Convert from fontconfig weight values to OpenType ones
+@DESC@
+<function>FcWeightToOpenType</function> is the inverse of
+<function>FcWeightFromOpenType</function>. If the input is less than
+FC_WEIGHT_THIN or greater than FC_WEIGHT_EXTRABLACK, returns -1. Otherwise
+returns a number in the range 1 to 1000.
+@SINCE@ 2.11.91
+@@
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index af027f0..e5b0959 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -908,6 +908,13 @@ FcRangeDestroy (FcRange *range);
FcPublic FcRange *
FcRangeCopy (const FcRange *r);
+/* fcweight.c */
+
+FcPublic int
+FcWeightFromOpenType (int ot_weight);
+
+FcPublic int
+FcWeightToOpenType (int fc_weight);
/* fcstr.c */
diff --git a/src/Makefile.am b/src/Makefile.am
index c1991b2..3757cf8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -154,6 +154,7 @@ libfontconfig_la_SOURCES = \
fcserialize.c \
fcstat.c \
fcstr.c \
+ fcweight.c \
fcwindows.h \
fcxml.c \
ftglue.h \
diff --git a/src/fcfreetype.c b/src/fcfreetype.c
index 0e1ff5d..aca2f70 100644
--- a/src/fcfreetype.c
+++ b/src/fcfreetype.c
@@ -1628,32 +1628,7 @@ FcFreeTypeQueryFace (const FT_Face face,
if (os2 && os2->version != 0xffff)
{
- if (os2->usWeightClass == 0)
- ;
- else if (os2->usWeightClass < 150)
- weight = FC_WEIGHT_THIN;
- else if (os2->usWeightClass < 250)
- weight = FC_WEIGHT_EXTRALIGHT;
- else if (os2->usWeightClass < 325)
- weight = FC_WEIGHT_LIGHT;
- else if (os2->usWeightClass < 365)
- weight = FC_WEIGHT_SEMILIGHT;
- else if (os2->usWeightClass < 390)
- weight = FC_WEIGHT_BOOK;
- else if (os2->usWeightClass < 450)
- weight = FC_WEIGHT_REGULAR;
- else if (os2->usWeightClass < 550)
- weight = FC_WEIGHT_MEDIUM;
- else if (os2->usWeightClass < 650)
- weight = FC_WEIGHT_SEMIBOLD;
- else if (os2->usWeightClass < 750)
- weight = FC_WEIGHT_BOLD;
- else if (os2->usWeightClass < 850)
- weight = FC_WEIGHT_EXTRABOLD;
- else if (os2->usWeightClass < 925)
- weight = FC_WEIGHT_BLACK;
- else if (os2->usWeightClass < 1000)
- weight = FC_WEIGHT_EXTRABLACK;
+ weight = FcWeightFromOpenType (os2->usWeightClass);
if ((FcDebug() & FC_DBG_SCANV) && weight != -1)
printf ("\tos2 weight class %d maps to weight %d\n",
os2->usWeightClass, weight);
diff --git a/src/fcweight.c b/src/fcweight.c
new file mode 100644
index 0000000..20c5da0
--- /dev/null
+++ b/src/fcweight.c
@@ -0,0 +1,84 @@
+/*
+ * fontconfig/src/fcweight.c
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the author(s) not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fcint.h"
+
+static const struct {
+ int ot;
+ int fc;
+} map[] = {
+ { 0, FC_WEIGHT_THIN },
+ { 100, FC_WEIGHT_THIN },
+ { 200, FC_WEIGHT_EXTRALIGHT },
+ { 350, FC_WEIGHT_DEMILIGHT },
+ { 300, FC_WEIGHT_LIGHT },
+ { 380, FC_WEIGHT_BOOK },
+ { 400, FC_WEIGHT_REGULAR },
+ { 500, FC_WEIGHT_MEDIUM },
+ { 600, FC_WEIGHT_DEMIBOLD },
+ { 700, FC_WEIGHT_BOLD },
+ { 800, FC_WEIGHT_EXTRABOLD },
+ { 900, FC_WEIGHT_BLACK },
+ {1000, FC_WEIGHT_EXTRABLACK },
+};
+
+static int lerp(int x, int x1, int x2, int y1, int y2)
+{
+ int dx = x2 - x1;
+ int dy = y2 - y1;
+ assert (dx > 0 && dy > 0 && x1 <= x && x <= x2);
+ return y1 + (dy*(x-x1) + dx/2) / dx;
+}
+
+FcPublic int
+FcWeightFromOpenType (int ot_weight)
+{
+ int i;
+ if (ot_weight <= 0 || ot_weight > 1000)
+ return -1;
+
+ for (i = 1; ot_weight > map[i].ot; i++)
+ ;
+
+ if (ot_weight == map[i].ot)
+ return map[i].fc;
+
+ /* Interpolate between two items. */
+ return lerp (ot_weight, map[i-1].ot, map[i].ot, map[i-1].fc, map[i].fc);
+}
+
+FcPublic int
+FcWeightToOpenType (int fc_weight)
+{
+ int i;
+ if (fc_weight < 0 || fc_weight > FC_WEIGHT_EXTRABLACK)
+ return -1;
+
+ for (i = 1; fc_weight > map[i].fc; i++)
+ ;
+
+ if (fc_weight == map[i].fc)
+ return map[i].ot;
+
+ /* Interpolate between two items. */
+ return lerp (fc_weight, map[i-1].fc, map[i].fc, map[i-1].ot, map[i].ot);
+}