/source/otp_src_R14B02/lib/percept/src/egd_font.erl
https://github.com/cparedes/omnibus · Erlang · 175 lines · 96 code · 23 blank · 56 comment · 0 complexity · 726de96a9368a8fd9b7758d252f75d98 MD5 · raw file
- %%
- %% %CopyrightBegin%
- %%
- %% Copyright Ericsson AB 2008-2009. All Rights Reserved.
- %%
- %% The contents of this file are subject to the Erlang Public License,
- %% Version 1.1, (the "License"); you may not use this file except in
- %% compliance with the License. You should have received a copy of the
- %% Erlang Public License along with this software. If not, it can be
- %% retrieved online at http://www.erlang.org/.
- %%
- %% Software distributed under the License is distributed on an "AS IS"
- %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- %% the License for the specific language governing rights and limitations
- %% under the License.
- %%
- %% %CopyrightEnd%
- %%
- %% @doc egd_font
- %%
- -module(egd_font).
- -export([load/1, size/1, glyph/2]).
- -include("egd.hrl").
- %% Font represenatation in ets table
- %% egd_font_table
- %%
- %% Information:
- %% {Key, Description, Size}
- %% Key :: {Font :: atom(), information}
- %% Description :: any(), Description header from font file
- %% Size :: {W :: integer(), H :: integer()}
- %%
- %% Glyphs:
- %% {Key, Translation LSs} where
- %% Key :: {Font :: atom(), Code :: integer()}, Code = glyph char code
- %% Translation :: {
- %% W :: integer(), % BBx width
- %% H :: integer(), % BBx height
- %% X0 :: integer(), % X start
- %% Y0 :: integer(), % Y start
- %% Xm :: integer(), % Glyph X move when drawing
- %% }
- %% LSs :: [[{Xl :: integer(), Xr :: integer()}]]
- %% The first list is height (top to bottom), the inner list is the list
- %% of line spans for the glyphs horizontal pixels.
- %%
- %%==========================================================================
- %%
- %% Interface functions
- %%
- %%==========================================================================
- size(Font) ->
- [{_Key, _Description, Size}] = ets:lookup(egd_font_table,{Font,information}),
- Size.
- glyph(Font, Code) ->
- [{_Key, Translation, LSs}] = ets:lookup(egd_font_table,{Font,Code}),
- {Translation, LSs}.
- load(Filename) ->
- {ok, Bin} = file:read_file(Filename),
- Font = erlang:binary_to_term(Bin),
- load_font_header(Font).
- %%==========================================================================
- %%
- %% Internal functions
- %%
- %%==========================================================================
- %% ETS handler functions
- initialize_table() ->
- ets:new(egd_font_table, [named_table, ordered_set, public]).
- glyph_insert(Font, Code, Translation, LSs) ->
- Element = {{Font, Code}, Translation, LSs},
- ets:insert(egd_font_table, Element).
- font_insert(Font, Description, Dimensions) ->
- Element = {{Font, information}, Description, Dimensions},
- ets:insert(egd_font_table, Element).
- %% Font loader functions
- is_font_loaded(Font) ->
- try
- case ets:lookup(egd_font_table, {Font, information}) of
- [] -> false;
- _ -> true
- end
- catch
- error:_ ->
- initialize_table(),
- false
- end.
-
- load_font_header({_Type, _Version, Font}) ->
- load_font_body(Font).
-
- load_font_body({Key,Desc,W,H,Glyphs,Bitmaps}) ->
- case is_font_loaded(Key) of
- true -> Key;
- false ->
- % insert dimensions
- font_insert(Key, Desc, {W,H}),
- parse_glyphs(Glyphs, Bitmaps, Key),
- Key
- end.
- parse_glyphs([], _ , _Key) -> ok;
- parse_glyphs([Glyph|Glyphs], Bs, Key) ->
- {Code, Translation, LSs} = parse_glyph(Glyph, Bs),
- glyph_insert(Key, Code, Translation, LSs),
- parse_glyphs(Glyphs, Bs, Key).
- parse_glyph({Code,W,H,X0,Y0,Xm,Offset}, Bitmasks) ->
- BytesPerLine = ((W+7) div 8),
- NumBytes = BytesPerLine*H,
- <<_:Offset/binary,Bitmask:NumBytes/binary,_/binary>> = Bitmasks,
- LSs = render_glyph(W,H,X0,Y0,Xm,Bitmask),
- {Code, {W,H,X0,Y0,Xm}, LSs}.
- render_glyph(W, H, X0, Y0, Xm, Bitmask) ->
- render_glyph(W,{0,H},X0,Y0,Xm,Bitmask, []).
- render_glyph(_W, {H,H}, _X0, _Y0, _Xm, _Bitmask, Out) -> Out;
- render_glyph(W, {Hi,H}, X0, Y0,Xm, Bitmask , LSs) ->
- N = ((W+7) div 8),
- O = N*Hi,
- <<_:O/binary, Submask/binary>> = Bitmask,
- LS = render_glyph_horizontal(
- Submask, % line glyph bitmask
- {down, W - 1}, % loop state
- W - 1, % Width
- []), % Linespans
- render_glyph(W,{Hi+1,H},X0,Y0,Xm, Bitmask, [LS|LSs]).
- render_glyph_horizontal(Value, {Pr, Px}, 0, Spans) ->
- Cr = bit_spin(Value, 0),
- case {Pr,Cr} of
- {up , up } -> % closure of interval since its last
- [{0, Px}|Spans];
- {up , down} -> % closure of interval
- [{1, Px}|Spans];
- {down, up } -> % beginning of interval
- [{0, 0}|Spans];
- {down, down} -> % no change in interval
- Spans
- end;
- render_glyph_horizontal(Value, {Pr, Px}, Cx, Spans) ->
- Cr = bit_spin(Value, Cx),
- case {Pr,Cr} of
- {up , up } -> % no change in interval
- render_glyph_horizontal(Value, {Cr, Px}, Cx - 1, Spans);
- {up , down} -> % closure of interval
- render_glyph_horizontal(Value, {Cr, Cx}, Cx - 1, [{Cx+1,Px}|Spans]);
- {down, up } -> % beginning of interval
- render_glyph_horizontal(Value, {Cr, Cx}, Cx - 1, Spans);
- {down, down} -> % no change in interval
- render_glyph_horizontal(Value, {Cr, Px}, Cx - 1, Spans)
- end.
- bit_spin(Value, Cx) ->
- <<_:Cx, Bit:1, _/bits>> = Value,
- case Bit of
- 1 -> up;
- 0 -> down
- end.