Aurelien Larcher
2018-10-28 a49d4f2dee82e6d44ca66c1f47f4872c42d61c0d
Adapt font rules from solaris-userland
2 files added
334 ■■■■■ changed files
make-rules/font.mk 180 ●●●●● patch | view | raw | blame | history
tools/generate_font_metadata.pl 154 ●●●●● patch | view | raw | blame | history
make-rules/font.mk
New file
@@ -0,0 +1,180 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, Aurelien Larcher. All rights reserved.
#
BUILD_BITS  ?= NO_ARCH
BUILD_STYLE ?= archive
include $(WS_MAKE_RULES)/common.mk
MKFONTSCALE = mkfontscale
MKFONTDIR = mkfontdir
ETCFONTSDIR = $(ETCDIR)/fonts
ETCFONTSCONFDIR = $(ETCFONTSDIR)/conf.avail
USRSHAREFONTSDIR = $(USRSHAREDIR)/fonts
#
# Font type macros
#
TTFFONTDIR = TrueType
OTFFONTDIR = OpenType
X11FONTDIR = X11
PKGFONTDIR?= $($(FONT_TYPE)FONTDIR)
# For compatibility
USRSHARETTFONTSDIR = $(USRSHAREFONTSDIR)/$(TTFFONTDIR)
USRSHAREOTFONTSDIR = $(USRSHAREFONTSDIR)/$(OTFFONTDIR)
TTFFONTSRC = ttf
OTFFONTSRC = otf
X11FONTSRC =
PKGFONTSRC?= $($(FONT_TYPE)FONTSRC)
TTFFONTCLS = truetype
OTFFONTCLS = opentype
X11FONTCLS = xorg
PKGFONTCLS?= $($(FONT_TYPE)FONTCLS)
TTFFONTEXT = *.ttc *.tte *.ttf
OTFFONTEXT = *.otf *.otc *.ttf *.ttc
X11FONTEXT =
PKGFONTEXT?= $($(FONT_TYPE)FONTEXT)
PKGFONTCONFSRC = fontconfig
PKGFONTCONFEXT = *.conf
#
# Proto area directories
#
PROTOFONTSDIR = $(PROTO_DIR)$(USRSHAREFONTSDIR)
PROTOTTFFONTSDIR = $(PROTO_DIR)$(TTFFONTDIR)
PROTOOTFFONTSDIR = $(PROTO_DIR)$(OTFFONTDIR)
PROTOX11FONTSDIR = $(PROTO_DIR)$(X11FONTDIR)
PROTOPKGFONTSDIR = $(PROTO$(FONT_TYPE)FONTSDIR)
PROTOFONTSCONFDIR = $(PROTO_DIR)$(ETCFONTSCONFDIR)
#
# Default rules
#
COMPONENT_FONT_TYPE = $(PKGFONTCLS)
COMPONENT_FONT_NAME?= $(COMPONENT_NAME)
COMPONENT_FMRI = \
  system/font/$(strip $(COMPONENT_FONT_TYPE))/$(strip $(COMPONENT_FONT_NAME))
COMPONENT_CLASSIFICATION = System/Fonts
COMPONENT_FONT_DEST_DIR?= $(USRSHAREFONTSDIR)/$(PKGFONTDIR)/$(COMPONENT_FONT_NAME)
COMPONENT_FONT_SRC_DIR ?= $(PKGFONTSRC)
COMPONENT_FONT_FILES    =
COMPONENT_FONTCONF_DEST_DIR?= $(ETCFONTSCONFDIR)
COMPONENT_FONTCONF_SRC_DIR ?= $(PKGFONTCONFSRC)
COMPONENT_FONTCONF_FILES    = $(PKGFONTCONFEXT)
ifeq ($(strip $(BUILD_STYLE)),archive)
POST_INSTALL_MKFONT?=no
COMPONENT_BUILD_ACTION?= true
ifeq ($(strip $(POST_INSTALL_MKFONT)),no)
COMPONENT_BUILD_ACTION = \
  cd $(@D)/$(COMPONENT_FONT_SRC_DIR); $(MKFONTSCALE); $(MKFONTDIR);
endif
$(BUILD_DIR)/%/.built: $(SOURCE_DIR)/.prep
    ($(RM) -rf $(@D) ; $(MKDIR) $(@D))
    $(CLONEY) $(SOURCE_DIR) $(@D)
    $(COMPONENT_PRE_BUILD_ACTION)
    ($(COMPONENT_BUILD_ACTION))
    $(COMPONENT_POST_BUILD_ACTION)
    $(TOUCH) $@
build: $(BUILD_$(MK_BITS))
COMPONENT_FONT_POST_INSTALL_ACTION = \
  ( $(MKFONTSCALE) $(PROTO_DIR)$(COMPONENT_FONT_DEST_DIR); \
    $(MKFONTDIR) $(PROTO_DIR)$(COMPONENT_FONT_DEST_DIR) )
ifeq ($(strip $(POST_INSTALL_MKFONT)),yes)
COMPONENT_POST_INSTALL_ACTION+=$(COMPONENT_FONT_POST_INSTALL_ACTION)
else
COMPONENT_FONT_FILES += fonts.dir
COMPONENT_FONT_FILES += fonts.scale
endif
COMPONENT_INSTALL_ACTION = \
  cd $(@D)/$(COMPONENT_FONT_SRC_DIR) && \
    $(INSTALL) -m 0444 $(COMPONENT_FONT_FILES) \
      $(PROTO_DIR)$(COMPONENT_FONT_DEST_DIR) ; \
  if [ -n "$(strip $(COMPONENT_FONTCONF_FILES))" ]; \
  then \
    cd $(@D)/$(COMPONENT_FONTCONF_SRC_DIR) && \
      $(INSTALL) -m 0444 $(COMPONENT_FONTCONF_FILES) \
        $(PROTO_DIR)$(COMPONENT_FONTCONF_DEST_DIR) ; \
  fi;
$(BUILD_DIR)/%/.installed: $(BUILD_DIR)/%/.built
    $(MKDIR) $(@D)
    $(COMPONENT_PRE_INSTALL_ACTION)
    -$(RM) -r $(PROTO_DIR)$(COMPONENT_FONT_DEST_DIR)
    $(MKDIR) $(PROTO_DIR)$(COMPONENT_FONT_DEST_DIR)
    $(MKDIR) $(PROTO_DIR)$(COMPONENT_FONTCONF_DEST_DIR)
    ($(COMPONENT_INSTALL_ACTION))
    $(COMPONENT_POST_INSTALL_ACTION)
    $(TOUCH) $@
install: $(INSTALL_$(MK_BITS))
clean::
    $(RM) -r $(BUILD_DIR) $(PROTO_DIR)
endif
ifeq ($(strip $(BUILD_STYLE)),configure)
# We don't compress individual font files so that we get better compression
# at higher levels in ZFS & IPS, and so that we aren't constantly replacing
# font files in every build just because the timestamp in the compressed
# version changed.
CONFIGURE_OPTIONS += --without-compression
endif
# Add font metadata to packages to make it easier to search for fonts
$(MANIFEST_BASE)-%.mogrified: PUBLISH_TRANSFORMS += $(@:.mogrified=.font-transforms)
$(MANIFESTS:%.p5m=%.mogrified): font-transforms
font-transforms: $(MANIFESTS:%.p5m=%.font-transforms)
$(MANIFEST_BASE)-%.font-transforms: %.p5m
    $(PERL) $(WS_TOOLS)/generate_font_metadata.pl \
    -p $(PROTO_DIR) -m $< > $@ || ( rm $@ ; exit 1 )
# Package containing fc-scan used in generate_font_metadata.pl
REQUIRED_PACKAGES    += system/library/fontconfig
# Package containing $(MKFONTSCALE) & $(MKFONTDIR)
REQUIRED_PACKAGES    += x11/font-utilities
tools/generate_font_metadata.pl
New file
@@ -0,0 +1,154 @@
#! /usr/perl5/bin/perl -w
#
# Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
#
require 5.005;                # minimal Perl version required
use strict;                #
use diagnostics;            #
use integer;                #
use File::Spec;                # pathname manipulation routines
use English qw( -nomatchvars );
use Getopt::Long;
# Required arguments:
# -p <proto_area>
# -m <manifest>
my $proto_dir;
my $manifest;
my $result = GetOptions('p|protodir=s' => \$proto_dir,
                        'm|manifest=s' => \$manifest);
if (!defined($proto_dir)) {
  print STDERR "Missing required protodir argument\n";
  exit(1);
}
if (!defined($manifest)) {
  print STDERR "Missing required manifest argument\n";
  exit(1);
}
# Directories containing font files
my %fontdirs = ();
open my $MANIFEST, '<', $manifest
  or die "Cannot open manifest $manifest: $!\n";
while (my $man = <$MANIFEST>) {
  if ($man =~ m{path=(\S+)/fonts.dir}) {
    $fontdirs{$1} = $1;
  }
}
close $MANIFEST;
foreach my $fd (keys %fontdirs) {
  my $protofontpath = join('/', $proto_dir, $fd);
  my $protometafile = join('/', $proto_dir, $fd, 'fonts.dir');
  my %xlfds = ();
  if (! -f $protometafile) {
      # mkfontscale -b -s -l is equivalent to mkfontdir
      run_cmd("/usr/bin/mkfontscale", "-b", "-s", "-l",
          $protofontpath);
  }
  open my $XFILE, '<', $protometafile
    or die "Cannot open $protometafile: $!\n";
  while (my $x = <$XFILE>) {
    chomp($x);
    if ($x =~ m{\s+}) {
      my ($fontfile, $fontxlfd) = split(/\s+/, $x, 2);
      $xlfds{$fontxlfd} = $fontfile;
      printf
    qq(<transform file path="$fd/%s" -> add info.file.font.xlfd "%s">\n),
    $fontfile, $fontxlfd;
    }
  }
  close $XFILE;
  $protometafile = join('/', $proto_dir, $fd, 'fonts.alias');
  if (-f $protometafile) {
    open my $XFILE, '<', $protometafile
      or die "Cannot open $protometafile: $!\n";
    while (my $x = <$XFILE>) {
      chomp($x);
      if ($x =~ m{\s+}) {
    my ($fontalias, $fontxlfd) = split(/\s+/, $x, 2);
    $fontxlfd =~ s{^"(.*)"$}{$1};
    if (exists $xlfds{$fontxlfd}) {
      my $fontfile = $xlfds{$fontxlfd};
      printf
        qq(<transform file path="$fd/%s" -> add info.file.font.xlfd "%s">\n),
          $fontfile, $fontalias;
    } else {
#      print STDERR qq(No match found for "$fontxlfd" in $protometafile\n);
    }
      }
    }
    close $XFILE;
  }
}
my $fc_scan = "/usr/bin/fc-scan";
# See FcPatternFormat(3) for the full definition of the format syntax
#  %{file} => print the named value for this font
#  %{fullname|cescape} => print the named value with C-style string escapes
#              (adds \ in front of \ or " characters)
#  %{?fullname{..A..}{..B..}} => if fullname is defined, then print A, else B
#  []fullname,fullnamelang{..A..} => for each pair of fullname & fullnamelang,
#                    print A with those values substituted
my $fc_scan_format = q(--format=%{?fullname{%{[]fullname,fullnamelang{<transform file path="%{file}" -> add info.file.font.name:%{fullnamelang} "%{fullname|cescape}">\n}}}{%{[]family,style{<transform file path="%{file}" -> add info.file.font.name "%{family|cescape} %{style|cescape} %{pixelsize}">\n}}}});
chdir($proto_dir);
run_cmd($fc_scan, $fc_scan_format, keys %fontdirs);
exit(0);
sub run_cmd {
    my $cmd = $_[0];
    system(@_);
    if ($? == -1) {
    print STDERR "failed to execute $cmd: $!\n";
    }
    elsif ($? & 127) {
    printf STDERR "$cmd died with signal %d, %s coredump\n",
    ($? & 127),  ($? & 128) ? 'with' : 'without';
    }
    elsif ($? != 0) {
    my $exit_code = $? >> 8;
    if ($exit_code != 1) {
        printf STDERR "$cmd exited with value %d\n", $exit_code;
        exit($exit_code);
    }
    }
}