Exemple #1
0
    def write(self, name, dest_dir, docx, variant):
        f = self.fonts[name]
        ef = f.embedded[variant]
        raw = docx.read(ef.name)
        prefix = raw[:32]
        if ef.key:
            key = re.sub(r'[^A-Fa-f0-9]', '', ef.key)
            key = bytearray(
                reversed(
                    tuple(
                        int(key[i:i + 2], 16)
                        for i in xrange(0, len(key), 2))))
            prefix = bytearray(prefix)
            prefix = bytes(
                bytearray(prefix[i] ^ key[i % len(key)]
                          for i in xrange(len(prefix))))
        if not is_truetype_font(prefix):
            return None
        ext = 'otf' if prefix.startswith(b'OTTO') else 'ttf'
        fname = ascii_filename('%s - %s.%s' % (name, variant, ext))
        with open(os.path.join(dest_dir, fname), 'wb') as dest:
            dest.write(prefix)
            dest.write(raw[32:])

        return fname
Exemple #2
0
    def fonts_for_family(self, family, normalize=True):
        family = type("")(family)
        ans = {}
        for weight, is_italic in product((self.w.FW_NORMAL, self.w.FW_BOLD), (False, True)):
            try:
                data = self.w.font_data(family, is_italic, weight)
            except Exception as e:
                prints(
                    "Failed to get font data for font: %s [%s] with error: %s"
                    % (family, self.get_normalized_name(is_italic, weight), e)
                )
                continue

            ok, sig = is_truetype_font(data)
            if not ok:
                prints("Not a supported font, sfnt_version: %r" % sig)
                continue
            ext = "otf" if sig == b"OTTO" else "ttf"

            try:
                weight, is_italic, is_bold, is_regular = get_font_characteristics(data)[:4]
            except Exception as e:
                prints(
                    "Failed to get font characteristic for font: %s [%s]"
                    " with error: %s" % (family, self.get_normalized_name(is_italic, weight), e)
                )
                continue

            try:
                family_name, sub_family_name, full_name = get_font_names(data)
            except:
                pass

            if normalize:
                ft = {(True, True): "bi", (True, False): "italic", (False, True): "bold", (False, False): "normal"}[
                    (is_italic, is_bold)
                ]
            else:
                ft = (1 if is_italic else 0, weight // 10)

            if not (family_name or full_name):
                # prints('Font %s [%s] has no names'%(family,
                #     self.get_normalized_name(is_italic, weight)))
                family_name = family
            name = full_name or family + " " + (sub_family_name or "")

            try:
                name.encode("ascii")
            except ValueError:
                try:
                    sub_family_name.encode("ascii")
                    subf = sub_family_name
                except:
                    subf = ""

                name = family + ((" " + subf) if subf else "")

            ans[ft] = (ext, name, data)

        return ans
Exemple #3
0
    def write(self, name, dest_dir, docx, variant):
        f = self.fonts[name]
        ef = f.embedded[variant]
        raw = docx.read(ef.name)
        prefix = raw[:32]
        if ef.key:
            key = re.sub(r'[^A-Fa-f0-9]', '', ef.key)
            key = bytearray(reversed(tuple(int(key[i:i+2], 16) for i in xrange(0, len(key), 2))))
            prefix = bytearray(prefix)
            prefix = bytes(bytearray(prefix[i]^key[i % len(key)] for i in xrange(len(prefix))))
        if not is_truetype_font(prefix):
            return None
        ext = 'otf' if prefix.startswith(b'OTTO') else 'ttf'
        fname = ascii_filename('%s - %s.%s' % (name, variant, ext))
        with open(os.path.join(dest_dir, fname), 'wb') as dest:
            dest.write(prefix)
            dest.write(raw[32:])

        return fname
Exemple #4
0
    def fonts_for_family(self, family, normalize=True):
        family = unicode_type(family)
        ans = {}
        for weight, is_italic in product((self.w.FW_NORMAL, self.w.FW_BOLD), (False, True)):
            if family in self.app_font_families:
                m = self.app_font_families[family]
                path = m.get((weight, is_italic), None)
                if path is None:
                    continue
                data = P(path, data=True)
            else:
                try:
                    data = self.w.font_data(family, is_italic, weight)
                except Exception as e:
                    prints('Failed to get font data for font: %s [%s] with error: %s'%
                            (family, self.get_normalized_name(is_italic, weight), e))
                    continue

            ok, sig = is_truetype_font(data)
            if not ok:
                prints('Not a supported font, sfnt_version: %r'%sig)
                continue
            ext = 'otf' if sig == b'OTTO' else 'ttf'

            try:
                weight, is_italic, is_bold, is_regular = get_font_characteristics(data)[:4]
            except Exception as e:
                prints('Failed to get font characteristic for font: %s [%s]'
                        ' with error: %s'%(family,
                            self.get_normalized_name(is_italic, weight), e))
                continue

            try:
                family_name, sub_family_name, full_name = get_font_names(data)
            except:
                pass

            if normalize:
                ft = {(True, True):'bi', (True, False):'italic', (False,
                    True):'bold', (False, False):'normal'}[(is_italic,
                        is_bold)]
            else:
                ft = (1 if is_italic else 0, weight//10)

            if not (family_name or full_name):
                # prints('Font %s [%s] has no names'%(family,
                #     self.get_normalized_name(is_italic, weight)))
                family_name = family
            name = full_name or family + ' ' + (sub_family_name or '')

            try:
                name.encode('ascii')
            except ValueError:
                try:
                    sub_family_name.encode('ascii')
                    subf = sub_family_name
                except:
                    subf = ''

                name = family + ((' ' + subf) if subf else '')

            ans[ft] = (ext, name, data)

        return ans
Exemple #5
0
    def fonts_for_family(self, family, normalize=True):
        family = type(u'')(family)
        ans = {}
        for weight, is_italic in product( (self.w.FW_NORMAL, self.w.FW_BOLD), (False, True) ):
            if family in self.app_font_families:
                m = self.app_font_families[family]
                path = m.get((weight, is_italic), None)
                if path is None: continue
                data = P(path, data=True)
            else:
                try:
                    data = self.w.font_data(family, is_italic, weight)
                except Exception as e:
                    prints('Failed to get font data for font: %s [%s] with error: %s'%
                            (family, self.get_normalized_name(is_italic, weight), e))
                    continue

            ok, sig = is_truetype_font(data)
            if not ok:
                prints('Not a supported font, sfnt_version: %r'%sig)
                continue
            ext = 'otf' if sig == b'OTTO' else 'ttf'

            try:
                weight, is_italic, is_bold, is_regular = get_font_characteristics(data)[:4]
            except Exception as e:
                prints('Failed to get font characteristic for font: %s [%s]'
                        ' with error: %s'%(family,
                            self.get_normalized_name(is_italic, weight), e))
                continue

            try:
                family_name, sub_family_name, full_name = get_font_names(data)
            except:
                pass

            if normalize:
                ft = {(True, True):'bi', (True, False):'italic', (False,
                    True):'bold', (False, False):'normal'}[(is_italic,
                        is_bold)]
            else:
                ft = (1 if is_italic else 0, weight//10)

            if not (family_name or full_name):
                # prints('Font %s [%s] has no names'%(family,
                #     self.get_normalized_name(is_italic, weight)))
                family_name = family
            name = full_name or family + ' ' + (sub_family_name or '')

            try:
                name.encode('ascii')
            except ValueError:
                try:
                    sub_family_name.encode('ascii')
                    subf = sub_family_name
                except:
                    subf = ''

                name = family + ((' ' + subf) if subf else '')

            ans[ft] = (ext, name, data)

        return ans