Skip to content
This repository has been archived by the owner on Mar 13, 2023. It is now read-only.

Font autoconfigure #97

Merged
merged 61 commits into from
Oct 22, 2016
Merged

Font autoconfigure #97

merged 61 commits into from
Oct 22, 2016

Conversation

dkochmanski
Copy link
Member

Refactor CLX fonts and TTF extension

dkochmanski and others added 30 commits September 21, 2016 09:35
We remove a whole `cond' from the code block, because size is never
NIL (it is preset a few lines earlier). We leave a comment to remember
that during the further refactoring.
Setting size doesn't require lexical scope containing display, so we can
move it earlier.
Separate `find-font' into two smaller functions.
Our autodetection facilities rely either on looking for TTF/ directory
or on fc-match. They return relative and absolute pathnames
accordingly. This commit fixes handling of them. Related to #75.
Add text-style to the message, so the user may verify which font can't
be found (NIL filename doesn't give us much information).
We've used `T', which isn't the right thing to use here.
Abstract `font-acent', `font-descent', `font-glyph-width',
`font-text-extents' and `font-draw-glphs' so we can work on both
truetype fonts and the ordinary fonts provided by X server (extension
specializes on different font type).

Font access will be wrapped in a protocol for truetype (and possibly
other) extensions.
Now that we have unified `font-text-extents', so there is no need to
redefine the method `text-bounding-rectangle' (body is exactly the
same).
Both implementations from truetype and clx/ugly were practically the
same (except a few optimizations to the former). Backported
optimizations and removed truetype one.
Both implementations now are thread-safe (we have lock around the
drawing function) and have additional optimizations. Except that they
are should behave same as before.
Move the dummy case one level up and use return-from there.
If we can't find requested style in our registered TTF fonts, we try to
find them among CLX native fonts.
If the fallback returns NIL (so we don't have such mapping), signal a
MISSING-FONT condition.
I think it might be used in the past, or was planned to be used in the
future, but for now it's just a non-exported interface which isn't used
whoatsoever.
Variable *clx-text-sizes* from clim-clx was duplicated in ttf extensions
under the name *sizes*. Remove the duplication.
native clx backend text-style-mapping stored (font-name . font) in the
text-style unnecessarily, while xrender-ttf extension just holds there
font-value. Unify that.
native clx backend text-style-mapping was searching for the requested
font and this was used by text-style-to-X-font. On the other hand ttf
extension was searching for the font in text-style-to-X-font. We have
unified that and text-style-mapping is the same thing for both
implementations now.
We did triple-checking, first in the hashtable, the second one in the
lookaside variable and the third one in the second hashtable. Unify
behaviour with clx backend which does only one check now.
Use similar pattern as used in text-style-to-X-font in xrender-fonts ttf
extension.
use ensure-gethash idiom
Separate font configuration from xrender-fonts. Also add default path
search which doesn't require shelling out.
Previously slot was unbound on creation.
Previously we only cached basic text-styles. We cache it to ensure
EQL on the same extended styles (family/face designators may be strings
or other kinds of objects).
This class has slots for size and other details, hence it is a font not
a face, which only denotes how it looks like.

Next commits will introduce truetype-face as a separate class.
@jorams
Copy link

jorams commented Oct 3, 2016

There is another library, clx-truetype, that does antialiased TTF font rendering for CLX. Was this looked at?

Rendering using that library tends to perform terribly, so I wonder how the implementation here compares.

xrender-fonts takes care of glueing it, but mcclim-native-ttf is
now reusable.
We have calculated some parameters in make-truetype-font while they
could be (and should) initialized during object creation.
add register-ttf-fonts function to fontconfig which registers all *.ttf
files which may be read by zpb
move register-ttf-fonts function to xrender-fonts, because it is indeed
xrender-fonts specific at the moment.
@stacksmith
Copy link

dkochmanski:
I may be doing something stupid, but I checked out your branch to take a look. Loading via (ql:quickload :mcclim) craps out (sbcl 1.3.8):

The name "ALEXANDRIA" does not designate any package.
   [Condition of type SB-KERNEL:SIMPLE-PACKAGE-ERROR]

Restarts:
 0: [TRY-RECOMPILING] Recompile package and try loading it again
 1: [RETRY] Retry loading FASL for #<CL-SOURCE-FILE "clim-lisp" "package">.
 2: [ACCEPT] Continue, treating loading FASL for #<CL-SOURCE-FILE "clim-lisp" "package"> as having been successful.
 3: [RETRY] Retry ASDF operation.
 4: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting the configuration.
 5: [ABORT] Give up on "mcclim"
 --more--

Backtrace:
  0: (SB-INT:FIND-UNDELETED-PACKAGE-OR-LOSE "ALEXANDRIA")
  1: (SB-IMPL::IMPORT-LIST-SYMBOLS (("ALEXANDRIA" "ENSURE-GETHASH")))
  2: ((FLET SB-IMPL::THUNK :IN SB-IMPL::%DEFPACKAGE))
  3: ((FLET #:WITHOUT-INTERRUPTS-BODY-387 :IN SB-THREAD::CALL-WITH-RECURSIVE-LOCK))
  4: (SB-THREAD::CALL-WITH-RECURSIVE-LOCK #<CLOSURE (FLET SB-THREAD::WITH-RECURSIVE-LOCK-THUNK :IN SB-IMPL::CALL-WITH-PACKAGE-GRAPH) {7FFFE4244B1B}> #<SB-THREAD:MUTEX "Package Graph Lock" owner: #<SB-THREA..
  5: (SB-IMPL::CALL-WITH-PACKAGE-GRAPH #<CLOSURE (FLET SB-IMPL::THUNK :IN SB-IMPL::%DEFPACKAGE) {7FFFE4244B6B}>)
  6: (SB-IMPL::%DEFPACKAGE "CLIM-INTERNALS" ("CLIMI") NIL NIL NIL ("CLIM" "CLIM-SYS" "CLIM-EXTENSIONS" "CLIM-BACKEND" "CLIM-LISP") (("ALEXANDRIA" "ENSURE-GETHASH")) ("LETF") NIL ("CLIM-INTERNALS") NIL NIL ..
  7: (SB-FASL::LOAD-FASL-GROUP #S(SB-FASL::FASL-INPUT :STREAM #<SB-SYS:FD-STREAM for "file /home/stacksmith/.cache/common-lisp/sbcl-1.3.8-linux-x64/home/stacksmith/2016/lisp/McCLIM/package.fasl" {100DDE958..
  8: (SB-FASL::LOAD-AS-FASL #<SB-SYS:FD-STREAM for "file /home/stacksmith/.cache/common-lisp/sbcl-1.3.8-linux-x64/home/stacksmith/2016/lisp/McCLIM/package.fasl" {100DDE9583}> NIL NIL)
  9: ((FLET SB-FASL::LOAD-STREAM :IN LOAD) #<SB-SYS:FD-STREAM for "file /home/stacksmith/.cache/common-lisp/sbcl-1.3.8-linux-x64/home/stacksmith/2016/lisp/McCLIM/package.fasl" {100DDE9583}> T)
 10: (LOAD #P"/home/stacksmith/.cache/common-lisp/sbcl-1.3.8-linux-x64/home/stacksmith/2016/lisp/McCLIM/package.fasl" :VERBOSE NIL :PRINT NIL :IF-DOES-NOT-EXIST T :EXTERNAL-FORMAT :DEFAULT)
 11: (UIOP/UTILITY:CALL-WITH-MUFFLED-CONDITIONS #<CLOSURE (LAMBDA NIL :IN UIOP/LISP-BUILD:LOAD*) {100DDE716B}> ("Overwriting already existing readtable ~S." #(#:FINALIZERS-OFF-WARNING :ASDF-FINALIZERS)))
 12: ((SB-PCL::EMF ASDF/ACTION:PERFORM) #<unavailable argument> #<unavailable argument> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "clim-lisp" "package">)
 13: ((:METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS (ASDF/LISP-ACTION:LOAD-OP ASDF/LISP-ACTION:CL-SOURCE-FILE)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "clim-lisp" "package">) [fast-met..
 14: ((:METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS :AROUND (T T)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "clim-lisp" "package">) [fast-method]
 15: ((:METHOD ASDF/PLAN:PERFORM-PLAN (LIST)) ((#1=#<ASDF/LISP-ACTION:PREPARE-OP > . #2=#<ASDF/SYSTEM:SYSTEM #3="trivial-gray-streams">) (#1# . #4=#<ASDF/LISP-ACTION:CL-SOURCE-FILE #3# "package">) (#5=#<AS..
 16: ((FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT))
 17: ((:METHOD ASDF/PLAN:PERFORM-PLAN :AROUND (T)) ((#1=#<ASDF/LISP-ACTION:PREPARE-OP > . #2=#<ASDF/SYSTEM:SYSTEM #3="trivial-gray-streams">) (#1# . #4=#<ASDF/LISP-ACTION:CL-SOURCE-FILE #3# "package">) (#5..
 18: ((FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT))
 19: ((:METHOD ASDF/PLAN:PERFORM-PLAN :AROUND (T)) #<ASDF/PLAN:SEQUENTIAL-PLAN {100AB45593}> :VERBOSE NIL) [fast-method]
 --more--

@TeMPOraL
Copy link

TeMPOraL commented Oct 5, 2016

Looks to me that Alexandria is referenced in package.lisp in an :import-from clause, but it's not loaded anywhere; in particular, it's not present in :depends-on clause in the mcclim.asd file.

@dkochmanski
Copy link
Member Author

yes, that was me being sloppy, thanks! (last commit fixes this)

@dkochmanski
Copy link
Member Author

@jorams I wasn't aware about that, will check it for sure. Thanks.

@stacksmith
Copy link

stacksmith commented Oct 6, 2016

@jorams, @dkochmanski - it seems that neither McCLIM nor clx-truetype render fonts using sub-pixel antialiasing that makes all the difference visually. This compares McCLIM's font selector demo font with my emacs font (Make sure your browser is not zooming - in firefox, C-0)

here

and magnified

here

Note the top pixel line of the non-rgb antialiased font makes it look really unfortunate...

I am trying to figure it out... xrender supports it...

OK, CLX-TRUETYPE officially does not support it:

TrueType hints are not supported.
RGB antialiasing is not supported.
Text rendering do not use XRender glyph sets. 

CL-CAIRO2 does not seem to do RGB subpixel, or at least I could not coax it to do so.

@dkochmanski
Copy link
Member Author

XRender is an extension which we use to draw fonts ourself (using cl-vectors etc.).

Excerpt from the McCLIM truetype extension readme:

TODO

  • Kerning (we didn't do this with Freetype, either. Oops.)
  • Implement fixed-font-width-p for zpb-ttf.
  • Boxes for missing glyphs.
  • Make certain left/right bearings and text-bounding-rectangle are
    correct. (I doubt they are..)

Wish-list

  • Subpixel antialiasing. It would be straightforward to generate the
    glyphs by tripling the width as passed to cl-vectors and compressing
    triplets of pixels together ourselves. I'm not certain how to draw
    the result through xrender. I've seen hints on Google that there is
    subpixel AA support in xrender, which isn't obvious from CLX or the
    spec. Failing that, we could use a 24bpp mask with component-alpha.
    That might even be how you're supposed to do it. I'm skeptical as to
    whether this would be accelerated for most people.
  • Subpixel positioning. Not hard in principle - render multiple versions
    of each glyph, offset by fractions of a pixel. Horizontal positioning
    is more important than vertical, so 1/4 pixel horizontal resolution
    and 1 pixel vertical resolution should suffice. Given how ugly most
    CLIM apps are, and the lack of WYSIWYG document editors crying out
    for perfect text spacing in small fonts, we don't really need this.

@dkochmanski dkochmanski merged commit f7faabe into master Oct 22, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants