电子书阅读器上的浏览器 [Day08] 调整网页字型

https://ithelp.ithome.com.tw/upload/images/20210904/20140260aEL6Aw4ahx.jpg

字型大小

这次的重点是字型。先来说说字型大小。

现在市面上的电子纸设备大大小小各种尺寸都有:从海信出的 A5 手机(5.8寸),A7(6.7寸),Kindle (6寸),到 Onyx 出的 Nova3 (7.8寸),Note3(10寸), Boox Max Lumi(13寸)。每种尺寸都有比较合适的字型大小,如果浏览器可以快速地调整字型大小的话,应该是个很方便的功能。

这对 Android WebView 来说,是件很容易的事。在 WebSettings 中可以直接呼叫函式来达成。

webSettings.setTextZoom(100);

预设字型大小是 100,想要放大或缩小字型,只是改变这个数字就行。这方式虽然修改起来很快速,但是它只会调整到字型的大小,其他画面上的元件并不会随之放大。所以偶尔会看到放大的字体显示超出它原本的范围,是个稍微可以忽略的小缺点。

原本这个 App 就已经有设定字型大小的地方,但是藏很深,我把它变成了随处可呼叫的字型调整对话框,并且将对话框的灰色背景给去掉了,整体看起来更为简洁。

https://ithelp.ithome.com.tw/upload/images/20210907/20140260urGd2L0xbi.jpg

字体粗细

有些网站为了美观,字体可能会选用比较细的,或是在呈现上把颜色调得比较淡。这对电子纸来说,在阅读上都会带来困扰。部分电子书阅读器厂商(像是文石)提供从系统面提供较有弹性的调整方式,让使用者可以视 App 情况自己将字体加粗,或是调高对比度。但这并非每家厂商都有类似的设定可以修改。

所以,如果从浏览器本身能支援调体字型粗细和颜色的话,就能更不受 Eink 设备本身的限制。实作这功能需要对 WebView 注入 Javascript 。作法是将想要注入的 CSS Style 字串,先转成 bytes ,再塞到下面的函式就可以。

private void injectCss(byte[] bytes) {
    try {
        String encoded = Base64.encodeToString(bytes, Base64.NO_WRAP);
        loadUrl("javascript:(function() {" +
                "var parent = document.getElementsByTagName('head').item(0);" +
                "var style = document.createElement('style');" +
                "style.type = 'text/css';" +
                "style.innerHTML = window.atob('" + encoded + "');" +
                "parent.appendChild(style)" +
                "})()");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

上面的作法大致上的概念是:注入 Javascript,在现在的网页中生出一个 的 element,里头有我们要的 style 描述。以加粗这个 style 来说的话,可以注入下面的内容:

* {
  font-weight:700 !important;
}

font-weight 可以是 100 ~ 900。详细的说明可以参考 MDN。而 !important 表示,要盖掉所有其他的设定。

Font-weight on MDN

CSS !important property

效果如下:

修改前 修改後
https://ithelp.ithome.com.tw/upload/images/20210904/20140260YqO1MtMr23.jpg https://ithelp.ithome.com.tw/upload/images/20210904/201402601ah02CKaDx.jpg

更换云端字型

开启 inject Javascript 这扇大门後,许多事都变得可能了。换字型这件事,原本我想要做的是让使用者可以下载字型到手机上,然後再去读取字型来呈现。不过目前还没有找到可以怎麽做。

网路上面的文章都只有提到怎麽将想要的字型塞到 Android 的 asset 目录下,然後从 asset 目录中读取。这种方式没有办法解决使用者自行下载字型的情况。

既然还找不到怎麽读取下载的字型,我又不想塞字型档到浏览器 App 中,因为一个字型至少也是好几 MB 起跳,中文字型的话甚至会到 10 MB 以上,比 App 本身大了许多。

转个念头,不如去载入云端字型好了。虽然每次都要载入,但至少是目前唯一可以换字型又不增加 App 大小的方法。要载入网路字型的话,最有名的莫过於 Google 推出的 Google Font。其中包含了 CJK 字体(Chinese Japanese, Korean),还有其他许多的选择 (可以参考下面连结)。

https://fonts.google.com

目前 Onyx Boox 最新的设备使用的字体是细圆体;而海信手机用的则是黑体。以可读性来说,海信的黑体比细圆体还要易读。但其实我最想要的是明体。所以在 Google Web Font 中找了明体的字型,利用下面的 CSS Style 把网页的字型改掉。

@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+TC:wght@400&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+JP:wght@400&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@400&display=swap');
body {
   "font-family: 'Noto Serif TC', 'Noto Serif JP', 'Noto Serif KR', serif !important;
}

原先只加了 Noto Serif TC ,也就是繁中的明体。但是因为平常还有在看日文和韩文的网页,只有中文变成明体,混在文章里的日文和韩文还是原来的字型,整个感觉很差。所以就也把 JP 和 KR 也加了进来,在繁中找不到时,会依序再去找日文和韩文的对应字型。效果如下:

更换字型前 更换字型後
https://ithelp.ithome.com.tw/upload/images/20210904/20140260XdoAKwuACc.jpg https://ithelp.ithome.com.tw/upload/images/20210904/2014026032b1tB6vHt.jpg

详细的修改内容

这次内容有点多。下回来点轻松的,加几行程序码来支援用音量键翻页。


<<:  [Day 07] 简单的单元测试实作(一)

>>:  JAVA - JAVA Log4j 专门用於 Java 语言的日志记录工具

第30天:《听说做完380个实例,就能成为.NET Core大内高手》里面真的没怎麽讲.NET Core

今天是最後一天了,每天看这本书《听说做完380个实例,就能成为.NET Core大内高手》,真的里面...

Day5. 活用Hash,掌握资料处理的诀窍

Day5. Hash in Ruby 今天我们会介绍Hash,Hash中文为杂凑,不过汉汉老师还是习...

# Day 14 Cache and TLB Flushing Under Linux (Q&A - II)

今天来复习 cache 相关的知识! 首先可以参考一下这篇:Day.8 Cache 的基本原理 ca...

30天程序语言研究

今天是30天程序语言研究的第四天,研究的语言是python,今天主要学习的部分是tuple和func...