diff options
39 files changed, 1504 insertions, 783 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b91fd650..5d4a265f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,49 +1,40 @@ -image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/base:latest - stages: - build + - docs + - deploy + +# Common variables +variables: + COMMON_MESON_FLAGS: "--fatal-meson-warnings --werror" + MESON_TEST_TIMEOUT_MULTIPLIER: 2 -gnome-runtime-linux: +linux-fedora: + image: registry.gitlab.gnome.org/gnome/pango/fedora:v1 stage: build - before_script: - - > - dnf install -y \ - glibc-langpack-en \ - gcc \ - gcc-c++ \ - meson \ - redhat-rpm-config \ - glib2-devel \ - harfbuzz-devel \ - fribidi-devel \ - cairo-devel \ - libthai-devel \ - gobject-introspection-devel \ - cairo-gobject-devel \ - abattis-cantarell-fonts \ - google-droid-sans-fonts \ - thai-scalable-waree-fonts \ - desktop-file-utils \ - diffutils + variables: + EXTRA_MESON_FLAGS: "--buildtype=debug --default-library=both" script: + - meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} + _build - meson _build - ninja -C _build - - meson test -C_build --suite pango - - _build/utils/pango-list --verbose > _build/fontlist.txt - - _build/tests/test-font -p /pango/font/metrics --verbose - - _build/utils/pango-view --no-display --output _build/hello.png utils/HELLO.txt + - .gitlab-ci/run-tests.sh _build artifacts: - name: "%CI_JOB_NAME%-%CI_COMMIT_REF_NAME%" when: always + reports: + junit: + - "${CI_PROJECT_DIR}/_build/report.xml" + name: "gtk-${CI_COMMIT_REF_NAME}" paths: - - _build/meson-logs - - _build/hello.png - - _build/fontlist.txt + - "${CI_PROJECT_DIR}/_build/meson-logs" + - "${CI_PROJECT_DIR}/_build/report.xml" + - "${CI_PROJECT_DIR}/_build/hello.png" + - "${CI_PROJECT_DIR}/_build/fontlist.txt" msys2-mingw64: stage: build tags: - - win32 + - win32-ps variables: MSYSTEM: "MINGW64" CHERE_INVOKING: "yes" @@ -53,9 +44,33 @@ msys2-mingw64: - C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/render-msys2.sh" - C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/list-msys2.sh" artifacts: - name: "%CI_JOB_NAME%-%CI_COMMIT_REF_NAME%" + name: "${env:CI_JOB_NAME}-${env:CI_COMMIT_REF_NAME}" when: always paths: - _build/meson-logs - _build/hello.png - _build/fontlist.txt + +reference: + image: registry.gitlab.gnome.org/gnome/pango/fedora:v1 + stage: docs + variables: + EXTRA_MESON_FLAGS: "" + script: + - meson ${COMMON_MESON_FLAGS} ${EXTRA_MESON_FLAGS} -Dgtk_doc=true _build + - ninja -C _build pango-doc + - mkdir -p _reference/ + - mv _build/docs/html/ _reference/ + artifacts: + paths: + - _reference + +pages: + stage: deploy + script: + - mv _reference/ public/ + artifacts: + paths: + - public + only: + - master diff --git a/.gitlab-ci/README.md b/.gitlab-ci/README.md new file mode 100644 index 00000000..a5c7736d --- /dev/null +++ b/.gitlab-ci/README.md @@ -0,0 +1,38 @@ +## Pango CI infrastructure + +Pango uses different CI images depending on platform and jobs. + +The CI images are Docker containers, generated either using `docker` or +`podman`, and pushed to the GitLab [container registry][registry]. + +Each Docker image has a tag composed of two parts: + + - `${image}`: the base image for a given platform, like "fedora" or + "debian-stable" + - `${number}`: an incremental version number, or `latest` + +See the [container registry][registry] for the available images for each +branch, as well as their available versions. + +### Checklist for Updating a CI image + + - [ ] Update the `${image}.Dockerfile` file with the dependencies + - [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}` + - [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}` + once the Docker image is built; you may need to log in by using + `docker login` or `podman login` + - [ ] Update the `image` keys in the `.gitlab-ci.yml` file with the new + image tag + - [ ] Open a merge request with your changes and let it run + +### Checklist for Adding a new CI image + + - [ ] Write a new `${image}.Dockerfile` with the instructions to set up + a build environment + - [ ] Add the `pip3 install meson` incantation + - [ ] Run `./run-docker.sh build --base ${image} --base-version ${number}` + - [ ] Run `./run-docker.sh push --base ${image} --base-version ${number}` + - [ ] Add the new job to `.gitlab-ci.yml` referencing the image + - [ ] Open a merge request with your changes and let it run + +[registry]: https://gitlab.gnome.org/GNOME/pango/container_registry diff --git a/.gitlab-ci/fedora.Dockerfile b/.gitlab-ci/fedora.Dockerfile new file mode 100644 index 00000000..e7ff2feb --- /dev/null +++ b/.gitlab-ci/fedora.Dockerfile @@ -0,0 +1,51 @@ +FROM fedora:31 + +RUN dnf -y install \ + abattis-cantarell-fonts \ + cairo-devel \ + cairo-gobject-devel \ + ccache \ + clang \ + clang-analyzer \ + desktop-file-utils \ + diffutils \ + fontconfig-devel \ + fribidi-devel \ + gcc \ + gcc-c++ \ + gettext \ + git \ + glib2-devel \ + glib2-static \ + glibc-devel \ + glibc-headers \ + glibc-langpack-en \ + gobject-introspection-devel \ + google-droid-sans-fonts \ + gtk-doc \ + harfbuzz-devel \ + hicolor-icon-theme \ + itstool \ + lcov \ + libthai-devel \ + libXft-devel \ + ninja-build \ + python3 \ + python3-jinja2 \ + python3-pip \ + python3-pygments \ + python3-wheel \ + redhat-rpm-config \ + thai-scalable-waree-fonts \ + && dnf clean all + +RUN pip3 install meson==0.53.1 + +ARG HOST_USER_ID=5555 +ENV HOST_USER_ID ${HOST_USER_ID} +RUN useradd -u $HOST_USER_ID -ms /bin/bash user + +USER user +WORKDIR /home/user + +ENV LANG C.UTF-8 diff --git a/.gitlab-ci/meson-junit-report.py b/.gitlab-ci/meson-junit-report.py new file mode 100755 index 00000000..fc96efba --- /dev/null +++ b/.gitlab-ci/meson-junit-report.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 + +# Turns a Meson testlog.json file into a JUnit XML report +# +# Copyright 2019 GNOME Foundation +# +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Original author: Emmanuele Bassi + +import argparse +import datetime +import json +import os +import sys +import xml.etree.ElementTree as ET + +aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUnit report') +aparser.add_argument('--project-name', metavar='NAME', + help='The project name', + default='unknown') +aparser.add_argument('--job-id', metavar='ID', + help='The job ID for the report', + default='Unknown') +aparser.add_argument('--branch', metavar='NAME', + help='Branch of the project being tested', + default='master') +aparser.add_argument('--output', metavar='FILE', + help='The output file, stdout by default', + type=argparse.FileType('w', encoding='UTF-8'), + default=sys.stdout) +aparser.add_argument('infile', metavar='FILE', + help='The input testlog.json, stdin by default', + type=argparse.FileType('r', encoding='UTF-8'), + default=sys.stdin) + +args = aparser.parse_args() + +outfile = args.output + +testsuites = ET.Element('testsuites') +testsuites.set('id', '{}/{}'.format(args.job_id, args.branch)) +testsuites.set('package', args.project_name) +testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes')) + +suites = {} +for line in args.infile: + data = json.loads(line) + unit_name = data['name'] + suite_name = args.project_name + project_name = args.project_name + + duration = data['duration'] + return_code = data['returncode'] + result = data['result'] + log = data['stdout'] + + unit = { + 'suite': suite_name, + 'name': unit_name, + 'duration': duration, + 'returncode': return_code, + 'result': result, + 'stdout': log, + } + + units = suites.setdefault(suite_name, []) + units.append(unit) + +for name, units in suites.items(): + print('Processing suite {} (units: {})'.format(name, len(units))) + + def if_failed(unit): + if unit['result'] in ['FAIL', 'UNEXPECTEDPASS', 'TIMEOUT']: + return True + return False + + def if_succeded(unit): + if unit['result'] in ['OK', 'EXPECTEDFAIL', 'SKIP']: + return True + return False + + successes = list(filter(if_succeded, units)) + failures = list(filter(if_failed, units)) + print(' - {}: {} pass, {} fail'.format(name, len(successes), len(failures))) + + testsuite = ET.SubElement(testsuites, 'testsuite') + testsuite.set('name', '{}/{}'.format(args.project_name, name)) + testsuite.set('tests', str(len(units))) + testsuite.set('errors', str(len(failures))) + testsuite.set('failures', str(len(failures))) + + for unit in successes: + testcase = ET.SubElement(testsuite, 'testcase') + testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) + testcase.set('name', unit['name']) + testcase.set('time', str(unit['duration'])) + + for unit in failures: + testcase = ET.SubElement(testsuite, 'testcase') + testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) + testcase.set('name', unit['name']) + testcase.set('time', str(unit['duration'])) + + failure = ET.SubElement(testcase, 'failure') + failure.set('classname', '{}/{}'.format(args.project_name, unit['suite'])) + failure.set('name', unit['name']) + failure.set('type', 'error') + failure.text = unit['stdout'] + +output = ET.tostring(testsuites, encoding='unicode') +outfile.write(output) diff --git a/.gitlab-ci/run-docker.sh b/.gitlab-ci/run-docker.sh new file mode 100755 index 00000000..06c4f63d --- /dev/null +++ b/.gitlab-ci/run-docker.sh @@ -0,0 +1,135 @@ +#!/bin/bash + +read_arg() { + # $1 = arg name + # $2 = arg value + # $3 = arg parameter + local rematch='^[^=]*=(.*)$' + if [[ $2 =~ $rematch ]]; then + read "$1" <<< "${BASH_REMATCH[1]}" + else + read "$1" <<< "$3" + # There is no way to shift our callers args, so + # return 1 to indicate they should do it instead. + return 1 + fi +} + +set -e + +build=0 +run=0 +push=0 +list=0 +print_help=0 +no_login=0 + +while (($# > 0)); do + case "${1%%=*}" in + build) build=1;; + run) run=1;; + push) push=1;; + list) list=1;; + help) print_help=1;; + --base|-b) read_arg base "$@" || shift;; + --base-version) read_arg base_version "$@" || shift;; + --no-login) no_login=1;; + *) echo -e "\e[1;31mERROR\e[0m: Unknown option '$1'"; exit 1;; + esac + shift +done + +if [ $print_help == 1 ]; then + echo "$0 - Build and run Docker images" + echo "" + echo "Usage: $0 <command> [options] [basename]" + echo "" + echo "Available commands" + echo "" + echo " build --base=<BASENAME> - Build Docker image <BASENAME>.Dockerfile" + echo " run --base=<BASENAME> - Run Docker image <BASENAME>" + echo " push --base=<BASENAME> - Push Docker image <BASENAME> to the registry" + echo " list - List available images" + echo " help - This help message" + echo "" + exit 0 +fi + +cd "$(dirname "$0")" + +if [ $list == 1 ]; then + echo "Available Docker images:" + for f in *.Dockerfile; do + filename=$( basename -- "$f" ) + basename="${filename%.*}" + + echo -e " \e[1;39m$basename\e[0m" + done + exit 0 +fi + +# All commands after this require --base to be set +if [ -z $base ]; then + echo "Usage: $0 <command>" + exit 1 +fi + +if [ ! -f "$base.Dockerfile" ]; then + echo -e "\e[1;31mERROR\e[0m: Dockerfile for '$base' not found" + exit 1 +fi + +if [ -z $base_version ]; then + base_version="latest" +else + base_version="v$base_version" +fi + +if [ ! -x "$(command -v docker)" ] || [ docker --help |& grep -q podman ]; then + # Docker is actually implemented by podman, and its OCI output + # is incompatible with some of the dockerd instances on GitLab + # CI runners. + echo "Using: Podman" + format="--format docker" + CMD="podman" +else + echo "Using: Docker" + format="" + CMD="sudo socker" +fi + +REGISTRY="registry.gitlab.gnome.org" +TAG="${REGISTRY}/gnome/pango/${base}:${base_version}" + +if [ $build == 1 ]; then + echo -e "\e[1;32mBUILDING\e[0m: ${base} as ${TAG}" + ${CMD} build \ + ${format} \ + --build-arg HOST_USER_ID="$UID" \ + --tag "${TAG}" \ + --file "${base}.Dockerfile" . + exit $? +fi + +if [ $push == 1 ]; then + echo -e "\e[1;32mPUSHING\e[0m: ${base} as ${TAG}" + + if [ $no_login == 0 ]; then + ${CMD} login ${REGISTRY} + fi + + ${CMD} push ${TAG} + exit $? +fi + +if [ $run == 1 ]; then + echo -e "\e[1;32mRUNNING\e[0m: ${base} as ${TAG}" + ${CMD} run \ + --rm \ + --volume "$(pwd)/..:/home/user/app" \ + --workdir "/home/user/app" \ + --tty \ + --interactive "${TAG}" \ + bash + exit $? +fi diff --git a/.gitlab-ci/run-tests.sh b/.gitlab-ci/run-tests.sh new file mode 100755 index 00000000..cca589b4 --- /dev/null +++ b/.gitlab-ci/run-tests.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set +x +set +e + +srcdir=$( pwd ) +builddir=$1 + +meson test -C ${builddir} \ + --print-errorlogs \ + --suite=pango + +# Store the exit code for the CI run, but always +# generate the reports +exit_code=$? + +cd ${builddir} + +./utils/pango-list --verbose > fontlist.txt +./tests/test-font -p /pango/font/metrics --verbose +./utils/pango-view --no-display --output hello.png ${srcdir}/utils/HELLO.txt + +$srcdir/.gitlab-ci/meson-junit-report.py \ + --project-name=pango \ + --job-id="${CI_JOB_NAME}" \ + --output=report.xml \ + meson-logs/testlog.json + +exit $exit_code diff --git a/docs/meson.build b/docs/meson.build index a99448af..e847a34f 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -55,7 +55,7 @@ if build_pangoft2 docdeps += libpangoft2_dep endif -if xft_dep.found() +if xft_dep.found() and fontconfig_dep.found() docdeps += libpangoxft_dep endif @@ -72,8 +72,7 @@ docpath = join_paths(pango_datadir, 'gtk-doc', 'html') gnome.gtkdoc('pango', main_xml: 'pango-docs.sgml', src_dir: [ - join_paths(meson.source_root(), 'pango'), - join_paths(meson.build_root(), 'pango'), + pango_inc, ], dependencies: docdeps, gobject_typesfile: configure_file(input: 'pango.types.in', diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt index e87b8750..4648816b 100644 --- a/docs/pango-sections.txt +++ b/docs/pango-sections.txt @@ -440,6 +440,7 @@ pango_attr_list_filter pango_attr_list_update PangoAttrFilterFunc pango_attr_list_get_attributes +pango_attr_list_equal pango_attr_list_get_iterator PangoAttrIterator pango_attr_iterator_copy diff --git a/examples/cairotwisted.c b/examples/cairotwisted.c index d2d1cd30..1572c89a 100644 --- a/examples/cairotwisted.c +++ b/examples/cairotwisted.c @@ -234,7 +234,7 @@ parametrize_path (cairo_path_t *path) case CAIRO_PATH_CLOSE_PATH: /* Make it look like it's a line_to to last_move_to */ data = (&last_move_to) - 1; - /* fall through */ + G_GNUC_FALLTHROUGH; case CAIRO_PATH_LINE_TO: parametrization[i] = two_points_distance (¤t_point, &data[1]); current_point = data[1]; @@ -361,7 +361,7 @@ point_on_path (parametrized_path_t *param, case CAIRO_PATH_CLOSE_PATH: /* Make it look like it's a line_to to last_move_to */ data = (&last_move_to) - 1; - /* fall through */ + G_GNUC_FALLTHROUGH; case CAIRO_PATH_LINE_TO: { ratio = the_x / parametrization[i]; diff --git a/meson.build b/meson.build index d4cff2af..c427842a 100644 --- a/meson.build +++ b/meson.build @@ -57,8 +57,8 @@ common_ldflags = [] if cc.get_id() == 'msvc' # Compiler options taken from msvc_recommended_pragmas.h # in GLib, based on _Win32_Programming_ by Rector and Newcomer - test_cflags = [] - add_project_arguments([ '-FImsvc_recommended_pragmas.h' ], language: 'c') + test_cflags = ['-FImsvc_recommended_pragmas', '-utf-8'] + add_project_arguments(cc.get_supported_arguments(test_cflags), language: 'c') test_c_only_flags = [] elif cc.get_id() == 'gcc' or cc.get_id() == 'clang' test_c_only_flags = [ @@ -172,23 +172,25 @@ foreach h: checked_headers endif endforeach -buildtype = get_option('buildtype') -if buildtype.startswith('debug') - pango_debug_cflags = [ '-DPANGO_ENABLE_DEBUG', ] -elif buildtype == 'release' - pango_debug_cflags = [ '-DG_DISABLE_CAST_CHECKS', ] +# Use debug/optimization flags to determine whether to enable debug or disable +# cast checks +pango_debug_cflags = [] +if get_option('debug') + pango_debug_cflags = [ '-DPANGO_ENABLE_DEBUG' ] + message('Enabling various debug infrastructure') +elif get_option('optimization') in ['2', '3', 's'] + pango_debug_cflags = [ '-DG_DISABLE_CAST_CHECKS' ] + message('Disabling cast checks') # TODO: We may want a configuration argument to add `G_DISABLE_CHECKS` # and `G_DISABLE_ASSERT` from the build, for specific build environments. # On the other hand, those who need these symbols can inject them in their # build as well. -else - pango_debug_cflags = [] endif # Dependencies pango_deps = [] -glib_req_version = '>= 2.59.2' +glib_req_version = '>= 2.60' fribidi_req_version = '>= 0.19.7' libthai_req_version = '>= 0.1.9' harfbuzz_req_version = '>= 2.0.0' @@ -310,8 +312,7 @@ message('fontconfig has FcWeightFromOpenTypeDouble: ' + res) # The first version of freetype with a pkg-config file is 2.1.5 # We require both fontconfig and freetype if we are to have either. -freetype_dep = dependency('freetype2', required: false, - fallback: ['freetype2', 'freetype_dep']) +freetype_dep = dependency('freetype2', required: false) if freetype_dep.found() freetype2_pc = 'freetype2' @@ -328,6 +329,11 @@ else endif endif +if fontconfig_required and not freetype_dep.found() + freetype_dep = dependency('freetype2', required: false, + fallback: ['freetype2', 'freetype_dep']) +endif + # To build pangoft2, we need HarfBuzz, FontConfig and FreeType build_pangoft2 = harfbuzz_dep.found() and fontconfig_dep.found() and freetype_dep.found() if build_pangoft2 @@ -539,6 +545,7 @@ pkgconfig = import('pkgconfig') configure_file(output: 'config.h', configuration: pango_conf) root_inc = include_directories('.') +pango_inc = include_directories('pango') subdir('pango') subdir('utils') @@ -6,6 +6,7 @@ <name xml:lang="en">pango</name> <shortdesc xml:lang="en">Internationalized text layout and rendering library</shortdesc> + <description xml:lang="en">Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pango can be used anywhere that text layout is needed. Pango forms the core of text and font handling for GTK.</description> <category rdf:resource="http://api.gnome.org/doap-extensions#core" /> <programming-language>C</programming-language> @@ -16,7 +17,7 @@ <download-page rdf:resource="http://download.gnome.org/sources/pango/"/> <bug-database - rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=pango"/> + rdf:resource="https://gitlab.gnome.org/GNOME/pango/issues/"/> <maintainer> <foaf:Person> @@ -32,4 +33,18 @@ <gnome:userid>behdad</gnome:userid> </foaf:Person> </maintainer> + <maintainer> + <foaf:Person> + <foaf:name>Matthias Clasen</foaf:name> + <foaf:mbox rdf:resource="mailto:mclasen@redhat.com" /> + <gnome:userid>matthiasc</gnome:userid> + </foaf:Person> + </maintainer> + <maintainer> + <foaf:Person> + <foaf:name>Emmanuele Bassi</foaf:name> + <foaf:mbox rdf:resource="mailto:ebassi@gnome.org" /> + <gnome:userid>ebassi</gnome:userid> + </foaf:Person> + </maintainer> </Project> diff --git a/pango/break.c b/pango/break.c index ca62a28f..875d776c 100644 --- a/pango/break.c +++ b/pango/break.c @@ -398,14 +398,13 @@ pango_default_break (const gchar *text, wc == 0x6DD || wc == 0x70F || wc == 0x8E2 || - wc == 0xD4E || wc == 0x110BD || - (wc >= 0x111C2 && wc <= 0x111C3))) + wc == 0x110CD)) { GB_type = GB_Prepend; break; } - /* fall through */ + G_GNUC_FALLTHROUGH; case G_UNICODE_CONTROL: case G_UNICODE_LINE_SEPARATOR: case G_UNICODE_PARAGRAPH_SEPARATOR: @@ -421,11 +420,15 @@ pango_default_break (const gchar *text, GB_type = GB_ControlCRLF; break; } - /* fall through */ + G_GNUC_FALLTHROUGH; case G_UNICODE_OTHER_LETTER: if (makes_hangul_syllable) GB_type = GB_InHangulSyllable; + + if (_pango_is_Consonant_Preceding_Repha (wc) || + _pango_is_Consonant_Prefixed (wc)) + GB_type = GB_Prepend; break; case G_UNICODE_MODIFIER_LETTER: @@ -570,7 +573,7 @@ pango_default_break (const gchar *text, WB_type = WB_ExtendFormat; /* Other_Grapheme_Extend */ break; case 0x05: - if (wc == 0x05F3) + if (wc == 0x058A) WB_type = WB_ALetter; /* ALetter exceptions */ break; } @@ -594,7 +597,7 @@ pango_default_break (const gchar *text, case G_UNICODE_CONTROL: if (wc != 0x000D && wc != 0x000A && wc != 0x000B && wc != 0x000C && wc != 0x0085) break; - /* fall through */ + G_GNUC_FALLTHROUGH; case G_UNICODE_LINE_SEPARATOR: case G_UNICODE_PARAGRAPH_SEPARATOR: WB_type = WB_NewlineCRLF; /* CR, LF, Newline */ @@ -617,12 +620,16 @@ pango_default_break (const gchar *text, WB_type = WB_MidNumLet; /* MidNumLet */ break; case G_UNICODE_OTHER_PUNCTUATION: - if (wc == 0x0027 || wc == 0x002e || wc == 0x2024 || + if ((wc >= 0x055a && wc <= 0x055c) || + wc == 0x055e || wc == 0x05f3) + WB_type = WB_ALetter; /* ALetter */ + else if (wc == 0x0027 || wc == 0x002e || wc == 0x2024 || wc == 0xfe52 || wc == 0xff07 || wc == 0xff0e) WB_type = WB_MidNumLet; /* MidNumLet */ - else if (wc == 0x00b7 || wc == 0x05f4 || wc == 0x2027 || wc == 0x003a || wc == 0x0387 || + else if (wc == 0x00b7 || wc == 0x05f4 || wc == 0x2027 || + wc == 0x003a || wc == 0x0387 || wc == 0x055f || wc == 0xfe13 || wc == 0xfe55 || wc == 0xff1a) - WB_type = WB_MidLetter; /* WB_MidLetter */ + WB_type = WB_MidLetter; /* MidLetter */ else if (wc == 0x066c || wc == 0xfe50 || wc == 0xfe54 || wc == 0xff0c || wc == 0xff1b) WB_type = WB_MidNum; /* MidNum */ @@ -1074,10 +1081,12 @@ pango_default_break (const gchar *text, if ((prev_break_type == G_UNICODE_BREAK_ALPHABETIC || prev_break_type == G_UNICODE_BREAK_HEBREW_LETTER || prev_break_type == G_UNICODE_BREAK_NUMERIC) && - break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION) + break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION && + !_pango_is_EastAsianWide (wc)) break_op = BREAK_PROHIBITED; if (prev_break_type == G_UNICODE_BREAK_CLOSE_PARANTHESIS && + !_pango_is_EastAsianWide (prev_wc)&& (break_type == G_UNICODE_BREAK_ALPHABETIC || break_type == G_UNICODE_BREAK_HEBREW_LETTER || break_type == G_UNICODE_BREAK_NUMERIC)) @@ -1219,25 +1228,7 @@ pango_default_break (const gchar *text, /* Rule LB22 */ if (break_type == G_UNICODE_BREAK_INSEPARABLE) - { - if (prev_break_type == G_UNICODE_BREAK_ALPHABETIC || - prev_break_type == G_UNICODE_BREAK_HEBREW_LETTER) - break_op = BREAK_PROHIBITED; - - if (prev_break_type == G_UNICODE_BREAK_EXCLAMATION) - break_op = BREAK_PROHIBITED; - - if (prev_break_type == G_UNICODE_BREAK_IDEOGRAPHIC || - prev_break_type == G_UNICODE_BREAK_EMOJI_BASE || - prev_break_type == G_UNICODE_BREAK_EMOJI_MODIFIER) - break_op = BREAK_PROHIBITED; - - if (prev_break_type == G_UNICODE_BREAK_INSEPARABLE) - break_op = BREAK_PROHIBITED; - - if (prev_break_type == G_UNICODE_BREAK_NUMERIC) - break_op = BREAK_PROHIBITED; - } + break_op = BREAK_PROHIBITED; if (break_type == G_UNICODE_BREAK_AFTER || break_type == G_UNICODE_BREAK_HYPHEN || diff --git a/pango/meson.build b/pango/meson.build index e2e24baa..b2496373 100644 --- a/pango/meson.build +++ b/pango/meson.build @@ -136,7 +136,7 @@ if build_gir identifier_prefix: 'Pango', symbol_prefix: 'pango', export_packages: 'pango', - includes: [ 'HarfBuzz-0.0', 'GObject-2.0', 'cairo-1.0', ], + includes: [ 'GObject-2.0', 'cairo-1.0', ], header: 'pango/pango.h', install: true, extra_args: gir_args, @@ -152,11 +152,16 @@ libpango_dep = declare_dependency( sources: pango_dep_sources, ) +pango_pkg_requires = ['gobject-2.0'] +if harfbuzz_dep.type_name() == 'pkgconfig' + pango_pkg_requires += 'harfbuzz' +endif + pkgconfig.generate(libpango, name: 'Pango', description: 'Internationalized text handling', version: meson.project_version(), - requires: ['gobject-2.0', 'harfbuzz'], + requires: pango_pkg_requires, filebase: 'pango', subdirs: pango_api_name, install_dir: join_paths(pango_libdir, 'pkgconfig'), @@ -237,9 +242,9 @@ if build_pangoft2 nsversion: pango_api_version, identifier_prefix: 'PangoFc', symbol_prefix: 'pango_fc', - export_packages: 'pangoft2', + export_packages: 'pangofc', includes: [ pango_gir[0], 'fontconfig-2.0', ], - header: 'pango/pangoft2.h', + header: 'pango/pangofc-fontmap.h', install: true, extra_args: gir_args, ) @@ -255,9 +260,9 @@ if build_pangoft2 nsversion: pango_api_version, identifier_prefix: 'PangoOT', symbol_prefix: 'pango_ot', - export_packages: 'pangoft2', + export_packages: 'pangoot', includes: [ pangofc_gir[0], 'freetype2-2.0', ], - header: 'pango/pangoft2.h', + header: 'pango/pango-ot.h', install: true, extra_args: gir_args, ) diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 2d2dd2a2..03a45de4 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -1916,6 +1916,82 @@ pango_attr_list_get_attributes (PangoAttrList *list) return g_slist_copy_deep (list->attributes, (GCopyFunc)pango_attribute_copy, NULL); } +/** + * pango_attr_list_equal: + * @list: a #PangoAttrList + * @other_list: the other #PangoAttrList + * + * Checks whether @list and @other_list contain the same attributes and + * whether those attributes apply to the same ranges. Beware that this + * will return wrong values if any list contains duplicates. + * + * Return value: %TRUE if the lists are equal, %FALSE if they aren't. + * + * Since: 1.46 + */ +gboolean +pango_attr_list_equal (PangoAttrList *list, + PangoAttrList *other_list) +{ + GSList *attrs, *other_attrs; + GSList *iter = NULL; + guint attrs_length = 0; + guint64 skip_bitmask = 0; + + if (list == other_list) + return TRUE; + + if (list == NULL || other_list == NULL) + return FALSE; + + attrs = list->attributes; + other_attrs = other_list->attributes; + + for (iter = attrs; iter != NULL; iter = iter->next) + { + PangoAttribute *attr = iter->data; + GSList *other_iter = NULL; + gboolean attr_equal = FALSE; + guint other_attr_index = 0; + + attrs_length++; + + for (other_iter = other_attrs; + other_iter != NULL; + other_iter = other_iter->next) + { + PangoAttribute *other_attr = other_iter->data; + guint64 other_attr_bitmask = + other_attr_index < 64 ? 1 << other_attr_index : 0; + + if ((skip_bitmask & other_attr_bitmask) != 0) + { + other_attr_index++; + continue; + } + + if (attr->start_index == other_attr->start_index && + attr->end_index == other_attr->end_index && + pango_attribute_equal (attr, other_attr)) + { + skip_bitmask |= other_attr_bitmask; + attr_equal = TRUE; + break; + } + + other_attr_index++; + } + + if (!attr_equal) + return FALSE; + } + + if (attrs_length != g_slist_length (other_attrs)) + return FALSE; + + return TRUE; +} + G_DEFINE_BOXED_TYPE (PangoAttrIterator, pango_attr_iterator, pango_attr_iterator_copy, diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index 7def13ab..6f6622ab 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -150,7 +150,7 @@ typedef struct _PangoAttrIterator PangoAttrIterator; * @PANGO_ATTR_ALLOW_BREAKS: whether breaks are allowed (#PangoAttrInt). Since 1.44 * @PANGO_ATTR_SHOW: how to render invisible characters (#PangoAttrInt). Since 1.44 * @PANGO_ATTR_INSERT_HYPHENS: whether to insert hyphens at intra-word line breaks (#PangoAttrInt). Since 1.44 - * @PANGO_ATTR_OVERLINE: whether the text has an overline (#PangoAttrInt). Sincd 1.46 + * @PANGO_ATTR_OVERLINE: whether the text has an overline (#PangoAttrInt). Since 1.46 * @PANGO_ATTR_OVERLINE_COLOR: overline color (#PangoAttrColor). Since 1.46 * * The #PangoAttrType @@ -633,6 +633,10 @@ PangoAttrList *pango_attr_list_filter (PangoAttrList *list, PANGO_AVAILABLE_IN_1_44 GSList *pango_attr_list_get_attributes (PangoAttrList *list); +PANGO_AVAILABLE_IN_1_46 +gboolean pango_attr_list_equal (PangoAttrList *list, + PangoAttrList *other_list); + PANGO_AVAILABLE_IN_1_44 GType pango_attr_iterator_get_type (void) G_GNUC_CONST; diff --git a/pango/pango-break-table.h b/pango/pango-break-table.h index 2361ede5..c587fd5a 100644 --- a/pango/pango-break-table.h +++ b/pango/pango-break-table.h @@ -2,22 +2,21 @@ /* * The following tables are generated by running: * - * ./gen-break-table.py SentenceBreakProperty.txt IndicSyllabicCategory.txt | indent + * ./gen-break-table.py SentenceBreakProperty.txt IndicSyllabicCategory.txt EastAsianWidth.txt | indent * * on files with these headers: * - * # SentenceBreakProperty-11.0.0.txt - * # Date: 2018-03-15, 04:28:45 GMT - * # © 2018 Unicode®, Inc. + * # SentenceBreakProperty-13.0.0.txt + * # Date: 2019-11-27, 03:13:39 GMT + * # © 2019 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. * # For terms of use, see http://www.unicode.org/terms_of_use.html * # * # Unicode Character Database * # For documentation, see http://www.unicode.org/reports/tr44/ - * - * # IndicSyllabicCategory-11.0.0.txt - * # Date: 2018-05-21, 18:33:00 GMT [KW, RP] - * # © 2018 Unicode®, Inc. + * # IndicSyllabicCategory-13.0.0.txt + * # Date: 2019-07-22, 19:55:00 GMT [KW, RP] + * # © 2019 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. * # For terms of use, see http://www.unicode.org/terms_of_use.html * # @@ -53,20 +52,62 @@ * # Indic_Syllabic_Category are the following: * # * # Ahom, Balinese, Batak, Bengali, Bhaiksuki, Brahmi, Buginese, Buhid, - * # Chakma, Cham, Devanagari, Dogra, Grantha, Gujarati, Gunjala Gondi, - * # Gurmukhi, Hanunoo, Javanese, Kaithi, Kannada, Kayah Li, Kharoshthi, - * # Khmer, Khojki, Khudawadi, Lao, Lepcha, Limbu, Mahajani, Makasar, - * # Malayalam, Marchen, Masaram Gondi, Meetei Mayek, Modi, Multani, - * # Myanmar, Newa, New Tai Lue, Oriya, Phags-pa, Rejang, Saurashtra, - * # Sharada, Siddham, Sinhala, Soyombo, Sundanese, Syloti Nagri, - * # Tagalog, Tagbanwa, Tai Le, Tai Tham, Tai Viet, Takri, Tamil, - * # Telugu, Thai, Tibetan, Tirhuta, and Zanabazar Square. + * # Chakma, Cham, Devanagari, Dives Akuru, Dogra, Grantha, Gujarati, + * # Gunjala Gondi, Gurmukhi, Hanunoo, Javanese, Kaithi, Kannada, + * # Kayah Li, Kharoshthi, Khmer, Khojki, Khudawadi, Lao, Lepcha, Limbu, + * # Mahajani, Makasar, Malayalam, Marchen, Masaram Gondi, Meetei Mayek, + * # Modi, Multani, Myanmar, Nandinagari, Newa, New Tai Lue, Oriya, + * # Phags-pa, Rejang, Saurashtra, Sharada, Siddham, Sinhala, Soyombo, + * # Sundanese, Syloti Nagri, Tagalog, Tagbanwa, Tai Le, Tai Tham, + * # Tai Viet, Takri, Tamil, Telugu, Thai, Tibetan, Tirhuta, and + * # Zanabazar Square. * # * # All characters for all other scripts not in that list * # take the default value for this property, unless they * # are individually listed in this data file. * # - * + * # EastAsianWidth-13.0.0.txt + * # Date: 2029-01-21, 18:14:00 GMT [KW, LI] + * # © 2020 Unicode®, Inc. + * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. + * # For terms of use, see http://www.unicode.org/terms_of_use.html + * # + * # Unicode Character Database + * # For documentation, see http://www.unicode.org/reports/tr44/ + * # + * # East_Asian_Width Property + * # + * # This file is a normative contributory data file in the + * # Unicode Character Database. + * # + * # The format is two fields separated by a semicolon. + * # Field 0: Unicode code point value or range of code point values + * # Field 1: East_Asian_Width property, consisting of one of the following values: + * # "A", "F", "H", "N", "Na", "W" + * # - All code points, assigned or unassigned, that are not listed + * # explicitly are given the value "N". + * # - The unassigned code points in the following blocks default to "W": + * # CJK Unified Ideographs Extension A: U+3400..U+4DBF + * # CJK Unified Ideographs: U+4E00..U+9FFF + * # CJK Compatibility Ideographs: U+F900..U+FAFF + * # - All undesignated code points in Planes 2 and 3, whether inside or + * # outside of allocated blocks, default to "W": + * # Plane 2: U+20000..U+2FFFD + * # Plane 3: U+30000..U+3FFFD + * # + * # Character ranges are specified as for other property files in the + * # Unicode Character Database. + * # + * # For legacy reasons, there are no spaces before or after the semicolon + * # which separates the two fields. The comments following the number sign + * # "#" list the General_Category property value or the L& alias of the + * # derived value LC, the Unicode character name or names, and, in lines + * # with ranges of code points, the code point count in square brackets. + * # + * # For more information, see UAX #11: East Asian Width, + * # at http://www.unicode.org/reports/tr11/ + * # + * # @missing: 0000..10FFFF; N */ #ifndef PANGO_BREAK_TABLE_H @@ -78,112 +119,130 @@ static inline gboolean _pango_is_STerm (gunichar wc) { - if ((wc >= 0x0021 && wc <= 0x1803)) + if ((wc >= 0x0021 && wc <= 0x1809)) { if (wc == 0x0021 || wc == 0x003F || wc == 0x0589 || (wc >= 0x061E && wc <= 0x061F)) return TRUE; - if (wc == 0x06D4 || - (wc >= 0x0700 && wc <= 0x0702) || wc == 0x07F9 || wc == 0x0837) - return TRUE; - if (wc == 0x0839 || - (wc >= 0x083D && wc <= 0x083E) || - (wc >= 0x0964 && wc <= 0x0965) || (wc >= 0x104A && wc <= 0x104B)) - return TRUE; - if ((wc >= 0x1362 && wc <= 0x1803)) + if ((wc >= 0x06D4 && wc <= 0x0839)) { - if (wc == 0x1362) + if (wc == 0x06D4) + return TRUE; + if ((wc >= 0x0700 && wc <= 0x0702)) + return TRUE; + if (wc == 0x07F9) return TRUE; + if (wc == 0x0837 || wc == 0x0839) + return TRUE; + return FALSE; + } + if ((wc >= 0x083D && wc <= 0x083E) || + (wc >= 0x0964 && wc <= 0x0965) || + (wc >= 0x104A && wc <= 0x104B) || wc == 0x1362) + return TRUE; + if ((wc >= 0x1367 && wc <= 0x1809)) + { if ((wc >= 0x1367 && wc <= 0x1368)) return TRUE; if (wc == 0x166E) return TRUE; - if ((wc >= 0x1735 && wc <= 0x1736) || wc == 0x1803) + if ((wc >= 0x1735 && wc <= 0x1736)) + return TRUE; + if (wc == 0x1803 || wc == 0x1809) return TRUE; return FALSE; } return FALSE; } - if ((wc >= 0x1809 && wc <= 0xA8CF)) + if ((wc >= 0x1944 && wc <= 0xA92F)) { - if (wc == 0x1809 || - (wc >= 0x1944 && wc <= 0x1945) || - (wc >= 0x1AA8 && wc <= 0x1AAB) || (wc >= 0x1B5A && wc <= 0x1B5B)) + if ((wc >= 0x1944 && wc <= 0x1945) || + (wc >= 0x1AA8 && wc <= 0x1AAB) || + (wc >= 0x1B5A && wc <= 0x1B5B) || (wc >= 0x1B5E && wc <= 0x1B5F)) return TRUE; - if ((wc >= 0x1B5E && wc <= 0x2049)) + if ((wc >= 0x1C3B && wc <= 0x2E2E)) { - if ((wc >= 0x1B5E && wc <= 0x1B5F)) - return TRUE; if ((wc >= 0x1C3B && wc <= 0x1C3C)) return TRUE; if ((wc >= 0x1C7E && wc <= 0x1C7F)) return TRUE; - if ((wc >= 0x203C && wc <= 0x203D) || - (wc >= 0x2047 && wc <= 0x2049)) + if ((wc >= 0x203C && wc <= 0x203D)) + return TRUE; + if ((wc >= 0x2047 && wc <= 0x2049) || wc == 0x2E2E) return TRUE; return FALSE; } - if (wc == 0x2E2E || wc == 0x2E3C || wc == 0x3002 || wc == 0xA4FF) + if (wc == 0x2E3C || + wc == 0x3002 || wc == 0xA4FF || (wc >= 0xA60E && wc <= 0xA60F)) return TRUE; - if ((wc >= 0xA60E && wc <= 0xA8CF)) + if ((wc >= 0xA6F3 && wc <= 0xA92F)) { - if ((wc >= 0xA60E && wc <= 0xA60F)) - return TRUE; if (wc == 0xA6F3) return TRUE; if (wc == 0xA6F7) return TRUE; - if ((wc >= 0xA876 && wc <= 0xA877) || - (wc >= 0xA8CE && wc <= 0xA8CF)) + if ((wc >= 0xA876 && wc <= 0xA877)) + return TRUE; + if ((wc >= 0xA8CE && wc <= 0xA8CF) || wc == 0xA92F) return TRUE; return FALSE; } return FALSE; } - if ((wc >= 0xA92F && wc <= 0x111DF)) + if ((wc >= 0xA9C8 && wc <= 0x1123C)) { - if (wc == 0xA92F || - (wc >= 0xA9C8 && wc <= 0xA9C9) || - (wc >= 0xAA5D && wc <= 0xAA5F) || (wc >= 0xAAF0 && wc <= 0xAAF1)) - return TRUE; - if (wc == 0xABEB || - (wc >= 0xFE56 && wc <= 0xFE57) || wc == 0xFF01 || wc == 0xFF1F) + if ((wc >= 0xA9C8 && wc <= 0xA9C9) || + (wc >= 0xAA5D && wc <= 0xAA5F) || + (wc >= 0xAAF0 && wc <= 0xAAF1) || wc == 0xABEB) return TRUE; - if (wc == 0xFF61 || - (wc >= 0x10A56 && wc <= 0x10A57) || - (wc >= 0x10F55 && wc <= 0x10F59) || - (wc >= 0x11047 && wc <= 0x11048)) - return TRUE; - if ((wc >= 0x110BE && wc <= 0x111DF)) + if ((wc >= 0xFE56 && wc <= 0x10A57)) { - if ((wc >= 0x110BE && wc <= 0x110C1)) + if ((wc >= 0xFE56 && wc <= 0xFE57)) + return TRUE; + if (wc == 0xFF01) + return TRUE; + if (wc == 0xFF1F) return TRUE; - if ((wc >= 0x11141 && wc <= 0x11143)) + if (wc == 0xFF61 || (wc >= 0x10A56 && wc <= 0x10A57)) return TRUE; + return FALSE; + } + if ((wc >= 0x10F55 && wc <= 0x10F59) || + (wc >= 0x11047 && wc <= 0x11048) || + (wc >= 0x110BE && wc <= 0x110C1) || + (wc >= 0x11141 && wc <= 0x11143)) + return TRUE; + if ((wc >= 0x111C5 && wc <= 0x1123C)) + { if ((wc >= 0x111C5 && wc <= 0x111C6)) return TRUE; - if (wc == 0x111CD || (wc >= 0x111DE && wc <= 0x111DF)) + if (wc == 0x111CD) + return TRUE; + if ((wc >= 0x111DE && wc <= 0x111DF)) + return TRUE; + if ((wc >= 0x11238 && wc <= 0x11239) || + (wc >= 0x1123B && wc <= 0x1123C)) return TRUE; return FALSE; } return FALSE; } - if ((wc >= 0x11238 && wc <= 0x1DA88)) + if ((wc >= 0x112A9 && wc <= 0x1DA88)) { - if ((wc >= 0x11238 && wc <= 0x11239) || - (wc >= 0x1123B && wc <= 0x1123C) || - wc == 0x112A9 || (wc >= 0x1144B && wc <= 0x1144C)) + if (wc == 0x112A9 || + (wc >= 0x1144B && wc <= 0x1144C) || + (wc >= 0x115C2 && wc <= 0x115C3) || + (wc >= 0x115C9 && wc <= 0x115D7)) return TRUE; - if ((wc >= 0x115C2 && wc <= 0x11A43)) + if ((wc >= 0x11641 && wc <= 0x11A43)) { - if ((wc >= 0x115C2 && wc <= 0x115C3)) + if ((wc >= 0x11641 && wc <= 0x11642)) return TRUE; - if ((wc >= 0x115C9 && wc <= 0x115D7)) + if ((wc >= 0x1173C && wc <= 0x1173E)) return TRUE; - if ((wc >= 0x11641 && wc <= 0x11642)) + if (wc == 0x11944) return TRUE; - if ((wc >= 0x1173C && wc <= 0x1173E) || - (wc >= 0x11A42 && wc <= 0x11A43)) + if (wc == 0x11946 || (wc >= 0x11A42 && wc <= 0x11A43)) return TRUE; return FALSE; } @@ -232,7 +291,7 @@ _pango_is_Virama (gunichar wc) return TRUE; if (wc == 0x0DCA) return TRUE; - if (wc == 0x1B44 || wc == 0xA8C4) + if (wc == 0x1B44 || wc == 0xA806 || wc == 0xA8C4) return TRUE; return FALSE; } @@ -250,13 +309,13 @@ _pango_is_Virama (gunichar wc) } if ((wc >= 0x11442 && wc <= 0x11C3F)) { - if (wc == 0x11442) + if (wc == 0x11442 || wc == 0x114C2) return TRUE; - if (wc == 0x114C2 || wc == 0x115BF) + if (wc == 0x115BF || wc == 0x1163F) return TRUE; - if (wc == 0x1163F) + if (wc == 0x116B6 || wc == 0x11839) return TRUE; - if (wc == 0x116B6 || wc == 0x11839 || wc == 0x11C3F) + if (wc == 0x119E0 || wc == 0x11C3F) return TRUE; return FALSE; } @@ -266,258 +325,257 @@ _pango_is_Virama (gunichar wc) static inline gboolean _pango_is_Vowel_Dependent (gunichar wc) { - if ((wc >= 0x093A && wc <= 0x0C63)) + if ((wc >= 0x093A && wc <= 0x0CC8)) { - if ((wc >= 0x093A && wc <= 0x09C8)) + if ((wc >= 0x093A && wc <= 0x09CC)) { - if ((wc >= 0x093A && wc <= 0x093B)) - return TRUE; - if ((wc >= 0x093E && wc <= 0x094C) || - (wc >= 0x094E && wc <= 0x094F)) + if ((wc >= 0x093A && wc <= 0x093B) || + (wc >= 0x093E && wc <= 0x094C)) return TRUE; - if ((wc >= 0x0955 && wc <= 0x0957)) + if ((wc >= 0x094E && wc <= 0x094F) || + (wc >= 0x0955 && wc <= 0x0957)) return TRUE; if ((wc >= 0x0962 && wc <= 0x0963) || - (wc >= 0x09BE && wc <= 0x09C4) || - (wc >= 0x09C7 && wc <= 0x09C8)) + (wc >= 0x09BE && wc <= 0x09C4)) + return TRUE; + if ((wc >= 0x09C7 && wc <= 0x09C8) || + (wc >= 0x09CB && wc <= 0x09CC)) return TRUE; return FALSE; } - if ((wc >= 0x09CB && wc <= 0x0AC9)) + if ((wc >= 0x09D7 && wc <= 0x0ACC)) { - if ((wc >= 0x09CB && wc <= 0x09CC) || wc == 0x09D7) + if (wc == 0x09D7 || (wc >= 0x09E2 && wc <= 0x09E3)) return TRUE; - if ((wc >= 0x09E2 && wc <= 0x09E3) || - (wc >= 0x0A3E && wc <= 0x0A42)) + if ((wc >= 0x0A3E && wc <= 0x0A42) || + (wc >= 0x0A47 && wc <= 0x0A48)) return TRUE; - if ((wc >= 0x0A47 && wc <= 0x0A48) || - (wc >= 0x0A4B && wc <= 0x0A4C)) + if ((wc >= 0x0A4B && wc <= 0x0A4C) || + (wc >= 0x0ABE && wc <= 0x0AC5)) return TRUE; - if ((wc >= 0x0ABE && wc <= 0x0AC5) || - (wc >= 0x0AC7 && wc <= 0x0AC9)) + if ((wc >= 0x0AC7 && wc <= 0x0AC9) || + (wc >= 0x0ACB && wc <= 0x0ACC)) return TRUE; return FALSE; } - if ((wc >= 0x0ACB && wc <= 0x0B63)) + if ((wc >= 0x0AE2 && wc <= 0x0BC8)) { - if ((wc >= 0x0ACB && wc <= 0x0ACC)) - return TRUE; if ((wc >= 0x0AE2 && wc <= 0x0AE3) || (wc >= 0x0B3E && wc <= 0x0B44)) return TRUE; - if ((wc >= 0x0B47 && wc <= 0x0B48)) + if ((wc >= 0x0B47 && wc <= 0x0B48) || + (wc >= 0x0B4B && wc <= 0x0B4C)) return TRUE; - if ((wc >= 0x0B4B && wc <= 0x0B4C) || - (wc >= 0x0B56 && wc <= 0x0B57) || + if ((wc >= 0x0B55 && wc <= 0x0B57) || (wc >= 0x0B62 && wc <= 0x0B63)) return TRUE; - return FALSE; - } - if ((wc >= 0x0BBE && wc <= 0x0C63)) - { if ((wc >= 0x0BBE && wc <= 0x0BC2) || (wc >= 0x0BC6 && wc <= 0x0BC8)) return TRUE; + return FALSE; + } + if ((wc >= 0x0BCA && wc <= 0x0CC8)) + { if ((wc >= 0x0BCA && wc <= 0x0BCC) || wc == 0x0BD7) return TRUE; if ((wc >= 0x0C3E && wc <= 0x0C44) || (wc >= 0x0C46 && wc <= 0x0C48)) return TRUE; if ((wc >= 0x0C4A && wc <= 0x0C4C) || - (wc >= 0x0C55 && wc <= 0x0C56) || - (wc >= 0x0C62 && wc <= 0x0C63)) + (wc >= 0x0C55 && wc <= 0x0C56)) + return TRUE; + if ((wc >= 0x0C62 && wc <= 0x0C63) || + (wc >= 0x0CBE && wc <= 0x0CC4) || + (wc >= 0x0CC6 && wc <= 0x0CC8)) return TRUE; return FALSE; } return FALSE; } - if ((wc >= 0x0CBE && wc <= 0x1733)) + if ((wc >= 0x0CCA && wc <= 0x17C8)) { - if ((wc >= 0x0CBE && wc <= 0x0D48)) + if ((wc >= 0x0CCA && wc <= 0x0D63)) { - if ((wc >= 0x0CBE && wc <= 0x0CC4)) + if ((wc >= 0x0CCA && wc <= 0x0CCC) || + (wc >= 0x0CD5 && wc <= 0x0CD6)) return TRUE; - if ((wc >= 0x0CC6 && wc <= 0x0CC8) || - (wc >= 0x0CCA && wc <= 0x0CCC)) + if ((wc >= 0x0CE2 && wc <= 0x0CE3) || + (wc >= 0x0D3E && wc <= 0x0D44)) return TRUE; - if ((wc >= 0x0CD5 && wc <= 0x0CD6)) + if ((wc >= 0x0D46 && wc <= 0x0D48) || + (wc >= 0x0D4A && wc <= 0x0D4C)) return TRUE; - if ((wc >= 0x0CE2 && wc <= 0x0CE3) || - (wc >= 0x0D3E && wc <= 0x0D44) || - (wc >= 0x0D46 && wc <= 0x0D48)) + if (wc == 0x0D57 || (wc >= 0x0D62 && wc <= 0x0D63)) return TRUE; return FALSE; } - if ((wc >= 0x0D4A && wc <= 0x0E39)) + if ((wc >= 0x0DCF && wc <= 0x0EB9)) { - if ((wc >= 0x0D4A && wc <= 0x0D4C) || wc == 0x0D57) + if ((wc >= 0x0DCF && wc <= 0x0DD4) || wc == 0x0DD6) return TRUE; - if ((wc >= 0x0D62 && wc <= 0x0D63) || - (wc >= 0x0DCF && wc <= 0x0DD4)) + if ((wc >= 0x0DD8 && wc <= 0x0DDF) || + (wc >= 0x0DF2 && wc <= 0x0DF3)) return TRUE; - if (wc == 0x0DD6 || (wc >= 0x0DD8 && wc <= 0x0DDF)) + if ((wc >= 0x0E30 && wc <= 0x0E39) || + (wc >= 0x0E40 && wc <= 0x0E45)) return TRUE; - if ((wc >= 0x0DF2 && wc <= 0x0DF3) || - (wc >= 0x0E30 && wc <= 0x0E39)) + if (wc == 0x0E47 || (wc >= 0x0EB0 && wc <= 0x0EB9)) return TRUE; return FALSE; } - if ((wc >= 0x0E40 && wc <= 0x0F81)) + if ((wc >= 0x0EBB && wc <= 0x1068)) { - if ((wc >= 0x0E40 && wc <= 0x0E45)) + if (wc == 0x0EBB || (wc >= 0x0EC0 && wc <= 0x0EC4)) return TRUE; - if (wc == 0x0E47 || (wc >= 0x0EB0 && wc <= 0x0EB9)) - return TRUE; - if (wc == 0x0EBB) - return TRUE; - if ((wc >= 0x0EC0 && wc <= 0x0EC4) || - (wc >= 0x0F71 && wc <= 0x0F7D) || + if ((wc >= 0x0F71 && wc <= 0x0F7D) || (wc >= 0x0F80 && wc <= 0x0F81)) return TRUE; - return FALSE; - } - if ((wc >= 0x102B && wc <= 0x1733)) - { if ((wc >= 0x102B && wc <= 0x1035) || (wc >= 0x1056 && wc <= 0x1059)) return TRUE; if (wc == 0x1062 || (wc >= 0x1067 && wc <= 0x1068)) return TRUE; + return FALSE; + } + if ((wc >= 0x1071 && wc <= 0x17C8)) + { if ((wc >= 0x1071 && wc <= 0x1074) || (wc >= 0x1083 && wc <= 0x1086)) return TRUE; if ((wc >= 0x109C && wc <= 0x109D) || - (wc >= 0x1712 && wc <= 0x1713) || - (wc >= 0x1732 && wc <= 0x1733)) + (wc >= 0x1712 && wc <= 0x1713)) + return TRUE; + if ((wc >= 0x1732 && wc <= 0x1733) || + (wc >= 0x1752 && wc <= 0x1753)) + return TRUE; + if ((wc >= 0x1772 && wc <= 0x1773) || + (wc >= 0x17B6 && wc <= 0x17C5) || wc == 0x17C8) return TRUE; return FALSE; } return FALSE; } - if ((wc >= 0x1752 && wc <= 0x111BF)) + if ((wc >= 0x1920 && wc <= 0x11344)) { - if ((wc >= 0x1752 && wc <= 0x19C0)) + if ((wc >= 0x1920 && wc <= 0x1BEF)) { - if ((wc >= 0x1752 && wc <= 0x1753)) + if ((wc >= 0x1920 && wc <= 0x1928) || wc == 0x193A) return TRUE; - if ((wc >= 0x1772 && wc <= 0x1773) || - (wc >= 0x17B6 && wc <= 0x17C5)) + if ((wc >= 0x19B0 && wc <= 0x19C0) || + (wc >= 0x1A17 && wc <= 0x1A1B)) return TRUE; - if (wc == 0x17C8) + if ((wc >= 0x1A61 && wc <= 0x1A73) || + (wc >= 0x1B35 && wc <= 0x1B43)) return TRUE; - if ((wc >= 0x1920 && wc <= 0x1928) || - wc == 0x193A || (wc >= 0x19B0 && wc <= 0x19C0)) + if ((wc >= 0x1BA4 && wc <= 0x1BA9) || + (wc >= 0x1BE7 && wc <= 0x1BEF)) return TRUE; return FALSE; } - if ((wc >= 0x1A17 && wc <= 0xA8C3)) + if ((wc >= 0x1C26 && wc <= 0xA9E5)) { - if ((wc >= 0x1A17 && wc <= 0x1A1B) || - (wc >= 0x1A61 && wc <= 0x1A73)) - return TRUE; - if ((wc >= 0x1B35 && wc <= 0x1B43) || - (wc >= 0x1BA4 && wc <= 0x1BA9)) - return TRUE; - if ((wc >= 0x1BE7 && wc <= 0x1BEF) || - (wc >= 0x1C26 && wc <= 0x1C2C)) + if ((wc >= 0x1C26 && wc <= 0x1C2C) || wc == 0xA802) return TRUE; if ((wc >= 0xA823 && wc <= 0xA827) || (wc >= 0xA8B5 && wc <= 0xA8C3)) return TRUE; + if (wc == 0xA8FF || (wc >= 0xA947 && wc <= 0xA94E)) + return TRUE; + if ((wc >= 0xA9B4 && wc <= 0xA9BC) || wc == 0xA9E5) + return TRUE; return FALSE; } - if ((wc >= 0xA8FF && wc <= 0xAAEF)) + if ((wc >= 0xAA29 && wc <= 0x11045)) { - if (wc == 0xA8FF) + if ((wc >= 0xAA29 && wc <= 0xAA32) || + (wc >= 0xAAB0 && wc <= 0xAABE)) return TRUE; - if ((wc >= 0xA947 && wc <= 0xA94E) || - (wc >= 0xA9B4 && wc <= 0xA9BC)) + if ((wc >= 0xAAEB && wc <= 0xAAEF) || + (wc >= 0xABE3 && wc <= 0xABEA)) return TRUE; - if (wc == 0xA9E5) + if ((wc >= 0x10A01 && wc <= 0x10A03) || + (wc >= 0x10A05 && wc <= 0x10A06)) return TRUE; - if ((wc >= 0xAA29 && wc <= 0xAA32) || - (wc >= 0xAAB0 && wc <= 0xAABE) || - (wc >= 0xAAEB && wc <= 0xAAEF)) + if ((wc >= 0x10A0C && wc <= 0x10A0D) || + (wc >= 0x11038 && wc <= 0x11045)) return TRUE; return FALSE; } - if ((wc >= 0xABE3 && wc <= 0x111BF)) + if ((wc >= 0x110B0 && wc <= 0x11344)) { - if ((wc >= 0xABE3 && wc <= 0xABEA) || - (wc >= 0x10A01 && wc <= 0x10A03)) + if ((wc >= 0x110B0 && wc <= 0x110B8) || + (wc >= 0x11127 && wc <= 0x11132)) return TRUE; - if ((wc >= 0x10A05 && wc <= 0x10A06) || - (wc >= 0x10A0C && wc <= 0x10A0D)) + if ((wc >= 0x11145 && wc <= 0x11146) || + (wc >= 0x111B3 && wc <= 0x111BF)) return TRUE; - if ((wc >= 0x11038 && wc <= 0x11045) || - (wc >= 0x110B0 && wc <= 0x110B8)) + if ((wc >= 0x111CB && wc <= 0x111CC) || wc == 0x111CE) return TRUE; - if ((wc >= 0x11127 && wc <= 0x11132) || - (wc >= 0x11145 && wc <= 0x11146) || - (wc >= 0x111B3 && wc <= 0x111BF)) + if ((wc >= 0x1122C && wc <= 0x11233) || + (wc >= 0x112E0 && wc <= 0x112E8) || + (wc >= 0x1133E && wc <= 0x11344)) return TRUE; return FALSE; } return FALSE; } - if ((wc >= 0x111CB && wc <= 0x11EF6)) + if ((wc >= 0x11347 && wc <= 0x11EF6)) { - if ((wc >= 0x111CB && wc <= 0x11363)) + if ((wc >= 0x11347 && wc <= 0x115BB)) { - if ((wc >= 0x111CB && wc <= 0x111CC) || - (wc >= 0x1122C && wc <= 0x11233)) - return TRUE; - if ((wc >= 0x112E0 && wc <= 0x112E8) || - (wc >= 0x1133E && wc <= 0x11344)) - return TRUE; if ((wc >= 0x11347 && wc <= 0x11348) || (wc >= 0x1134B && wc <= 0x1134C)) return TRUE; if (wc == 0x11357 || (wc >= 0x11362 && wc <= 0x11363)) return TRUE; - return FALSE; - } - if ((wc >= 0x11435 && wc <= 0x116B5)) - { if ((wc >= 0x11435 && wc <= 0x11441) || (wc >= 0x114B0 && wc <= 0x114BE)) return TRUE; if ((wc >= 0x115AF && wc <= 0x115B5) || (wc >= 0x115B8 && wc <= 0x115BB)) return TRUE; + return FALSE; + } + if ((wc >= 0x115DC && wc <= 0x11938)) + { if ((wc >= 0x115DC && wc <= 0x115DD) || (wc >= 0x11630 && wc <= 0x1163C)) return TRUE; if (wc == 0x11640 || (wc >= 0x116AD && wc <= 0x116B5)) return TRUE; + if ((wc >= 0x11720 && wc <= 0x1172A) || + (wc >= 0x1182C && wc <= 0x11836)) + return TRUE; + if ((wc >= 0x11930 && wc <= 0x11935) || + (wc >= 0x11937 && wc <= 0x11938)) + return TRUE; return FALSE; } - if ((wc >= 0x11720 && wc <= 0x11D36)) + if ((wc >= 0x119D1 && wc <= 0x11CB4)) { - if ((wc >= 0x11720 && wc <= 0x1172A) || - (wc >= 0x1182C && wc <= 0x11836)) + if ((wc >= 0x119D1 && wc <= 0x119D7) || + (wc >= 0x119DA && wc <= 0x119DD)) return TRUE; - if ((wc >= 0x11A01 && wc <= 0x11A0A) || - (wc >= 0x11A51 && wc <= 0x11A5B)) + if (wc == 0x119E4 || (wc >= 0x11A01 && wc <= 0x11A0A)) return TRUE; - if ((wc >= 0x11C2F && wc <= 0x11C36) || - (wc >= 0x11C38 && wc <= 0x11C3B)) + if ((wc >= 0x11A51 && wc <= 0x11A5B) || + (wc >= 0x11C2F && wc <= 0x11C36)) return TRUE; - if ((wc >= 0x11CB0 && wc <= 0x11CB4) || - (wc >= 0x11D31 && wc <= 0x11D36)) + if ((wc >= 0x11C38 && wc <= 0x11C3B) || + (wc >= 0x11CB0 && wc <= 0x11CB4)) return TRUE; return FALSE; } - if ((wc >= 0x11D3A && wc <= 0x11EF6)) + if ((wc >= 0x11D31 && wc <= 0x11EF6)) { - if (wc == 0x11D3A || (wc >= 0x11D3C && wc <= 0x11D3D)) + if ((wc >= 0x11D31 && wc <= 0x11D36) || wc == 0x11D3A) return TRUE; - if (wc == 0x11D3F || wc == 0x11D43) + if ((wc >= 0x11D3C && wc <= 0x11D3D) || wc == 0x11D3F) return TRUE; - if ((wc >= 0x11D8A && wc <= 0x11D8E) || - (wc >= 0x11D90 && wc <= 0x11D91)) + if (wc == 0x11D43 || (wc >= 0x11D8A && wc <= 0x11D8E)) return TRUE; - if ((wc >= 0x11D93 && wc <= 0x11D94) || + if ((wc >= 0x11D90 && wc <= 0x11D91) || + (wc >= 0x11D93 && wc <= 0x11D94) || (wc >= 0x11EF3 && wc <= 0x11EF6)) return TRUE; return FALSE; @@ -527,6 +585,276 @@ _pango_is_Vowel_Dependent (gunichar wc) return FALSE; } +static inline gboolean +_pango_is_Consonant_Prefixed (gunichar wc) +{ + if ((wc >= 0x111C2 && wc <= 0x111C3) || + wc == 0x1193F || wc == 0x11A3A || (wc >= 0x11A84 && wc <= 0x11A89)) + return TRUE; + return FALSE; +} + +static inline gboolean +_pango_is_Consonant_Preceding_Repha (gunichar wc) +{ + if (wc == 0x0D4E || wc == 0x11941 || wc == 0x11D46) + return TRUE; + return FALSE; +} + +static inline gboolean +_pango_is_EastAsianWide (gunichar wc) +{ + if ((wc >= 0x1100 && wc <= 0x2797)) + { + if ((wc >= 0x1100 && wc <= 0x23F3)) + { + if ((wc >= 0x1100 && wc <= 0x115F)) + return TRUE; + if (wc == 0x20A9 || (wc >= 0x231A && wc <= 0x231B)) + return TRUE; + if ((wc >= 0x2329 && wc <= 0x232A)) + return TRUE; + if ((wc >= 0x23E9 && wc <= 0x23EC) || wc == 0x23F0 || wc == 0x23F3) + return TRUE; + return FALSE; + } + if ((wc >= 0x25FD && wc <= 0x26BE)) + { + if ((wc >= 0x25FD && wc <= 0x25FE) || + (wc >= 0x2614 && wc <= 0x2615)) + return TRUE; + if ((wc >= 0x2648 && wc <= 0x2653) || wc == 0x267F) + return TRUE; + if (wc == 0x2693 || wc == 0x26A1) + return TRUE; + if ((wc >= 0x26AA && wc <= 0x26AB) || + (wc >= 0x26BD && wc <= 0x26BE)) + return TRUE; + return FALSE; + } + if ((wc >= 0x26C4 && wc <= 0x26FA)) + { + if ((wc >= 0x26C4 && wc <= 0x26C5)) + return TRUE; + if (wc == 0x26CE || wc == 0x26D4) + return TRUE; + if (wc == 0x26EA) + return TRUE; + if ((wc >= 0x26F2 && wc <= 0x26F3) || wc == 0x26F5 || wc == 0x26FA) + return TRUE; + return FALSE; + } + if ((wc >= 0x26FD && wc <= 0x2797)) + { + if (wc == 0x26FD || wc == 0x2705) + return TRUE; + if ((wc >= 0x270A && wc <= 0x270B) || wc == 0x2728) + return TRUE; + if (wc == 0x274C || wc == 0x274E) + return TRUE; + if ((wc >= 0x2753 && wc <= 0x2755) || + wc == 0x2757 || (wc >= 0x2795 && wc <= 0x2797)) + return TRUE; + return FALSE; + } + return FALSE; + } + if ((wc >= 0x27B0 && wc <= 0xFFC7)) + { + if ((wc >= 0x27B0 && wc <= 0x2EF3)) + { + if (wc == 0x27B0) + return TRUE; + if (wc == 0x27BF || (wc >= 0x2B1B && wc <= 0x2B1C)) + return TRUE; + if (wc == 0x2B50) + return TRUE; + if (wc == 0x2B55 || + (wc >= 0x2E80 && wc <= 0x2E99) || + (wc >= 0x2E9B && wc <= 0x2EF3)) + return TRUE; + return FALSE; + } + if ((wc >= 0x2F00 && wc <= 0x318E)) + { + if ((wc >= 0x2F00 && wc <= 0x2FD5) || + (wc >= 0x2FF0 && wc <= 0x2FFB)) + return TRUE; + if (wc == 0x3000 || (wc >= 0x3001 && wc <= 0x303E)) + return TRUE; + if ((wc >= 0x3041 && wc <= 0x3096) || + (wc >= 0x3099 && wc <= 0x30FF)) + return TRUE; + if ((wc >= 0x3105 && wc <= 0x312F) || + (wc >= 0x3131 && wc <= 0x318E)) + return TRUE; + return FALSE; + } + if ((wc >= 0x3190 && wc <= 0xA97C)) + { + if ((wc >= 0x3190 && wc <= 0x31E3)) + return TRUE; + if ((wc >= 0x31F0 && wc <= 0x321E) || + (wc >= 0x3220 && wc <= 0x3247)) + return TRUE; + if ((wc >= 0x3250 && wc <= 0x4DBF)) + return TRUE; + if ((wc >= 0x4E00 && wc <= 0xA48C) || + (wc >= 0xA490 && wc <= 0xA4C6) || + (wc >= 0xA960 && wc <= 0xA97C)) + return TRUE; + return FALSE; + } + if ((wc >= 0xAC00 && wc <= 0xFFC7)) + { + if ((wc >= 0xAC00 && wc <= 0xD7A3) || + (wc >= 0xF900 && wc <= 0xFAFF)) + return TRUE; + if ((wc >= 0xFE10 && wc <= 0xFE19) || + (wc >= 0xFE30 && wc <= 0xFE52)) + return TRUE; + if ((wc >= 0xFE54 && wc <= 0xFE66) || + (wc >= 0xFE68 && wc <= 0xFE6B)) + return TRUE; + if ((wc >= 0xFF01 && wc <= 0xFF60) || + (wc >= 0xFF61 && wc <= 0xFFBE) || + (wc >= 0xFFC2 && wc <= 0xFFC7)) + return TRUE; + return FALSE; + } + return FALSE; + } + if ((wc >= 0xFFCA && wc <= 0x1F3F4)) + { + if ((wc >= 0xFFCA && wc <= 0x16FF1)) + { + if ((wc >= 0xFFCA && wc <= 0xFFCF)) + return TRUE; + if ((wc >= 0xFFD2 && wc <= 0xFFD7) || + (wc >= 0xFFDA && wc <= 0xFFDC)) + return TRUE; + if ((wc >= 0xFFE0 && wc <= 0xFFE6)) + return TRUE; + if ((wc >= 0xFFE8 && wc <= 0xFFEE) || + (wc >= 0x16FE0 && wc <= 0x16FE4) || + (wc >= 0x16FF0 && wc <= 0x16FF1)) + return TRUE; + return FALSE; + } + if ((wc >= 0x17000 && wc <= 0x1F004)) + { + if ((wc >= 0x17000 && wc <= 0x187F7) || + (wc >= 0x18800 && wc <= 0x18CD5)) + return TRUE; + if ((wc >= 0x18D00 && wc <= 0x18D08) || + (wc >= 0x1B000 && wc <= 0x1B11E)) + return TRUE; + if ((wc >= 0x1B150 && wc <= 0x1B152) || + (wc >= 0x1B164 && wc <= 0x1B167)) + return TRUE; + if ((wc >= 0x1B170 && wc <= 0x1B2FB) || wc == 0x1F004) + return TRUE; + return FALSE; + } + if ((wc >= 0x1F0CF && wc <= 0x1F251)) + { + if (wc == 0x1F0CF) + return TRUE; + if (wc == 0x1F18E || (wc >= 0x1F191 && wc <= 0x1F19A)) + return TRUE; + if ((wc >= 0x1F200 && wc <= 0x1F202)) + return TRUE; + if ((wc >= 0x1F210 && wc <= 0x1F23B) || + (wc >= 0x1F240 && wc <= 0x1F248) || + (wc >= 0x1F250 && wc <= 0x1F251)) + return TRUE; + return FALSE; + } + if ((wc >= 0x1F260 && wc <= 0x1F3F4)) + { + if ((wc >= 0x1F260 && wc <= 0x1F265) || + (wc >= 0x1F300 && wc <= 0x1F320)) + return TRUE; + if ((wc >= 0x1F32D && wc <= 0x1F335) || + (wc >= 0x1F337 && wc <= 0x1F37C)) + return TRUE; + if ((wc >= 0x1F37E && wc <= 0x1F393) || + (wc >= 0x1F3A0 && wc <= 0x1F3CA)) + return TRUE; + if ((wc >= 0x1F3CF && wc <= 0x1F3D3) || + (wc >= 0x1F3E0 && wc <= 0x1F3F0) || wc == 0x1F3F4) + return TRUE; + return FALSE; + } + return FALSE; + } + if ((wc >= 0x1F3F8 && wc <= 0x3FFFD)) + { + if ((wc >= 0x1F3F8 && wc <= 0x1F57A)) + { + if ((wc >= 0x1F3F8 && wc <= 0x1F43E)) + return TRUE; + if (wc == 0x1F440 || (wc >= 0x1F442 && wc <= 0x1F4FC)) + return TRUE; + if ((wc >= 0x1F4FF && wc <= 0x1F53D)) + return TRUE; + if ((wc >= 0x1F54B && wc <= 0x1F54E) || + (wc >= 0x1F550 && wc <= 0x1F567) || wc == 0x1F57A) + return TRUE; + return FALSE; + } + if ((wc >= 0x1F595 && wc <= 0x1F6EC)) + { + if ((wc >= 0x1F595 && wc <= 0x1F596) || wc == 0x1F5A4) + return TRUE; + if ((wc >= 0x1F5FB && wc <= 0x1F64F) || + (wc >= 0x1F680 && wc <= 0x1F6C5)) + return TRUE; + if (wc == 0x1F6CC || (wc >= 0x1F6D0 && wc <= 0x1F6D2)) + return TRUE; + if ((wc >= 0x1F6D5 && wc <= 0x1F6D7) || + (wc >= 0x1F6EB && wc <= 0x1F6EC)) + return TRUE; + return FALSE; + } + if ((wc >= 0x1F6F4 && wc <= 0x1F9FF)) + { + if ((wc >= 0x1F6F4 && wc <= 0x1F6FC)) + return TRUE; + if ((wc >= 0x1F7E0 && wc <= 0x1F7EB) || + (wc >= 0x1F90C && wc <= 0x1F93A)) + return TRUE; + if ((wc >= 0x1F93C && wc <= 0x1F945)) + return TRUE; + if ((wc >= 0x1F947 && wc <= 0x1F978) || + (wc >= 0x1F97A && wc <= 0x1F9CB) || + (wc >= 0x1F9CD && wc <= 0x1F9FF)) + return TRUE; + return FALSE; + } + if ((wc >= 0x1FA70 && wc <= 0x3FFFD)) + { + if ((wc >= 0x1FA70 && wc <= 0x1FA74) || + (wc >= 0x1FA78 && wc <= 0x1FA7A)) + return TRUE; + if ((wc >= 0x1FA80 && wc <= 0x1FA86) || + (wc >= 0x1FA90 && wc <= 0x1FAA8)) + return TRUE; + if ((wc >= 0x1FAB0 && wc <= 0x1FAB6) || + (wc >= 0x1FAC0 && wc <= 0x1FAC2)) + return TRUE; + if ((wc >= 0x1FAD0 && wc <= 0x1FAD6) || + (wc >= 0x20000 && wc <= 0x2FFFD) || + (wc >= 0x30000 && wc <= 0x3FFFD)) + return TRUE; + return FALSE; + } + return FALSE; + } + return FALSE; +} + #endif /* PANGO_BREAK_TABLE_H */ /* == End of generated table == */ diff --git a/pango/pango-language.c b/pango/pango-language.c index 575d4652..ed8b0195 100644 --- a/pango/pango-language.c +++ b/pango/pango-language.c @@ -66,7 +66,7 @@ pango_language_get_private (PangoLanguage *language) if (!language) return NULL; - priv = (PangoLanguagePrivate *) ((char *)language - sizeof (PangoLanguagePrivate)); + priv = (PangoLanguagePrivate *) ((void *)((char *)language - sizeof (PangoLanguagePrivate))); if (G_UNLIKELY (priv->magic != PANGO_LANGUAGE_PRIVATE_MAGIC)) { @@ -331,7 +331,7 @@ pango_language_from_string (const char *language) G_LOCK_DEFINE_STATIC (lang_from_string); static GHashTable *hash = NULL; /* MT-safe */ PangoLanguagePrivate *priv; - char *result; + void *result; int len; char *p; @@ -354,7 +354,7 @@ pango_language_from_string (const char *language) g_assert (result); priv = (PangoLanguagePrivate *) result; - result += sizeof (*priv); + result = ((char *)result) + sizeof (*priv); pango_language_private_init (priv); @@ -749,7 +749,7 @@ parse_default_languages (void) { char *p, *p_copy; gboolean done = FALSE; - GArray *langs; + GPtrArray *langs; p = getenv ("PANGO_LANGUAGE"); @@ -761,34 +761,34 @@ parse_default_languages (void) p_copy = p = g_strdup (p); - langs = g_array_new (TRUE, FALSE, sizeof (PangoLanguage *)); + langs = g_ptr_array_new (); while (!done) { char *end = strpbrk (p, LANGUAGE_SEPARATORS); if (!end) - { - end = p + strlen (p); - done = TRUE; - } + { + end = p + strlen (p); + done = TRUE; + } else *end = '\0'; /* skip empty languages, and skip the language 'C' */ if (p != end && !(p + 1 == end && *p == 'C')) { - PangoLanguage *l = pango_language_from_string (p); - - g_array_append_val (langs, l); - } + PangoLanguage *l = pango_language_from_string (p); + + g_ptr_array_add (langs, l); + } if (!done) - p = end + 1; + p = end + 1; } g_free (p_copy); - return (PangoLanguage **) g_array_free (langs, FALSE); + return (PangoLanguage **) g_ptr_array_free (langs, FALSE); } static PangoLanguage * diff --git a/pango/pango-markup.c b/pango/pango-markup.c index cdea3a98..a67e10fd 100644 --- a/pango/pango-markup.c +++ b/pango/pango-markup.c @@ -56,165 +56,169 @@ * ]| * * Pango uses #GMarkup to parse this language, which means that XML - * features such as numeric character entities such as &#169; for + * features such as numeric character entities such as `©` for * © can be used too. * - * The root tag of a marked-up document is <markup>, but - * pango_parse_markup()allows you to omit this tag, so you will most - * likely never need to use it. The most general markup tag is <span>, + * The root tag of a marked-up document is `<markup>`, but + * pango_parse_markup() allows you to omit this tag, so you will most + * likely never need to use it. The most general markup tag is `<span>`, * then there are some convenience tags. * - * <span> has the following attributes: + * ## Span attributes * - * font_desc - * : A font description string, such as "Sans Italic 12". + * `<span>` has the following attributes: + * + * * `font_desc`: + * A font description string, such as "Sans Italic 12". * See pango_font_description_from_string() for a description of the * format of the string representation . Note that any other span * attributes will override this description. So if you have "Sans Italic" - * and also a style="normal" attribute, you will get Sans normal, + * and also a `style="normal"` attribute, you will get Sans normal, * not italic. * - * font_family - * : A font family name + * * `font_family`: + * A font family name * - * font_size, size - * : Font size in 1024ths of a point, or one of the absolute - * sizes 'xx-small', 'x-small', 'small', 'medium', 'large', - * 'x-large', 'xx-large', or one of the relative sizes 'smaller' - * or 'larger'. If you want to specify a absolute size, it's usually + * * `font_size`, `size`: + * Font size in 1024ths of a point, or one of the absolute + * sizes `xx-small`, `x-small`, `small`, `medium`, `large`, + * `x-large`, `xx-large`, or one of the relative sizes `smaller` + * or `larger`. If you want to specify a absolute size, it's usually * easier to take advantage of the ability to specify a partial - * font description using 'font'; you can use |font='12.5'| - * rather than |size='12800'|. + * font description using `font`; you can use `font='12.5'` + * rather than `size='12800'`. * - * font_style - * : One of 'normal', 'oblique', 'italic' + * * `font_style`: + * One of `normal`, `oblique`, `italic` * - * font_weight - * : One of 'ultralight', 'light', 'normal', 'bold', - * 'ultrabold', 'heavy', or a numeric weight + * * `font_weight`: + * One of `ultralight`, `light`, `normal`, `bold`, + * `ultrabold`, `heavy`, or a numeric weight * - * font_variant - * : One of 'normal' or 'smallcaps' + * * `font_variant`: + * One of `normal` or `smallcaps` * - * font_stretch, stretch - * : One of 'ultracondensed', 'extracondensed', 'condensed', - * 'semicondensed', 'normal', 'semiexpanded', 'expanded', - * 'extraexpanded', 'ultraexpanded' + * * `font_stretch`, `stretch`: + * One of `ultracondensed`, `extracondensed`, `condensed`, + * `semicondensed`, `normal`, `semiexpanded`, `expanded`, + * `extraexpanded`, `ultraexpanded` * - * font_features - * : A comma separated list of OpenType font feature + * * `font_features`: + * A comma-separated list of OpenType font feature * settings, in the same syntax as accepted by CSS. E.g: - * |font_features='dlig=1, -kern, afrc on'| + * `font_features='dlig=1, -kern, afrc on'` * - * foreground, fgcolor - * : An RGB color specification such as '#00FF00' or a color - * name such as 'red'. Since 1.38, an RGBA color specification such - * as '#00FF007F' will be interpreted as specifying both a foreground + * * `foreground`, `fgcolor`: + * An RGB color specification such as `#00FF00` or a color + * name such as `red`. Since 1.38, an RGBA color specification such + * as `#00FF007F` will be interpreted as specifying both a foreground * color and foreground alpha. * - * background, bgcolor - * : An RGB color specification such as '#00FF00' or a color - * name such as'red'. - * Since 1.38, an RGBA color specification such as '#00FF007F' will + * * `background`, `bgcolor`: + * An RGB color specification such as `#00FF00` or a color + * name such as `red`. + * Since 1.38, an RGBA color specification such as `#00FF007F` will * be interpreted as specifying both a background color and * background alpha. * - * alpha, fgalpha - * : An alpha value for the foreground color, either a plain - * integer between 1 and 65536 or a percentage value like '50%'. + * * `alpha`, `fgalpha`: + * An alpha value for the foreground color, either a plain + * integer between 1 and 65536 or a percentage value like `50%`. * - * background_alpha, bgalpha - * : An alpha value for the background color, either a plain - * integer between 1 and 65536 or a percentage value like '50%'. + * * `background_alpha`, `bgalpha`: + * An alpha value for the background color, either a plain + * integer between 1 and 65536 or a percentage value like `50%`. * - * underline - * : One of 'none', 'single', 'double', 'low', 'error', - * 'single-line', 'double-line' or 'error-line'. + * * `underline`: + * One of `none`, `single`, `double`, `low`, `error`, + * `single-line`, `double-line` or `error-line`. * - * underline_color - * : The color of underlines; an RGB color - * specification such as '#00FF00' or a color name such as 'red' + * * `underline_color`: + * The color of underlines; an RGB color + * specification such as `#00FF00` or a color name such as `red` * - * overline - * : One of 'none' or 'single' + * * `overline`: + * One of `none` or `single` * - * overline_color - * : The color of overlines; an RGB color - * specification such as '#00FF00' or a color name such as 'red' + * * `overline_color`: + * The color of overlines; an RGB color + * specification such as `#00FF00` or a color name such as `red` * - * rise - * : Vertical displacement, in Pango units. Can be negative for + * * `rise`: + * Vertical displacement, in Pango units. Can be negative for * subscript, positive for superscript. * - * strikethrough - * : 'true' or 'false' whether to strike through the text + * * `strikethrough` + * `true` or `false` whether to strike through the text * - * strikethrough_color - * : The color of strikethrough lines; an RGB - * color specification such as '#00FF00' or a color name such as 'red' + * * `strikethrough_color`: + * The color of strikethrough lines; an RGB + * color specification such as `#00FF00` or a color name such as `red` * - * fallback - * : 'true' or 'false' whether to enable fallback. If + * * `fallback`: + * `true` or `false` whether to enable fallback. If * disabled, then characters will only be used from the closest * matching font on the system. No fallback will be done to other * fonts on the system that might contain the characters in the text. * Fallback is enabled by default. Most applications should not * disable fallback. * - * allow_breaks - * : 'true' or 'false' whether to allow line breaks or not. If + * * `allow_breaks`: + * `true` or `false` whether to allow line breaks or not. If * not allowed, the range will be kept in a single run as far * as possible. Breaks are allowed by default. * - * insert_hyphens - * : 'true' or 'false' whether to insert hyphens when breaking + * * `insert_hyphens`:` + * `true` or `false` whether to insert hyphens when breaking * lines in the middle of a word. Hyphens are inserted by default. * - * show - * : A value determining how invisible characters are treated. - * Possible values are 'spaces', 'line-breaks', 'ignorables' - * or combinations, such as 'spaces|line-breaks'. + * * `show`: + * A value determining how invisible characters are treated. + * Possible values are `spaces`, `line-breaks`, `ignorables` + * or combinations, such as `spaces|line-breaks`. + * + * * `lang`: + * A language code, indicating the text language * - * lang - * : A language code, indicating the text language + * * `letter_spacing`: + * Inter-letter spacing in 1024ths of a point. * - * letter_spacing - * : Inter-letter spacing in 1024ths of a point. + * * `gravity`: + * One of `south`, `east`, `north`, `west`, `auto`. * - * gravity - * : One of 'south', 'east', 'north', 'west', 'auto'. + * * `gravity_hint`: + * One of `natural`, `strong`, `line`. * - * gravity_hint - * : One of 'natural', 'strong', 'line'. + * ## Convenience tags * * The following convenience tags are provided: * - * <b> - * : Bold + * * `<b>`: + * Bold * - * <big> - * : Makes font relatively larger, equivalent to <span size="larger"> + * * `<big>`: + * Makes font relatively larger, equivalent to `<span size="larger">` * - * <i> - * : Italic + * * `<i>`: + * Italic * - * <s> - * : Strikethrough + * * `<s>`: + * Strikethrough * - * <sub> - * : Subscript + * * `<sub>`: + * Subscript * - * <sup> - * : Superscript + * * `<sup>`: + * Superscript * - * <small> - * : Makes font relatively smaller, equivalent to <span size="smaller"> + * * `<small>`: + * Makes font relatively smaller, equivalent to `<span size="smaller">` * - * <tt> - * : Monospace + * * `<tt>`: + * Monospace * - * <u> - * : Underline + * * `<u>`: + * Underline */ /* FIXME */ diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c index 6c0786c5..07f81a88 100644 --- a/pango/pango-renderer.c +++ b/pango/pango-renderer.c @@ -227,7 +227,7 @@ draw_underline (PangoRenderer *renderer, rect->y + 2 * rect->height, rect->width, rect->height); - /* Fall through */ + G_GNUC_FALLTHROUGH; case PANGO_UNDERLINE_SINGLE: case PANGO_UNDERLINE_LOW: case PANGO_UNDERLINE_SINGLE_LINE: @@ -1096,15 +1096,22 @@ pango_renderer_default_draw_error_underline (PangoRenderer *renderer, int width, int height) { - int square = height / HEIGHT_SQUARES; - int unit_width = (HEIGHT_SQUARES - 1) * square; - int width_units = (width + unit_width / 2) / unit_width; + int square; + int unit_width; + int width_units; const PangoMatrix identity = PANGO_MATRIX_INIT; const PangoMatrix *matrix; double dx, dx0, dy0; PangoMatrix total; int i; + if (width <= 0 || height <= 0) + return; + + square = height / HEIGHT_SQUARES; + unit_width = (HEIGHT_SQUARES - 1) * square; + width_units = (width + unit_width / 2) / unit_width; + x += (width - width_units * unit_width) / 2; if (renderer->matrix) diff --git a/pango/pangocairo-win32fontmap.c b/pango/pangocairo-win32fontmap.c index b58d16f6..94500fd6 100644 --- a/pango/pangocairo-win32fontmap.c +++ b/pango/pangocairo-win32fontmap.c @@ -121,5 +121,5 @@ static void pango_cairo_win32_font_map_init (PangoCairoWin32FontMap *cwfontmap) { cwfontmap->serial = 1; - cwfontmap->dpi = GetDeviceCaps (pango_win32_get_dc (), LOGPIXELSY); + cwfontmap->dpi = GetDeviceCaps (_pango_win32_get_display_dc (), LOGPIXELSY); } diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c index 905fdee2..b43685c7 100644 --- a/pango/pangowin32-fontmap.c +++ b/pango/pangowin32-fontmap.c @@ -199,6 +199,12 @@ pango_win32_inner_enum_proc (LOGFONTW *lfp, return 1; } +struct EnumProcData +{ + HDC hdc; + PangoWin32FontMap *font_map; +}; + static int CALLBACK pango_win32_enum_proc (LOGFONTW *lfp, NEWTEXTMETRICW *metrics, @@ -206,6 +212,7 @@ pango_win32_enum_proc (LOGFONTW *lfp, LPARAM lParam) { LOGFONTW lf; + struct EnumProcData *data = (struct EnumProcData *) lParam; PING (("%S: %lu %lx", lfp->lfFaceName, fontType, metrics->ntmFlags)); @@ -213,9 +220,9 @@ pango_win32_enum_proc (LOGFONTW *lfp, { lf = *lfp; - EnumFontFamiliesExW (_pango_win32_hdc, &lf, + EnumFontFamiliesExW (data->hdc, &lf, (FONTENUMPROCW) pango_win32_inner_enum_proc, - lParam, 0); + (LPARAM) data->font_map, 0); } return 1; @@ -604,19 +611,6 @@ read_windows_fallbacks (GHashTable *ht_aliases) #endif - -static gboolean -load_aliases (GHashTable *ht_aliases) -{ - -#ifdef HAVE_CAIRO_WIN32 - read_windows_fallbacks (ht_aliases); - read_builtin_aliases (ht_aliases); -#endif - - return TRUE; -} - static void lookup_aliases (GHashTable *aliases_ht, const char *fontname, @@ -627,9 +621,6 @@ lookup_aliases (GHashTable *aliases_ht, struct PangoAlias *alias; static gsize aliases_inited = 0; - if (g_once_init_enter (&aliases_inited)) - g_once_init_leave (&aliases_inited, load_aliases (aliases_ht)); - alias_key.alias = g_ascii_strdown (fontname, -1); alias = g_hash_table_lookup (aliases_ht, &alias_key); g_free (alias_key.alias); @@ -653,8 +644,9 @@ create_standard_family (PangoWin32FontMap *win32fontmap, int i; int n_aliases; char **aliases; + PangoWin32FontMapClass *class = (PangoWin32FontMapClass*) G_OBJECT_GET_CLASS (win32fontmap); - lookup_aliases (win32fontmap->aliases, standard_family_name, &aliases, &n_aliases); + lookup_aliases (class->aliases, standard_family_name, &aliases, &n_aliases); for (i = 0; i < n_aliases; i++) { PangoWin32Family *existing_family = g_hash_table_lookup (win32fontmap->families, aliases[i]); @@ -709,6 +701,8 @@ static void _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap) { LOGFONTW logfont; + HDC hdc = _pango_win32_get_display_dc (); + struct EnumProcData enum_proc_data; win32fontmap->families = g_hash_table_new_full ((GHashFunc) case_insensitive_str_hash, @@ -719,10 +713,6 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap) win32fontmap->font_cache = pango_win32_font_cache_new (); win32fontmap->freed_fonts = g_queue_new (); - win32fontmap->aliases = g_hash_table_new_full ((GHashFunc)alias_hash, - (GEqualFunc)alias_equal, - (GDestroyNotify)alias_free, - NULL); win32fontmap->warned_fonts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, @@ -730,9 +720,13 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap) memset (&logfont, 0, sizeof (logfont)); logfont.lfCharSet = DEFAULT_CHARSET; - EnumFontFamiliesExW (_pango_win32_hdc, &logfont, + + enum_proc_data.hdc = hdc; + enum_proc_data.font_map = win32fontmap; + + EnumFontFamiliesExW (hdc, &logfont, (FONTENUMPROCW) pango_win32_enum_proc, - (LPARAM) win32fontmap, 0); + (LPARAM) &enum_proc_data, 0); g_hash_table_foreach (win32fontmap->families, synthesize_foreach, win32fontmap); @@ -744,7 +738,7 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap) create_standard_family (win32fontmap, "Fantasy"); create_standard_family (win32fontmap, "System-ui"); - win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (_pango_win32_hdc, LOGPIXELSY)) * 72.0; + win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (hdc, LOGPIXELSY)) * 72.0; } static void @@ -762,8 +756,9 @@ pango_win32_font_map_fontset_add_fonts (PangoFontMap *fontmap, int n_aliases; int j; PangoWin32FontMap *win32fontmap = PANGO_WIN32_FONT_MAP (fontmap); + PangoWin32FontMapClass *class = (PangoWin32FontMapClass*)G_OBJECT_GET_CLASS(win32fontmap); - lookup_aliases (win32fontmap->aliases, family, &aliases, &n_aliases); + lookup_aliases (class->aliases, family, &aliases, &n_aliases); if (n_aliases) { for (j = 0; j < n_aliases; j++) @@ -806,8 +801,16 @@ _pango_win32_font_map_class_init (PangoWin32FontMapClass *class) fontmap_class->list_families = pango_win32_font_map_list_families; fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_WIN32; fontmap_class->get_face = pango_win32_font_map_get_face; + class->aliases = g_hash_table_new_full ((GHashFunc)alias_hash, + (GEqualFunc)alias_equal, + (GDestroyNotify)alias_free, + NULL); +#ifdef HAVE_CAIRO_WIN32 + read_windows_fallbacks (class->aliases); + read_builtin_aliases (class->aliases); +#endif - pango_win32_get_dc (); + _pango_win32_get_display_dc (); } /** @@ -856,7 +859,6 @@ pango_win32_font_map_finalize (GObject *object) pango_win32_font_cache_free (win32fontmap->font_cache); g_hash_table_destroy (win32fontmap->warned_fonts); - g_hash_table_destroy (win32fontmap->aliases); g_hash_table_destroy (win32fontmap->fonts); g_hash_table_destroy (win32fontmap->families); @@ -1159,6 +1161,7 @@ get_family_nameA (const LOGFONTA *lfp) { HFONT hfont; HFONT oldhfont; + HDC hdc; struct name_header header; struct name_record record; @@ -1189,17 +1192,19 @@ get_family_nameA (const LOGFONTA *lfp) if ((hfont = CreateFontIndirect (lfp)) == NULL) goto fail0; - if ((oldhfont = SelectObject (_pango_win32_hdc, hfont)) == NULL) + hdc = _pango_win32_get_display_dc (); + + if ((oldhfont = SelectObject (hdc, hfont)) == NULL) goto fail1; - if (!_pango_win32_get_name_header (_pango_win32_hdc, &header)) + if (!_pango_win32_get_name_header (hdc, &header)) goto fail2; PING (("%d name records", header.num_records)); for (i = 0; i < header.num_records; i++) { - if (!_pango_win32_get_name_record (_pango_win32_hdc, i, &record)) + if (!_pango_win32_get_name_record (hdc, i, &record)) goto fail2; if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0) @@ -1234,11 +1239,11 @@ get_family_nameA (const LOGFONTA *lfp) else goto fail2; - if (!_pango_win32_get_name_record (_pango_win32_hdc, name_ix, &record)) + if (!_pango_win32_get_name_record (hdc, name_ix, &record)) goto fail2; string = g_malloc (record.string_length + 1); - if (GetFontData (_pango_win32_hdc, NAME, + if (GetFontData (hdc, NAME, header.string_storage_offset + record.string_offset, string, record.string_length) != record.string_length) goto fail2; @@ -1264,14 +1269,14 @@ get_family_nameA (const LOGFONTA *lfp) PING (("%s", name)); - SelectObject (_pango_win32_hdc, oldhfont); + SelectObject (hdc, oldhfont); DeleteObject (hfont); return name; fail2: g_free (string); - SelectObject (_pango_win32_hdc, oldhfont); + SelectObject (hdc, oldhfont); fail1: DeleteObject (hfont); @@ -1343,6 +1348,7 @@ get_family_nameW (const LOGFONTW *lfp) { HFONT hfont; HFONT oldhfont; + HDC hdc; struct name_header header; struct name_record record; @@ -1373,17 +1379,19 @@ get_family_nameW (const LOGFONTW *lfp) if ((hfont = CreateFontIndirectW (lfp)) == NULL) goto fail0; - if ((oldhfont = SelectObject (_pango_win32_hdc, hfont)) == NULL) + hdc = _pango_win32_get_display_dc (); + + if ((oldhfont = SelectObject (hdc, hfont)) == NULL) goto fail1; - if (!_pango_win32_get_name_header (_pango_win32_hdc, &header)) + if (!_pango_win32_get_name_header (hdc, &header)) goto fail2; PING (("%d name records", header.num_records)); for (i = 0; i < header.num_records; i++) { - if (!_pango_win32_get_name_record (_pango_win32_hdc, i, &record)) + if (!_pango_win32_get_name_record (hdc, i, &record)) goto fail2; if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0) @@ -1416,11 +1424,11 @@ get_family_nameW (const LOGFONTW *lfp) else goto fail2; - if (!_pango_win32_get_name_record (_pango_win32_hdc, name_ix, &record)) + if (!_pango_win32_get_name_record (hdc, name_ix, &record)) goto fail2; string = g_malloc (record.string_length + 1); - if (GetFontData (_pango_win32_hdc, NAME, + if (GetFontData (hdc, NAME, header.string_storage_offset + record.string_offset, string, record.string_length) != record.string_length) goto fail2; @@ -1446,14 +1454,14 @@ get_family_nameW (const LOGFONTW *lfp) PING (("%s", name)); - SelectObject (_pango_win32_hdc, oldhfont); + SelectObject (hdc, oldhfont); DeleteObject (hfont); return name; fail2: g_free (string); - SelectObject (_pango_win32_hdc, oldhfont); + SelectObject (hdc, oldhfont); fail1: DeleteObject (hfont); diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h index 082470e7..1c9c1c09 100644 --- a/pango/pangowin32-private.h +++ b/pango/pangowin32-private.h @@ -113,7 +113,7 @@ struct _PangoWin32FontMapClass PangoContext *context, PangoWin32Face *face, const PangoFontDescription *desc); - + GHashTable *aliases; }; struct _PangoWin32Font @@ -272,7 +272,9 @@ void _pango_win32_fontmap_cache_remove (PangoFontMap *fontmap, _PANGO_EXTERN HFONT _pango_win32_font_get_hfont (PangoFont *font); -extern HDC _pango_win32_hdc; +_PANGO_EXTERN +HDC _pango_win32_get_display_dc (void); + extern gboolean _pango_win32_debug; #endif /* __PANGOWIN32_PRIVATE_H__ */ diff --git a/pango/pangowin32.c b/pango/pangowin32.c index 737cfa14..8849d4af 100644 --- a/pango/pangowin32.c +++ b/pango/pangowin32.c @@ -43,7 +43,6 @@ #define MAX_FREED_FONTS 256 -HDC _pango_win32_hdc; gboolean _pango_win32_debug = FALSE; static void pango_win32_font_dispose (GObject *object); @@ -134,19 +133,21 @@ _pango_win32_font_init (PangoWin32Font *win32font) win32font->glyph_info = g_hash_table_new_full (NULL, NULL, NULL, g_free); } -/** - * pango_win32_get_dc: - * - * Obtains a handle to the Windows device context that is used by Pango. - * - * Return value: A handle to the Windows device context that is used by Pango. - **/ +static GPrivate display_dc_key = G_PRIVATE_INIT ((GDestroyNotify) DeleteDC); + HDC -pango_win32_get_dc (void) +_pango_win32_get_display_dc (void) { - if (g_once_init_enter (&_pango_win32_hdc)) + HDC hdc = g_private_get (&display_dc_key); + + if (hdc == NULL) { - HDC hdc = CreateDC ("DISPLAY", NULL, NULL, NULL); + hdc = CreateDC ("DISPLAY", NULL, NULL, NULL); + + if (G_UNLIKELY (hdc == NULL)) + g_warning ("CreateDC() failed"); + + g_private_set (&display_dc_key, hdc); /* Also do some generic pangowin32 initialisations... this function * is a suitable place for those as it is called from a couple @@ -156,10 +157,22 @@ pango_win32_get_dc (void) if (getenv ("PANGO_WIN32_DEBUG") != NULL) _pango_win32_debug = TRUE; #endif - g_once_init_leave (&_pango_win32_hdc, hdc); } - return _pango_win32_hdc; + return hdc; +} + +/** + * pango_win32_get_dc: + * + * Obtains a handle to the Windows device context that is used by Pango. + * + * Return value: A handle to the Windows device context that is used by Pango. + **/ +HDC +pango_win32_get_dc (void) +{ + return _pango_win32_get_display_dc (); } /** @@ -198,7 +211,7 @@ _pango_win32_font_class_init (PangoWin32FontClass *class) class->done_font = pango_win32_font_real_done_font; class->get_metrics_factor = pango_win32_font_real_get_metrics_factor; - pango_win32_get_dc (); + _pango_win32_get_display_dc (); } /** @@ -448,7 +461,7 @@ pango_win32_font_get_glyph_extents (PangoFont *font, if (!info) { - HDC hdc = pango_win32_get_dc (); + HDC hdc = _pango_win32_get_display_dc (); info = g_new0 (PangoWin32GlyphInfo, 1); @@ -478,7 +491,7 @@ pango_win32_font_get_glyph_extents (PangoFont *font, info->ink_rect.y = - PANGO_SCALE * gm.gmptGlyphOrigin.y; info->ink_rect.height = PANGO_SCALE * gm.gmBlackBoxY; - GetTextMetrics (_pango_win32_hdc, &tm); + GetTextMetrics (hdc, &tm); info->logical_rect.x = 0; info->logical_rect.width = PANGO_SCALE * gm.gmCellIncX; info->logical_rect.y = - PANGO_SCALE * tm.tmAscent; @@ -555,9 +568,10 @@ pango_win32_font_get_metrics (PangoFont *font, { PangoCoverage *coverage; TEXTMETRIC tm; + HDC hdc = _pango_win32_get_display_dc (); - SelectObject (_pango_win32_hdc, hfont); - GetTextMetrics (_pango_win32_hdc, &tm); + SelectObject (hdc, hfont); + GetTextMetrics (hdc, &tm); metrics->ascent = tm.tmAscent * PANGO_SCALE; metrics->descent = tm.tmDescent * PANGO_SCALE; @@ -1215,7 +1229,7 @@ hfont_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data) DWORD size; /* We have a common DC for our PangoWin32Font, so let's just use it */ - hdc = pango_win32_get_dc (); + hdc = _pango_win32_get_display_dc (); hfont = (HFONT) user_data; /* we want to restore things, just to be safe */ diff --git a/subprojects/harfbuzz.wrap b/subprojects/harfbuzz.wrap new file mode 100644 index 00000000..e739b5e7 --- /dev/null +++ b/subprojects/harfbuzz.wrap @@ -0,0 +1,5 @@ +[wrap-git] +directory=harfbuzz +url=https://github.com/harfbuzz/harfbuzz.git +push-url=git@github.com:harfbuzz/harfbuzz.git +revision=master diff --git a/tests/GraphemeBreakTest.txt b/tests/GraphemeBreakTest.txt index 6847953c..5baf292a 100644 --- a/tests/GraphemeBreakTest.txt +++ b/tests/GraphemeBreakTest.txt @@ -1,6 +1,6 @@ -# GraphemeBreakTest-11.0.0.txt -# Date: 2018-03-18, 13:30:33 GMT -# © 2018 Unicode®, Inc. +# GraphemeBreakTest-13.0.0.txt +# Date: 2019-11-15, 19:49:10 GMT +# © 2019 Unicode®, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # @@ -56,8 +56,6 @@ ÷ 0020 × 0308 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0020 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 0020 × 0308 ÷ 0378 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 0020 ÷ D800 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 0020 × 0308 ÷ D800 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 000D ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] SPACE (Other) ÷ [0.3] ÷ 000D ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 000D ÷ 000D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -92,8 +90,6 @@ ÷ 000D ÷ 0308 × 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 000D ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3] ÷ 000D ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 000D ÷ D800 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 000D ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 000A ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] SPACE (Other) ÷ [0.3] ÷ 000A ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 000A ÷ 000D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -128,8 +124,6 @@ ÷ 000A ÷ 0308 × 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 000A ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3] ÷ 000A ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 000A ÷ D800 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 000A ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 0001 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] SPACE (Other) ÷ [0.3] ÷ 0001 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0001 ÷ 000D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -164,8 +158,6 @@ ÷ 0001 ÷ 0308 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0001 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3] ÷ 0001 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 0001 ÷ D800 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 0001 ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 034F ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 034F × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 034F ÷ 000D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -200,8 +192,6 @@ ÷ 034F × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 034F ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 034F × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 034F ÷ D800 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 034F × 0308 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 1F1E6 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 1F1E6 × 0308 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -236,8 +226,6 @@ ÷ 1F1E6 × 0308 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 1F1E6 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 1F1E6 × 0308 ÷ 0378 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 1F1E6 ÷ D800 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 1F1E6 × 0308 ÷ D800 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 0600 × 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] SPACE (Other) ÷ [0.3] ÷ 0600 × 0308 ÷ 0020 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0600 ÷ 000D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -272,8 +260,6 @@ ÷ 0600 × 0308 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0600 × 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] <reserved-0378> (Other) ÷ [0.3] ÷ 0600 × 0308 ÷ 0378 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 0600 ÷ D800 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 0600 × 0308 ÷ D800 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 0903 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0903 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0903 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -308,8 +294,6 @@ ÷ 0903 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0903 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 0903 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 0903 ÷ D800 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 0903 × 0308 ÷ D800 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 1100 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 1100 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 1100 ÷ 000D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -344,8 +328,6 @@ ÷ 1100 × 0308 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 1100 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 1100 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 1100 ÷ D800 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 1100 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 1160 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 1160 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 1160 ÷ 000D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -380,8 +362,6 @@ ÷ 1160 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 1160 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 1160 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 1160 ÷ D800 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 1160 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 11A8 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 11A8 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 11A8 ÷ 000D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -416,8 +396,6 @@ ÷ 11A8 × 0308 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 11A8 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 11A8 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 11A8 ÷ D800 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 11A8 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ AC00 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ AC00 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ AC00 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -452,8 +430,6 @@ ÷ AC00 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ AC00 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ AC00 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ AC00 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ AC00 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ AC01 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ AC01 × 0308 ÷ 0020 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ AC01 ÷ 000D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -488,8 +464,6 @@ ÷ AC01 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ AC01 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ AC01 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ AC01 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ AC01 × 0308 ÷ D800 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 231A ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 231A × 0308 ÷ 0020 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 231A ÷ 000D ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -524,8 +498,6 @@ ÷ 231A × 0308 × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 231A ÷ 0378 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 231A × 0308 ÷ 0378 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 231A ÷ D800 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 231A × 0308 ÷ D800 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 0300 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0300 × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0300 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -560,8 +532,6 @@ ÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0300 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 0300 × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 0300 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 0300 × 0308 ÷ D800 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 200D ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 200D × 0308 ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 200D ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -596,8 +566,6 @@ ÷ 200D × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 200D ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 200D × 0308 ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 200D ÷ D800 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 200D × 0308 ÷ D800 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 0378 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0378 × 0308 ÷ 0020 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0378 ÷ 000D ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -632,44 +600,6 @@ ÷ 0378 × 0308 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0378 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 0378 × 0308 ÷ 0378 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 0378 ÷ D800 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ 0378 × 0308 ÷ D800 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] -÷ D800 ÷ 0020 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] SPACE (Other) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 0020 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] -÷ D800 ÷ 000D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 000D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] -÷ D800 ÷ 000A ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <LINE FEED (LF)> (LF) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] -÷ D800 ÷ 0001 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ D800 ÷ 034F ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ D800 ÷ 0308 × 034F ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ D800 ÷ 1F1E6 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] -÷ D800 ÷ 0600 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 0600 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] -÷ D800 ÷ 0903 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] -÷ D800 ÷ 0308 × 0903 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark) ÷ [0.3] -÷ D800 ÷ 1100 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 1100 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] -÷ D800 ÷ 1160 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 1160 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] -÷ D800 ÷ 11A8 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 11A8 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] -÷ D800 ÷ AC00 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] -÷ D800 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] -÷ D800 ÷ AC01 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ D800 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ D800 ÷ 231A ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] WATCH (ExtPict) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] -÷ D800 ÷ 0300 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ D800 ÷ 0308 × 0300 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ D800 ÷ 200D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] -÷ D800 ÷ 0308 × 200D ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] -÷ D800 ÷ 0378 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3] -÷ D800 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ D800 ÷ D800 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] <surrogate-D800> (Control) ÷ [0.3] -÷ D800 ÷ 0308 ÷ D800 ÷ # ÷ [0.2] <surrogate-D800> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <surrogate-D800> (Control) ÷ [0.3] ÷ 000D × 000A ÷ 0061 ÷ 000A ÷ 0308 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) × [3.0] <LINE FEED (LF)> (LF) ÷ [4.0] LATIN SMALL LETTER A (Other) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [0.3] ÷ 0061 × 0308 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [0.3] ÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] ARABIC LETTER NOON (Other) ÷ [0.3] @@ -695,6 +625,6 @@ ÷ 2701 × 200D × 2701 ÷ # ÷ [0.2] UPPER BLADE SCISSORS (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] UPPER BLADE SCISSORS (Other) ÷ [0.3] ÷ 0061 × 200D ÷ 2701 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] UPPER BLADE SCISSORS (Other) ÷ [0.3] # -# Lines: 672 +# Lines: 602 # # EOF diff --git a/tests/SentenceBreakTest.txt b/tests/SentenceBreakTest.txt index 70898a31..5ae1f881 100644 --- a/tests/SentenceBreakTest.txt +++ b/tests/SentenceBreakTest.txt @@ -1,6 +1,6 @@ -# SentenceBreakTest-11.0.0.txt -# Date: 2018-01-31, 08:20:29 GMT -# © 2018 Unicode®, Inc. +# SentenceBreakTest-13.0.0.txt +# Date: 2019-11-20, 22:27:22 GMT +# © 2019 Unicode®, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # diff --git a/tests/WordBreakTest.txt b/tests/WordBreakTest.txt index c4c92550..3e85759b 100644 --- a/tests/WordBreakTest.txt +++ b/tests/WordBreakTest.txt @@ -1,6 +1,6 @@ -# WordBreakTest-11.0.0.txt -# Date: 2018-03-16, 20:34:16 GMT -# © 2018 Unicode®, Inc. +# WordBreakTest-13.0.0.txt +# Date: 2019-11-20, 22:27:23 GMT +# © 2019 Unicode®, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. # For terms of use, see http://www.unicode.org/terms_of_use.html # diff --git a/tests/markup-parse.c b/tests/markup-parse.c index dff0ccc4..5f1454a1 100644 --- a/tests/markup-parse.c +++ b/tests/markup-parse.c @@ -48,12 +48,8 @@ test_file (const gchar *filename, GString *string) char *str; int start, end; - if (!g_file_get_contents (filename, &contents, &length, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + g_file_get_contents (filename, &contents, &length, &error); + g_assert_no_error (error); ret = pango_parse_markup (contents, length, 0, &attrs, &text, NULL, &error); g_free (contents); @@ -152,7 +148,7 @@ main (int argc, char *argv[]) string = g_string_sized_new (0); test_file (argv[1], string); - g_print ("%s", string->str); + g_test_message ("%s", string->str); return 0; } diff --git a/tests/meson.build b/tests/meson.build index 4ffffa4c..9b78fbfd 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -10,11 +10,10 @@ if host_system == 'windows' test_cflags += '-DHAVE_WIN32' endif -test_env = [ - 'srcdir=@0@'.format(meson.current_source_dir()), - 'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()), - 'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()), -] +test_env = environment() +test_env.set('srcdir', meson.current_source_dir()) +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) tests = [ [ 'test-coverage' ], @@ -177,5 +176,10 @@ foreach t: tests install: get_option('install-tests'), install_dir: installed_test_bindir) - test(name, bin, env: test_env) + test(name, bin, + args: ['-k', '--tap'], + env: test_env, + suite: 'pango', + protocol: 'tap', + ) endforeach diff --git a/tests/test-break.c b/tests/test-break.c index 8549b678..3258cb98 100644 --- a/tests/test-break.c +++ b/tests/test-break.c @@ -51,12 +51,8 @@ test_file (const gchar *filename, GString *string) PangoAttrList *attributes; PangoLayout *layout; - if (!g_file_get_contents (filename, &contents, &length, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + g_file_get_contents (filename, &contents, &length, &error); + g_assert_no_error (error); test = contents; @@ -68,12 +64,8 @@ test_file (const gchar *filename, GString *string) len = g_utf8_strlen (test, -1) + 1; attrs = g_new (PangoLogAttr, len); - if (!pango_parse_markup (test, -1, 0, &attributes, &text, NULL, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + pango_parse_markup (test, -1, 0, &attributes, &text, NULL, &error); + g_assert_no_error (error); layout = pango_layout_new (context); pango_layout_set_text (layout, text, length); @@ -260,7 +252,8 @@ test_break (gconstpointer d) if (diff && diff[0]) { - g_printerr ("Contents don't match expected contents:\n%s", diff); + g_test_message ("Contents don't match expected contents"); + g_test_message ("%s", diff); g_test_fail (); g_free (diff); } @@ -291,7 +284,7 @@ main (int argc, char *argv[]) string = g_string_sized_new (0); test_file (argv[1], string); - printf ("%s", string->str); + g_test_message ("%s", string->str); return 0; } @@ -305,6 +298,12 @@ main (int argc, char *argv[]) if (!strstr (name, "break")) continue; +#ifndef HAVE_LIBTHAI + /* four.break involves Thai, so only test it when we have libthai */ + if (strstr (name, "four.break")) + continue; +#endif + path = g_strdup_printf ("/break/%s", name); g_test_add_data_func_full (path, g_test_build_filename (G_TEST_DIST, "breaks", name, NULL), test_break, g_free); diff --git a/tests/test-font.c b/tests/test-font.c index 5ef6cc39..486504f9 100644 --- a/tests/test-font.c +++ b/tests/test-font.c @@ -133,25 +133,21 @@ test_metrics (void) metrics = pango_context_get_metrics (context, desc, pango_language_get_default ()); - g_test_message ("%s metrics\n" - "\tascent %d\n" - "\tdescent %d\n" - "\theight %d\n" - "\tchar width %d\n" - "\tdigit width %d\n" - "\tunderline position %d\n" - "\tunderline thickness %d\n" - "\tstrikethrough position %d\n" - "\tstrikethrough thickness %d\n", - str, - pango_font_metrics_get_ascent (metrics), - pango_font_metrics_get_descent (metrics), - pango_font_metrics_get_height (metrics), - pango_font_metrics_get_approximate_char_width (metrics), - pango_font_metrics_get_approximate_digit_width (metrics), - pango_font_metrics_get_underline_position (metrics), - pango_font_metrics_get_underline_thickness (metrics), - pango_font_metrics_get_strikethrough_position (metrics), + g_test_message ("%s metrics", str); + g_test_message ("\tascent: %d", pango_font_metrics_get_ascent (metrics)); + g_test_message ("\tdescent: %d", pango_font_metrics_get_descent (metrics)); + g_test_message ("\theight: %d", pango_font_metrics_get_height (metrics)); + g_test_message ("\tchar width: %d", + pango_font_metrics_get_approximate_char_width (metrics)); + g_test_message ("\tdigit width: %d", + pango_font_metrics_get_approximate_digit_width (metrics)); + g_test_message ("\tunderline position: %d", + pango_font_metrics_get_underline_position (metrics)); + g_test_message ("\tunderline thickness: %d", + pango_font_metrics_get_underline_thickness (metrics)); + g_test_message ("\tstrikethrough position: %d", + pango_font_metrics_get_strikethrough_position (metrics)); + g_test_message ("\tstrikethrough thickness: %d", pango_font_metrics_get_strikethrough_thickness (metrics)); pango_font_metrics_unref (metrics); diff --git a/tests/test-itemize.c b/tests/test-itemize.c index d66c40d1..167e4e80 100644 --- a/tests/test-itemize.c +++ b/tests/test-itemize.c @@ -118,12 +118,8 @@ test_file (const gchar *filename, GString *string) GList *items, *l; const char *sep = ""; - if (!g_file_get_contents (filename, &contents, &length, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + g_file_get_contents (filename, &contents, &length, &error); + g_assert_no_error (error); test = contents; @@ -131,13 +127,8 @@ test_file (const gchar *filename, GString *string) while (test[0] == '#') test = strchr (test, '\n') + 1; - - if (!pango_parse_markup (test, -1, 0, &attrs, &text, NULL, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + pango_parse_markup (test, -1, 0, &attrs, &text, NULL, &error); + g_assert_no_error (error); s1 = g_string_new ("Items: "); s2 = g_string_new ("Font: "); @@ -257,7 +248,8 @@ test_itemize (gconstpointer d) if (diff && diff[0]) { - g_printerr ("Contents don't match expected contents:\n%s", diff); + g_test_message ("Contents don't match expected contents"); + g_test_message ("%s", diff); g_test_fail (); g_free (diff); } diff --git a/tests/test-layout.c b/tests/test-layout.c index cbbffd2c..2fc78240 100644 --- a/tests/test-layout.c +++ b/tests/test-layout.c @@ -238,12 +238,8 @@ test_file (const gchar *filename, GString *string) PangoWrapMode wrap = PANGO_WRAP_WORD; PangoFontDescription *desc; - if (!g_file_get_contents (filename, &contents, &length, &error)) - { - fprintf (stderr, "%s\n", error->message); - g_error_free (error); - return; - } + g_file_get_contents (filename, &contents, &length, &error); + g_assert_no_error (error); p = strchr (contents, '\n'); g_assert (p); @@ -319,7 +315,8 @@ test_layout (gconstpointer d) if (diff && diff[0]) { - g_printerr ("Contents don't match expected contents:\n%s", diff); + g_test_message ("Contents don't match expected contents"); + g_test_message ("%s", diff); g_test_fail (); g_free (diff); } @@ -350,7 +347,7 @@ main (int argc, char *argv[]) string = g_string_sized_new (0); test_file (argv[1], string); - g_print ("%s", string->str); + g_test_message ("%s", string->str); return 0; } diff --git a/tests/test-pangocairo-threads.c b/tests/test-pangocairo-threads.c index cdbd2419..ea97fc17 100644 --- a/tests/test-pangocairo-threads.c +++ b/tests/test-pangocairo-threads.c @@ -8,6 +8,7 @@ const char *text = "Hamburgerfonts\nวิวิวิวิวิวิ\nبهداد"; int num_iters = 50; +int num_threads = 5; GMutex mutex; @@ -65,18 +66,12 @@ thread_func (gpointer data) return 0; } -int -main (int argc, char **argv) +static void +pangocairo_threads (void) { - int num_threads = 5; - int i; GPtrArray *threads = g_ptr_array_new (); GPtrArray *surfaces = g_ptr_array_new (); - - if (argc > 1) - num_threads = atoi (argv[1]); - if (argc > 2) - num_iters = atoi (argv[2]); + int i; g_mutex_lock (&mutex); @@ -98,7 +93,7 @@ main (int argc, char **argv) for (i = 0; i < num_threads; i++) g_thread_join (g_ptr_array_index (threads, i)); - g_ptr_array_free (threads, TRUE); + g_ptr_array_unref (threads); /* Now, draw a reference image and check results. */ { @@ -123,10 +118,11 @@ main (int argc, char **argv) unsigned char *data = cairo_image_surface_get_data (surface); if (memcmp (ref_data, data, len)) { - fprintf (stderr, "image for thread %d different from reference image.\n", i); + g_test_message ("image for thread %d different from reference image", i); cairo_surface_write_to_png (ref_surface, "test-pangocairo-threads-reference.png"); cairo_surface_write_to_png (surface, "test-pangocairo-threads-failed.png"); - return 1; + g_test_fail (); + break; } cairo_surface_destroy (surface); } @@ -134,9 +130,23 @@ main (int argc, char **argv) cairo_surface_destroy (ref_surface); } - g_ptr_array_free (surfaces, TRUE); + g_ptr_array_unref (surfaces); pango_cairo_font_map_set_default (NULL); - return 0; +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + + if (argc > 1) + num_threads = atoi (argv[1]); + if (argc > 2) + num_iters = atoi (argv[2]); + + g_test_add_func ("/pangocairo/threads", pangocairo_threads); + + return g_test_run (); } diff --git a/tests/test-shape.c b/tests/test-shape.c index 6c1ae296..c2488dbf 100644 --- a/tests/test-shape.c +++ b/tests/test-shape.c @@ -319,7 +319,8 @@ test_shape (gconstpointer d) if (diff && diff[0]) { - g_printerr ("Contents don't match expected contents:\n%s", diff); + g_test_message ("Contents don't match expected contents"); + g_test_message ("%s", diff); g_test_fail (); g_free (diff); } diff --git a/tests/testboundaries.c b/tests/testboundaries.c index 75da772e..2390bb28 100644 --- a/tests/testboundaries.c +++ b/tests/testboundaries.c @@ -46,27 +46,6 @@ static gunichar current_wc = 0; static const char *line_start = NULL; static const char *line_end = NULL; -static void fail (const char *format, ...) G_GNUC_PRINTF (1, 2) G_GNUC_NORETURN; -static void fail (const char *format, ...) -{ - char *str; - char *line_text; - - va_list args; - - va_start (args, format); - str = g_strdup_vprintf (format, args); - va_end (args); - - line_text = g_strndup (line_start, line_end - line_start); - - fprintf (stderr, "line %d offset %d char is " CHFORMAT ": %s\n (line is '%s')\n", line, offset, current_wc, str, line_text); - g_free (str); - g_free (line_text); - - exit (1); -} - typedef void (* CharForeachFunc) (gunichar wc, gunichar prev_wc, gunichar next_wc, @@ -175,28 +154,36 @@ check_line_char (gunichar wc, { if (prev_wc == '\r') { - if (attr->is_line_break) - fail ("line break between \\r and \\n"); + g_test_message ("Do not line break between \\r and \\n"); + g_assert_false (attr->is_line_break); } - if (next_attr && !next_attr->is_line_break) - fail ("no line break after \\n"); + if (next_attr != NULL) + { + g_test_message ("Line break after \\n"); + g_assert_true (next_attr->is_line_break); + } } - if (attr->is_line_break && prev_wc == 0) - fail ("first char in string should not be marked as a line break"); + if (attr->is_line_break) + { + g_test_message ("first char in string should not be marked as a line break"); + g_assert_false (prev_wc == 0); + } if (break_type == G_UNICODE_BREAK_SPACE) { - if (attr->is_line_break && prev_attr != NULL && - !attr->is_mandatory_break && - !(next_wc && g_unichar_break_type (next_wc) == G_UNICODE_BREAK_COMBINING_MARK)) - fail ("can't break lines before a space unless a mandatory break char precedes it or a combining mark follows; prev char was " CHFORMAT, prev_wc); + g_test_message ("can't break lines before a space unless a mandatory break char precedes it or a combining mark follows; prev char was: " CHFORMAT, prev_wc); + g_assert_false (attr->is_line_break && prev_attr != NULL && + !attr->is_mandatory_break && + !(next_wc && g_unichar_break_type (next_wc) == G_UNICODE_BREAK_COMBINING_MARK)); } - if (attr->is_mandatory_break && !attr->is_line_break) - fail ("mandatory breaks must also be marked as regular breaks"); - + if (attr->is_mandatory_break) + { + g_test_message ("mandatory breaks must also be marked as regular breaks"); + g_assert_true (attr->is_line_break); + } /* FIXME use the break tables from break.c to automatically @@ -204,23 +191,23 @@ check_line_char (gunichar wc, * be that hard to do. */ - if (break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION && - prev_break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION && - attr->is_line_break && - !attr->is_mandatory_break) - fail ("can't break between two open punctuation chars"); - - if (break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION && - prev_break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION && - attr->is_line_break && - !attr->is_mandatory_break) - fail ("can't break between two close punctuation chars"); - - if (break_type == G_UNICODE_BREAK_QUOTATION && - prev_break_type == G_UNICODE_BREAK_ALPHABETIC && - attr->is_line_break && - !attr->is_mandatory_break) - fail ("can't break letter-quotemark sequence"); + g_test_message ("can't break between two open punctuation chars"); + g_assert_false (break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION && + prev_break_type == G_UNICODE_BREAK_OPEN_PUNCTUATION && + attr->is_line_break && + !attr->is_mandatory_break); + + g_test_message ("can't break between two close punctuation chars"); + g_assert_false (break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION && + prev_break_type == G_UNICODE_BREAK_CLOSE_PUNCTUATION && + attr->is_line_break && + !attr->is_mandatory_break); + + g_test_message ("can't break letter-quotemark sequence"); + g_assert_false (break_type == G_UNICODE_BREAK_QUOTATION && + prev_break_type == G_UNICODE_BREAK_ALPHABETIC && + attr->is_line_break && + !attr->is_mandatory_break); } static void @@ -290,8 +277,7 @@ check_invariants (const char *text) int len; PangoLogAttr *attrs; - if (!g_utf8_validate (text, -1, NULL)) - fail ("Invalid UTF-8 in test text"); + g_assert_true (g_utf8_validate (text, -1, NULL)); len = g_utf8_strlen (text, -1); attrs = g_new0 (PangoLogAttr, len + 1); @@ -318,24 +304,20 @@ check_invariants (const char *text) static void test_boundaries (void) { - gchar *text; - const gchar *filename; -#if GLIB_CHECK_VERSION(2, 37, 2) + const char *filename; + GError *error = NULL; + char *text; + filename = g_test_get_filename (G_TEST_DIST, "boundaries.utf8", NULL); -#else - filename = SRCDIR "/boundaries.utf8"; -#endif - g_print ("sample file: %s\n", filename); + g_test_message ("sample file: %s\n", filename); - if (!g_file_get_contents (filename, &text, NULL, NULL)) - fail ("Couldn't open sample text file"); + g_file_get_contents (filename, &text, NULL, &error); + g_assert_no_error (error); check_invariants (text); g_free (text); - - printf ("testboundaries passed\n"); } int @@ -347,4 +329,3 @@ main (int argc, char *argv[]) return g_test_run (); } - diff --git a/tests/testboundaries_ucd.c b/tests/testboundaries_ucd.c index 53f7b4cb..f77abdcd 100644 --- a/tests/testboundaries_ucd.c +++ b/tests/testboundaries_ucd.c @@ -104,7 +104,7 @@ parse_line (gchar *line, { case 0x00f7: /* DIVISION SIGN: boundary here */ temp_attr.bits |= bits.bits; - /* fall through */ + G_GNUC_FALLTHROUGH; case 0x00d7: /* MULTIPLICATION SIGN: no boundary here */ break; @@ -230,32 +230,28 @@ do_test (const gchar *filename, error = NULL; channel = g_io_channel_new_file (filename, "r", &error); - if (!channel) + if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { - if (error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT) - { - g_print ("%s not found. Skipping test.\n", filename); - goto done; - } - else - { - g_printerr ("%s: %s\n", filename, error->message); - exit (1); - } + g_test_skip ("Test file not found"); + return; } - g_print ("Testing %s.\n", filename); + + g_assert_no_error (error); + + g_test_message ("Filename: %s", filename); i = 1; for (;;) { error = NULL; status = g_io_channel_read_line (channel, &line, &length, &terminator_pos, &error); + g_assert_no_error (error); switch (status) { case G_IO_STATUS_ERROR: - g_printerr ("%s: %s\n", filename, error->message); - exit (1); + failed = TRUE; + goto done; case G_IO_STATUS_EOF: goto done; @@ -268,11 +264,8 @@ do_test (const gchar *filename, break; } - if (! parse_line (line, bits, &string, &expected_attrs, &num_attrs)) - { - g_printerr ("%s: error parsing line %d: %s\n", filename, i, line); - exit (1); - } + g_test_message ("Parsing line: %s", line); + g_assert_true (parse_line (line, bits, &string, &expected_attrs, &num_attrs)); if (num_attrs > 0) { @@ -293,11 +286,10 @@ do_test (const gchar *filename, comments = ""; } - g_printerr ("%s: line %d failed\n" - " expected: %s\n" - " returned: %s\n" - " comments: %s\n\n", - filename, i, line, str, comments); + g_test_message ("%s: line %d failed", filename, i); + g_test_message (" expected: %s", line); + g_test_message (" returned: %s", str); + g_test_message (" comments: %s", comments); g_free (str); failed = TRUE; @@ -316,20 +308,16 @@ done: if (error) g_error_free (error); - g_assert (!failed); + g_assert_true (!failed); } static void test_grapheme_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "GraphemeBreakTest.txt", NULL); -#else - filename = SRCDIR "/GraphemeBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_cursor_position = 1; do_test (filename, bits); @@ -338,14 +326,10 @@ test_grapheme_break (void) static void test_emoji_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "EmojiBreakTest.txt", NULL); -#else - filename = SRCDIR "/EmojiBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_cursor_position = 1; do_test (filename, bits); @@ -354,14 +338,10 @@ test_emoji_break (void) static void test_char_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "CharBreakTest.txt", NULL); -#else - filename = SRCDIR "/CharBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_char_break = 1; do_test (filename, bits); @@ -370,14 +350,10 @@ test_char_break (void) static void test_word_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "WordBreakTest.txt", NULL); -#else - filename = SRCDIR "/WordBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_word_boundary = 1; do_test (filename, bits); @@ -386,14 +362,10 @@ test_word_break (void) static void test_sentence_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) filename = g_test_get_filename (G_TEST_DIST, "SentenceBreakTest.txt", NULL); -#else - filename = SRCDIR "/SentenceBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_sentence_boundary = 1; do_test (filename, bits); @@ -402,17 +374,15 @@ test_sentence_break (void) static void test_line_break (void) { - const gchar *filename; + const char *filename; AttrBits bits; -#if GLIB_CHECK_VERSION(2, 37, 2) + filename = g_test_get_filename (G_TEST_DIST, "LineBreakTest.txt", NULL); -#else - filename = SRCDIR "/LineBreakTest.txt"; -#endif bits.bits = 0; bits.attr.is_line_break = 1; bits.attr.is_mandatory_break = 1; + do_test (filename, bits); } diff --git a/tests/testscript.c b/tests/testscript.c index aa610b44..33e8ad2e 100644 --- a/tests/testscript.c +++ b/tests/testscript.c @@ -60,18 +60,6 @@ #include "pango/pango-script.h" -#undef VERBOSE - -#define ASSERT(stmt) G_STMT_START { \ - if (stmt) { } \ - else \ - { \ - g_warning ("%s:%d (%s): assertion '%s' failed", \ - __FILE__, __LINE__, G_STRFUNC, #stmt); \ - exit (1); \ - } \ -} G_STMT_END - typedef struct { const char *run_text_escaped; @@ -170,9 +158,7 @@ test_script_iter (void) iter = pango_script_iter_new (all->str, -1); -#ifdef VERBOSE - g_print ("Total length: %d\n", all->len); -#endif + g_test_message ("Total length: %" G_GSIZE_FORMAT "\n", all->len); pos = all->str; for (i = 0; i < G_N_ELEMENTS(test_data); i++) @@ -181,16 +167,18 @@ test_script_iter (void) gboolean result; pango_script_iter_get_range (iter, &start, &end, &script); -#ifdef VERBOSE - g_print ("Range: %d-%d: %d\n", start - all->str, end - all->str, script); -#endif - ASSERT (start == pos); - ASSERT (end == next_pos); - ASSERT (script == test_data[i].run_code); + g_test_message ("Range: %d-%d: %d\n", + (int) (start - all->str), + (int) (end - all->str), + script); + + g_assert_true (start == pos); + g_assert_true (end == next_pos); + g_assert_true (script == test_data[i].run_code); result = pango_script_iter_next (iter); - ASSERT (result == (i != G_N_ELEMENTS (test_data) - 1)); + g_assert_true (result == (i != G_N_ELEMENTS (test_data) - 1)); pos = next_pos; } @@ -204,10 +192,10 @@ test_script_iter (void) pango_script_iter_get_range (iter, &start, &end, &script); - ASSERT (start == all->str); - ASSERT (end == all->str); - ASSERT (script == PANGO_SCRIPT_COMMON); - ASSERT (!pango_script_iter_next (iter)); + g_assert_true (start == all->str); + g_assert_true (end == all->str); + g_assert_true (script == PANGO_SCRIPT_COMMON); + g_assert_true (!pango_script_iter_next (iter)); pango_script_iter_free (iter); diff --git a/tools/gen-break-table.py b/tools/gen-break-table.py index 2c8a7d70..5d346c8c 100755 --- a/tools/gen-break-table.py +++ b/tools/gen-break-table.py @@ -9,20 +9,21 @@ from collections import OrderedDict header = [] ranges = OrderedDict() -def load_data(filename): +def load_data(filename, prefix=""): global header, ranges f = open(filename) lines = f.readlines() for line in lines: - header.append(line) if not line.startswith("#"): break + header.append(line) for line in lines: line = line.strip() if not line or line[0] == '#': continue rang, typ = [s.strip() for s in line.split('#')[0].split(';')[:2]] + typ = prefix + typ rang = [int(s, 16) for s in rang.split('..')] if len(rang) > 1: @@ -87,6 +88,7 @@ def print_ranges(ranges): def print_balanced_search(ranges): if 4 >= len(ranges): print_ranges(ranges) + print("return FALSE;") return length = len(ranges) @@ -116,7 +118,7 @@ def print_table(): print("/*") print(" * The following tables are generated by running:") print(" *") - print(" * ./gen-break-table.py SentenceBreakProperty.txt IndicSyllabicCategory.txt | indent") + print(" * ./gen-break-table.py SentenceBreakProperty.txt IndicSyllabicCategory.txt EastAsianWidth.txt | indent") print(" *") print(" * on files with these headers:") print(" *") @@ -132,14 +134,22 @@ def print_table(): for typ,s in ranges.items(): if typ not in ['STerm', - 'Virama', - 'Vowel_Dependent']: continue + 'Virama', + 'Vowel_Dependent', + 'Consonant_Prefixed', + 'Consonant_Preceding_Repha']: continue print() print("static inline gboolean _pango_is_%s (gunichar wc)" % typ) print("{") - print_balanced_search(sorted(s)) + print_balanced_search(sorted(s)) print("}") + s = ranges["EastAsian_F"] + ranges["EastAsian_W"] + ranges["EastAsian_H"] + print("static inline gboolean _pango_is_EastAsianWide (gunichar wc)") + print("{") + print_balanced_search(sorted(s)) + print("}") + print() print("#endif /* PANGO_BREAK_TABLE_H */") print() @@ -147,10 +157,11 @@ def print_table(): if __name__ == "__main__": - if len (sys.argv) != 3: - print("usage: ./gen-break-table.py SentenceBreakProperty.txt IndicSyllabicCategory.txt | indent", file=sys.stderr) + if len (sys.argv) != 4: + print("usage: ./gen-break-table.py SentenceBreakProperty.txt IndicSyllabicCategory.txt EastAsianWidth.txt | indent", file=sys.stderr) sys.exit (1) load_data(sys.argv[1]) load_data(sys.argv[2]) + load_data(sys.argv[3], "EastAsian_") print_table() |