diff --git a/README.md b/README.md index 08c745b2..27f35ab0 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,11 @@ python3 tests/test.input.py # Press CTRL-C to exit # the logs are written to "session.log" python3 tests/test.ui.002.py -python3 tests/test.ui.003.py -python3 tests/test.ui.004.py +python3 tests/test.ui.003.layout.py +python3 tests/test.ui.004.windowspy ``` #### Profiling +##### cProfile ```shell python3 -m cProfile -o profiler.txt tests/test.ui.004.py @@ -33,4 +34,6 @@ python3 -m cProfile -o profiler.txt tests/test.ui.004.py # pip3 install cprofilev cprofilev -f profiler.txt # open http://127.0.0.1:4000 -``` \ No newline at end of file +``` +##### pyroscope +[pyroscope](https://pyroscope.io/) can be used as well for profiling \ No newline at end of file diff --git a/TermTk/TTkCore/__init__.py b/TermTk/TTkCore/__init__.py index d06af7c5..2261574b 100644 --- a/TermTk/TTkCore/__init__.py +++ b/TermTk/TTkCore/__init__.py @@ -1,4 +1,5 @@ from .log import * from .cfg import * +from .signal import pyTTkSlot, pyTTkSignal from .ttk import * from .color import * \ No newline at end of file diff --git a/TermTk/TTkCore/canvas.py b/TermTk/TTkCore/canvas.py index 1bcc3fd1..8964a41d 100644 --- a/TermTk/TTkCore/canvas.py +++ b/TermTk/TTkCore/canvas.py @@ -23,10 +23,12 @@ # SOFTWARE. import TermTk.libbpytop as lbt +from TermTk.TTkCore.constant import TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.cfg import * from TermTk.TTkCore.color import * from TermTk.TTkCore.helper import * +from TermTk.TTkGui.theme import * class TTkCanvas: ''' @@ -45,17 +47,26 @@ class TTkCanvas: in w = the width of the new canvas in h = the height of the new canvas ''' + __slots__ = ('_widget', '_width', '_height', '_newWidth', '_newHeight','_theme', '_data', '_colors', '_visible') def __init__(self, *args, **kwargs): self._widget = kwargs.get('widget', None) - self._width = kwargs.get('width', 0 ) - self._height = kwargs.get('height', 0 ) - self.resize(self._width, self._height) + self._visible = True + self._width = 0 + self._height = 0 + self._newWidth = kwargs.get('width', 0 ) + self._newHeight = kwargs.get('height', 0 ) + self.updateSize() + # self.resize(self._width, self._height) + self._theme = TTkTheme() # TTkLog.debug((self._width, self._height)) def getWidget(self): return self._widget - def resize(self, w, h): - # TTkLog.debug(f"CanvasResize:{(w,h)}") + def updateSize(self): + if not self._visible: return + w,h = self._newWidth, self._newHeight + if w == self._width and h == self._height: + return self._data = [[]]*h self._colors = [[]]*h for i in range(0,h): @@ -64,7 +75,12 @@ class TTkCanvas: self._width = w self._height = h + def resize(self, w, h): + self._newWidth = w + self._newHeight = h + def clean(self, pos=(0, 0), size=None): + if not self._visible: return x,y = pos w,h = size if size is not None else (self._width, self._height) for iy in range(y,y+h): @@ -72,46 +88,95 @@ class TTkCanvas: self._data[iy][ix] = ' ' self._colors[iy][ix] = TTkColor.RST + def hide(self): + self._visible = False + + def show(self): + self._visible = True + + def zTop(self): # TODO: Figure out how to use this pass + def _set(self, _y, _x, _ch, _col=TTkColor.RST): + if _y < self._height and \ + _x < self._width and \ + _x >= 0 and _y >=0 : + self._data[_y][_x] = _ch + self._colors[_y][_x] = _col + def drawText(self, pos, text, color=TTkColor.RST): - def _set(_y,_x,_c): - if _y < self._height and \ - _x < self._width and \ - _x >= 0 and _y >=0 : - self._data[_y][_x] = _c - self._colors[_y][_x] = color + if not self._visible: return x,y = pos arr = list(text) for i in range(0, len(arr)): - _set(y, x+i, arr[i]) + self._set(y, x+i, arr[i], color) def drawBox(self, pos, size, color=TTkColor.RST): + self.drawGrid(pos=pos, size=size, color=color) + + def drawGrid(self, pos, size, hlines=[], vlines=[], color=TTkColor.RST): + if not self._visible: return x,y = pos w,h = size - # TODO: Handle Clip/OutOfBorder - def _set(_y,_x,_c): - if _y < self._height and \ - _x < self._width and \ - _x >= 0 and _y >=0 : - self._data[_y][_x] = _c - self._colors[_y][_x] = color # 4 corners - _set(y, x, "╔") - _set(y, x+w-1, "╗") - _set(y+h-1, x, "╚") - _set(y+h-1, x+w-1, "╝") + self._set(y, x, self._theme.grid[2], color) + self._set(y, x+w-1, self._theme.grid[3], color) + self._set(y+h-1, x, self._theme.grid[4], color) + self._set(y+h-1, x+w-1, self._theme.grid[5], color) if w > 2: for i in range(x+1,x+w-1): - _set(y, i, "═") - _set(y+h-1, i, "═") + self._set(y, i, self._theme.grid[0], color) + self._set(y+h-1, i, self._theme.grid[0], color) if h > 2: for i in range(y+1,y+h-1): - _set(i, x, "║") - _set(i, x+w-1, "║") + self._set(i, x, self._theme.grid[1], color) + self._set(i, x+w-1, self._theme.grid[1], color) + # Draw horizontal lines + for iy in hlines: + iy += y + if not (0 < iy < h): continue + self._set(iy, x, self._theme.grid[6], color) + self._set(iy, x+w-1, self._theme.grid[7], color) + if w > 2: + for ix in range(x+1,x+w-1): + self._set(iy, ix, self._theme.grid[10], color) + # Draw vertical lines + for ix in vlines: + ix+=x + if not (0 < ix < w): continue + self._set(y, ix, self._theme.grid[8], color) + self._set(y+h-1, ix, self._theme.grid[9], color) + if h > 2: + for iy in range(y+1,y+h-1): + self._set(iy, ix, self._theme.grid[11], color) + # Draw intersections + for iy in hlines: + for ix in vlines: + self._set(y+iy, x+ix, self._theme.grid[12], color) + + def drawScroll(self, pos, size, slider, orientation, color): + if not self._visible: return + x,y = pos + f,t = slider # slider from-to position + if orientation == TTkK.HORIZONTAL: + for i in range(x+1,x+size-1): + self._set(y,x+i, self._theme.hscroll[1], color) + for i in range(f,t): + self._set(y,x+i, self._theme.hscroll[2], color) + self._set(y,x, self._theme.hscroll[0], color) + self._set(y,x+size-1, self._theme.hscroll[3], color) + else: + for i in range(y+1,y+size-1): + self._set(y+i,x, self._theme.vscroll[1], color) + for i in range(f,t): + self._set(y+i,x, self._theme.vscroll[2], color) + self._set(y,x, self._theme.vscroll[0], color) + self._set(y+size-1,x, self._theme.vscroll[3], color) + + pass def execPaint(self, winw, winh): pass @@ -125,6 +190,8 @@ class TTkCanvas: x, y, w, h = geom bx,by,bw,bh = bound # out of bound + if not self._visible: return + if not canvas._visible: return if x+w < bx or y+h=self._width: x=self._width-1 diff --git a/TermTk/TTkCore/constant.py b/TermTk/TTkCore/constant.py new file mode 100644 index 00000000..9a97d8ba --- /dev/null +++ b/TermTk/TTkCore/constant.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# 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 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. + +class TTkConstant: + MOUSE_EVENT = 0x01 + KEY_EVENT = 0x02 + SCREEN_EVENT = 0x04 + QUIT_EVENT = 0x08 + TIME_EVENT = 0x10 + + HORIZONTAL = 0x01 + VERTICAL = 0x02 + + # Keys + NoButton = 0x00000000 # The button state does not refer to any button (see QMouseEvent::button()). + AllButtons = 0x07ffffff # This value corresponds to a mask of all possible mouse buttons. Use to set the 'acceptedButtons' property of a MouseArea to accept ALL mouse buttons. + LeftButton = 0x00000001 # The left button is pressed, or an event refers to the left button. (The left button may be the right button on left-handed mice.) + RightButton = 0x00000002 # The right button. + MidButton = 0x00000004 # The middle button. + MiddleButton = MidButton # The middle button. + Wheel = 0x00000008 + + # Events + NoEvent = 0x00000000 + Press = 0x00010000 + Release = 0x00020000 + Drag = 0x00040000 + Move = 0x00080000 + WHEEL_Up = 0x00100000 # Wheel Up + WHEEL_Down = 0x00200000 # Wheel Down + +# Alias to TTkConstant +class TTkK(TTkConstant): pass \ No newline at end of file diff --git a/TermTk/TTkCore/helper.py b/TermTk/TTkCore/helper.py index b4a1ea57..f18d8664 100644 --- a/TermTk/TTkCore/helper.py +++ b/TermTk/TTkCore/helper.py @@ -57,9 +57,14 @@ class TTkHelper: #processed = [] pushToTerminal = False for widget in TTkHelper._updateBuffer: + if not widget.isVisible(): continue + # Resize the canvas just before the paintEvent + # to avoid too many allocations + widget.getCanvas().updateSize() widget.paintEvent() TTkHelper._updateBuffer = [] for widget in TTkHelper._updateWidget: + if not widget.isVisible(): continue pushToTerminal = True #processed.append(widget) widget.paintChildCanvas() diff --git a/TermTk/TTkCore/signal.py b/TermTk/TTkCore/signal.py new file mode 100644 index 00000000..e666aeaa --- /dev/null +++ b/TermTk/TTkCore/signal.py @@ -0,0 +1,92 @@ + +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# 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 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. + +''' +ref: http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html + https://github.com/ceccopierangiolieugenio/pyCuT/blob/master/cupy/CuTCore/CuSignal.py +''' + +# dummy decorator +def pyTTkSlot(*args, **kwargs): + def pyTTkSlot_d(func): + # Add signature attributes to the function + func._TTkslot_attr = args + return func + return pyTTkSlot_d + +def pyTTkSignal(*args, **kwargs): + return pyTTkSignal_obj(*args, **kwargs) + +class pyTTkSignal_obj(): + ''' + ref: http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html#PyQt5.QtCore.pyqtSignal + + PyQt5.QtCore.pyqtSignal(types[, name[, revision=0[, arguments=[]]]]) + Create one or more overloaded unbound signals as a class attribute. + + Parameters: + types - the types that define the C++ signature of the signal. Each type may be a Python type object or a string that is the name of a C++ type. Alternatively each may be a sequence of type arguments. In this case each sequence defines the signature of a different signal overload. The first overload will be the default. + name - the name of the signal. If it is omitted then the name of the class attribute is used. This may only be given as a keyword argument. + revision - the revision of the signal that is exported to QML. This may only be given as a keyword argument. + arguments - the sequence of the names of the signal's arguments that is exported to QML. This may only be given as a keyword argument. + Return type: + an unbound signal + ''' + __slots__ = ('_types', '_name', '_revision', '_connected_slots') + def __init__(self, *args, **kwargs): + self._types = args + self._name = kwargs.get('name', None) + self._revision = kwargs.get('revision', 0) + self._connected_slots = [] + + ''' + ref: http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html#connect + + connect(slot[, type=PyQt5.QtCore.Qt.AutoConnection[, no_receiver_check=False]]) -> PyQt5.QtCore.QMetaObject.Connection + Connect a signal to a slot. An exception will be raised if the connection failed. + + Parameters: + slot - the slot to connect to, either a Python callable or another bound signal. + type - the type of the connection to make. + no_receiver_check - suppress the check that the underlying C++ receiver instance still exists and deliver the signal anyway. + Returns: + a Connection object which can be passed to disconnect(). This is the only way to disconnect a connection to a lambda function. + ''' + def connect(self, slot): + if hasattr(slot, '_TTkslot_attr') and slot._TTkslot_attr != self._types: + error = "Decorated slot has no signature compatible: "+slot.__name__+str(slot._TTkslot_attr)+" != signal"+str(self._types) + raise TypeError(error) + self._connected_slots.append(slot) + + def disconnect(self, *args, **kwargs): + for slot in args: + self._connected_slots.remove(slot) + + def emit(self, *args, **kwargs): + if len(args) != len(self._types): + error = "func"+str(self._types)+" signal has "+str(len(self._types))+" argument(s) but "+str(len(args))+" provided" + raise TypeError(error) + for slot in self._connected_slots: + slot(*args, **kwargs) diff --git a/TermTk/TTkCore/ttk.py b/TermTk/TTkCore/ttk.py index f37bbf29..1a57aa19 100644 --- a/TermTk/TTkCore/ttk.py +++ b/TermTk/TTkCore/ttk.py @@ -27,6 +27,7 @@ import time import threading, queue import TermTk.libbpytop as lbt +from TermTk.TTkCore.constant import TTkConstant, TTkK from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.cfg import * from TermTk.TTkCore.canvas import * @@ -53,14 +54,14 @@ class TTk(TTkWidget): mouse_events = None screen_events = None - MOUSE_EVENT = 0x01 - KEY_EVENT = 0x02 - SCREEN_EVENT = 0x04 - QUIT_EVENT = 0x08 - TIME_EVENT = 0x10 + MOUSE_EVENT = TTkK.MOUSE_EVENT + KEY_EVENT = TTkK.KEY_EVENT + SCREEN_EVENT = TTkK.SCREEN_EVENT + QUIT_EVENT = TTkK.QUIT_EVENT + TIME_EVENT = TTkK.TIME_EVENT - HORIZONTAL = 0x01 - VERTICAL = 0x02 + HORIZONTAL = TTkConstant.HORIZONTAL + VERTICAL = TTkConstant.VERTICAL def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) diff --git a/TermTk/TTkGui/__init__.py b/TermTk/TTkGui/__init__.py new file mode 100644 index 00000000..3ccf92e3 --- /dev/null +++ b/TermTk/TTkGui/__init__.py @@ -0,0 +1 @@ +from .theme import * \ No newline at end of file diff --git a/TermTk/TTkGui/theme.py b/TermTk/TTkGui/theme.py new file mode 100644 index 00000000..8d9fbde1 --- /dev/null +++ b/TermTk/TTkGui/theme.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# 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 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. + +class TTkTheme(): + ''' from: https://en.wikipedia.org/wiki/Box-drawing_character + ┌─┬┐ ╔═╦╗ ╓─╥╖ ╒═╤╕ + │ ││ ║ ║║ ║ ║║ │ ││ + ├─┼┤ ╠═╬╣ ╟─╫╢ ╞═╪╡ + └─┴┘ ╚═╩╝ ╙─╨╜ ╘═╧╛ + ┌───────────────────┐ + │ ╔═══╗ Some Text │▒ + │ ╚═╦═╝ in the box │▒ + ╞═╤══╩══╤═══════════╡▒ + │ ├──┬──┤ │▒ + │ └──┴──┘ │▒ + └───────────────────┘▒ + ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ +''' + box = ( '═','║', + '╔','╗', + '╚','╝') + + grid = ( '═','║', + '╔','╗', + '╚','╝', + '╟','╢','╤','╧', + '─','│','┼',) + + hscroll = ('◀','┄','▓','▶') + vscroll = ('▲','┊','▓','▼') \ No newline at end of file diff --git a/TermTk/TTkWidgets/__init__.py b/TermTk/TTkWidgets/__init__.py index 8e5214f8..a80295ce 100644 --- a/TermTk/TTkWidgets/__init__.py +++ b/TermTk/TTkWidgets/__init__.py @@ -1,8 +1,10 @@ from .widget import * from .layout import * +from .spacer import * from .frame import * from .button import * from .label import * +from .scrollbar import * from .window import * from .logviewer import * from .testwidget import * \ No newline at end of file diff --git a/TermTk/TTkWidgets/button.py b/TermTk/TTkWidgets/button.py index 96674aca..374fd2d4 100644 --- a/TermTk/TTkWidgets/button.py +++ b/TermTk/TTkWidgets/button.py @@ -30,13 +30,13 @@ class TTkButton(TTkWidget): __slots__ = ('_text', '_border', '_pressed') def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) - self._text = kwargs.get('text', "" ) + self._name = kwargs.get('name' , 'TTkButton' ) + self.text = kwargs.get('text', "" ) self._border = kwargs.get('border', True ) if self._border: - self._padt = 1 - self._padb = 1 - self._padl = 1 - self._padr = 1 + self.setMinimumSize(2+len(self.text), 3) + else: + self.setMinimumSize(len(self.text), 1) self._pressed = False self.setFocusPolicy(TTkWidget.ClickFocus) @@ -47,7 +47,7 @@ class TTkButton(TTkWidget): else: borderColor = TTkColor.fg("#ffff00") textColor = TTkColor.fg("#00ff00") - self._canvas.drawText(pos=(1,1), color=textColor ,text=self._text) + self._canvas.drawText(pos=(1,1), color=textColor ,text=self.text) if self._border: self._canvas.drawBox(pos=(0,0),size=(self._width,self._height),color=borderColor) @@ -59,4 +59,14 @@ class TTkButton(TTkWidget): def mouseReleaseEvent(self, evt): TTkLog.debug(f"{self._name} Test Mouse {evt}") self._pressed = False + self.update() + + @property + def text(self): + return self._text + + @text.setter + def text(self, text): + self._text = text + self.setMinimumSize(len(text), 1) self.update() \ No newline at end of file diff --git a/TermTk/TTkWidgets/frame.py b/TermTk/TTkWidgets/frame.py index b906e370..77afd4c1 100644 --- a/TermTk/TTkWidgets/frame.py +++ b/TermTk/TTkWidgets/frame.py @@ -29,6 +29,7 @@ class TTkFrame(TTkWidget): __slots__ = ('_border') def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkFrame' ) self._border = kwargs.get('border', True ) if self._border: self.setPadding(1,1,1,1) diff --git a/TermTk/TTkWidgets/label.py b/TermTk/TTkWidgets/label.py index a6ae6561..68cd028c 100644 --- a/TermTk/TTkWidgets/label.py +++ b/TermTk/TTkWidgets/label.py @@ -26,20 +26,36 @@ from TermTk.TTkCore.log import TTkLog from .widget import * class TTkLabel(TTkWidget): - __slots__ = ('_text') + __slots__ = ('_text', '_color') def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) - self._text = kwargs.get('text', "" ) + self._name = kwargs.get('name' , 'TTkLabel' ) + self._text = "" + self._color = TTkColor.RST + self.text = kwargs.get('text', "" ) + self.color = kwargs.get('color', TTkColor.RST ) def paintEvent(self): - self._canvas.drawText(pos=(0,0), text=self._text) + self._canvas.drawText(pos=(0,0), text=' '*self.width(), color=self.color) + self._canvas.drawText(pos=(0,0), text=self.text, color=self.color) @property - def Abouttext(self): + def text(self): return self._text - @Abouttext.setter - def Abouttext(self, text): - self._text = text - self.setMinimumSize(len(text), 1) - self.update() \ No newline at end of file + @text.setter + def text(self, text): + if self.text != text: + self._text = text + self.setMinimumSize(len(text), 1) + self.update() + + @property + def color(self): + return self._color + + @color.setter + def color(self, color): + if self.color != color: + self._color = color + self.update() \ No newline at end of file diff --git a/TermTk/TTkWidgets/layout.py b/TermTk/TTkWidgets/layout.py index 883cf63a..b2cdfbbc 100644 --- a/TermTk/TTkWidgets/layout.py +++ b/TermTk/TTkWidgets/layout.py @@ -1,7 +1,33 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# 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 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. + ''' Layout System ''' +from TermTk.TTkCore.log import TTkLog + class TTkLayoutItem: __slots__ = ('_x', '_y', '_w', '_h', '_sMax', '_sMaxVal', '_sMin', '_sMinVal') def __init__(self): @@ -146,14 +172,18 @@ class TTkHBoxLayout(TTkLayout): item._sMax = False item._sMin = False iterate = True + + # Copy and Sort list of items based on the minsize + sortedItems = sorted(self.children(), key=lambda item: item.minimumWidth()) + while iterate and leftWidgets > 0: iterate = False - sliceSize = freeWidth//leftWidgets - for item in self.children(): + for item in sortedItems: if item._sMax or item._sMin: continue + sliceSize = freeWidth//leftWidgets maxs = item.maximumWidth() mins = item.minimumWidth() - if sliceSize > maxs: + if sliceSize >= maxs: freeWidth -= maxs iterate = True item._sMax = True @@ -162,7 +192,6 @@ class TTkHBoxLayout(TTkLayout): elif sliceSize < mins: freeWidth -= mins leftWidgets -= 1 - # slicesize = freeWidth//leftWidgets iterate = True item._sMin = True item._sMinVal = mins @@ -235,14 +264,18 @@ class TTkVBoxLayout(TTkLayout): item._sMax = False item._sMin = False iterate = True + + # Copy and Sort list of items based on the minsize + sortedItems = sorted(self.children(), key=lambda item: item.minimumHeight()) + while iterate and leftWidgets > 0: iterate = False - sliceSize = freeHeight//leftWidgets - for item in self.children(): + for item in sortedItems: if item._sMax or item._sMin: continue + sliceSize = freeHeight//leftWidgets maxs = item.maximumHeight() mins = item.minimumHeight() - if sliceSize > maxs: + if sliceSize >= maxs: freeHeight -= maxs iterate = True item._sMax = True @@ -251,7 +284,6 @@ class TTkVBoxLayout(TTkLayout): elif sliceSize < mins: freeHeight -= mins leftWidgets -= 1 - # slicesize = freeHeight//leftWidgets iterate = True item._sMin = True item._sMinVal = mins diff --git a/TermTk/TTkWidgets/scrollbar.py b/TermTk/TTkWidgets/scrollbar.py new file mode 100644 index 00000000..68fe3f3a --- /dev/null +++ b/TermTk/TTkWidgets/scrollbar.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# 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 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. + +from TermTk.TTkCore.constant import TTkK +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkCore.color import TTkColor +from TermTk.TTkWidgets.widget import TTkWidget + +class TTkScrollBar(TTkWidget): + __slots__ = ( + '_orientation', + '_minimum', '_maximum', + '_singlestep', '_pagestep', + '_value', '_color') + + def __init__(self, *args, **kwargs): + TTkWidget.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkScrollBar' ) + self._orientation = kwargs.get('orientation' , TTkK.VERTICAL ) + if self._orientation == TTkK.VERTICAL: + self.setMaximumWidth(1) + self.setMinimumSize(1,3) + else: + self.setMaximumHeight(1) + self.setMinimumSize(3,1) + self._minimum = kwargs.get('minimum' , 0 ) + self._maximum = kwargs.get('maximum' , 99 ) + self._singlestep = kwargs.get('singlestep' , 1 ) + self._pagestep = kwargs.get('pagestep' , 10 ) + self._value = kwargs.get('value' , 0 ) + self._color = kwargs.get('color', TTkColor.RST ) + self.update() + + ''' + | min | max + <-----XXXXX--------> scrollbar + |------------------| size = widt or height + |----------------| size2 = widt or height - 2 (removed the ending arrows) + |------------| workingSize = max - min + |----------------| drawingSize = max - min + pagestep + a---b slider = [a=value-min, b=a+pagestep] + |---| pagestep + + ''' + def paintEvent(self): + if self._orientation == TTkK.VERTICAL: + size=self._height + else: + size=self._width + size2 = size-2 + drawingSize = self._maximum - self._minimum + self._pagestep + a = self._value - self._minimum + b = a + self._pagestep + # covert i screen coordinates + aa = 1+a*size2//drawingSize + bb = 1+b*size2//drawingSize + self._canvas.drawScroll(pos=(0,0),size=size,slider=(aa,bb),orientation=self._orientation, color=self.color) + + @property + def minimum(self): return self._minimum + @minimum.setter + def minimum(self, v): self._minimum = v; self.update() + + @property + def maximum(self): return self._maximum + @minimum.setter + def minimum(self, v): self._maximum = v; self.update() + + @property + def singlestep(self): return self._singlestep + @singlestep.setter + def singlestep(self, v): self._singlestep = v; self.update() + + @property + def pagestep(self): return self._pagestep + @pagestep.setter + def pagestep(self, v): self._pagestep = v; self.update() + + @property + def value(self): return self._value + @value.setter + def value(self, v): + if v > self._maximum: v = self._maximum + if v < self._minimum: v = self._minimum + self._value = v + self.update() + + def wheelEvent(self, evt): + if evt.evt == TTkK.WHEEL_Up: + self.value = self._value - self._pagestep + else: + self.value = self._value + self._pagestep + + @property + def color(self): + return self._color + @color.setter + def color(self, color): + if self.color != color: + self._color = color + self.update() \ No newline at end of file diff --git a/TermTk/TTkWidgets/spacer.py b/TermTk/TTkWidgets/spacer.py new file mode 100644 index 00000000..d60acdb6 --- /dev/null +++ b/TermTk/TTkWidgets/spacer.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# 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 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. + +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkWidgets.widget import TTkWidget + +class TTkSpacer(TTkWidget): + def __init__(self, *args, **kwargs): + TTkWidget.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkSpacer') + self.hide() \ No newline at end of file diff --git a/TermTk/TTkWidgets/splitter.py b/TermTk/TTkWidgets/splitter.py index 62e03235..87c2902a 100644 --- a/TermTk/TTkWidgets/splitter.py +++ b/TermTk/TTkWidgets/splitter.py @@ -33,6 +33,7 @@ class TTkSplitter(TTkFrame): __slots__ = ('_widgets', '_orientation', '_splitters', '_selected') def __init__(self, *args, **kwargs): TTkFrame.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkSplitter' ) self._widgets = [] self._splitters = [] self._orientation = kwargs.get('orientation' , TTk.HORIZONTAL ) diff --git a/TermTk/TTkWidgets/testwidget.py b/TermTk/TTkWidgets/testwidget.py index b742048c..921fcc54 100644 --- a/TermTk/TTkWidgets/testwidget.py +++ b/TermTk/TTkWidgets/testwidget.py @@ -26,17 +26,13 @@ from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.color import TTkColor from TermTk.TTkWidgets.widget import * from TermTk.TTkWidgets.button import * +from TermTk.TTkWidgets.label import * from TermTk.TTkWidgets.frame import * class _TestContent(TTkWidget): def paintEvent(self): # TTkLog.debug(f"Test Paint - {self._name}") - self._canvas.drawText(pos=(0,0),text=f"Test Widget [{self._parent._name}]") - self._canvas.drawText(pos=(0,1),text=f"x,y ({self._parent._x},{self._parent._y})") - self._canvas.drawText(pos=(0,2),text=f"w,h ({self._parent._width},{self._parent._height})") - self._canvas.drawText(pos=(0,3),text=f"max w,h ({self._parent._maxw},{self._parent._maxh})") - self._canvas.drawText(pos=(0,4),text=f"min w,h ({self._parent._minw},{self._parent._minh})") - y=6; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#ff0000"),text="Lorem ipsum dolor sit amet,") + y=0; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#ff0000"),text="Lorem ipsum dolor sit amet,") y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#ff8800"),text="consectetur adipiscing elit,") y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#ffff00"),text="sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#00ff00"),text="Ut enim ad minim veniam,") @@ -44,21 +40,41 @@ class _TestContent(TTkWidget): y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#0088ff"),text="Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.") y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#0000ff"),text="Excepteur sint occaecat cupidatat non proident,") y+=1; self._canvas.drawText(pos=(0,y),color=TTkColor.fg("#ff00ff"),text="sunt in culpa qui officia deserunt mollit anim id est laborum.") + y+=1; self._canvas.drawGrid( + pos=(0,y),size=(self._width,self._height-y), + hlines=(2,5,7), vlines=(4,7,15,30), + color=TTkColor.fg("#aaffaa")) class TTkTestWidget(TTkFrame): ID = 1 - __slots__ = ('_name') + __slots__ = ('_name', '_l') def __init__(self, *args, **kwargs): TTkFrame.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkTestWidget' ) #self.setLayout(TTkHBoxLayout()) self._name = f"TestWidget-{TTkTestWidget.ID}" t,_,l,_ = self.getPadding() TTkButton(parent=self, x=l, y=t, width=15, height=3, text=' Test Button') - _TestContent(parent=self, x=l, y=3+t, width=50, height=50, name=f"content-{self._name}") + self._l = [ + TTkLabel(parent=self,pos=(l, t+3), size=(50,1), color=TTkColor.fg("#ff0000")+TTkColor.bg("#ffff88"), text="pippo"), + TTkLabel(parent=self,pos=(l, t+4), size=(50,1), color=TTkColor.fg("#0000ff")+TTkColor.bg("#ff8888")), + TTkLabel(parent=self,pos=(l, t+5), size=(50,1), color=TTkColor.fg("#0044ff")+TTkColor.bg("#ff88ff")), + TTkLabel(parent=self,pos=(l, t+6), size=(50,1), color=TTkColor.fg("#aaff00")+TTkColor.bg("#8888ff")), + TTkLabel(parent=self,pos=(l, t+7), size=(50,1), color=TTkColor.fg("#8800ff")+TTkColor.bg("#88ffff")), + ] + _TestContent(parent=self, x=l, y=t+8, width=50, height=50, name=f"content-{self._name}") TTkTestWidget.ID+=1 + def paintEvent(self): + self._l[0].text=f"Test Widget [{self._name}]" + self._l[1].text=f"x,y ({self._x},{self._y})" + self._l[2].text=f"w,h ({self._width},{self._height})" + self._l[3].text=f"max w,h ({self._maxw},{self._maxh})" + self._l[4].text=f"min w,h ({self._minw},{self._minh})" + + def mousePressEvent(self, evt): TTkLog.debug(f"{self._name} Test Mouse {evt}") diff --git a/TermTk/TTkWidgets/widget.py b/TermTk/TTkWidgets/widget.py index 92b0cd85..15127663 100644 --- a/TermTk/TTkWidgets/widget.py +++ b/TermTk/TTkWidgets/widget.py @@ -61,7 +61,7 @@ class TTkWidget: '_padt', '_padb', '_padl', '_padr', '_maxw', '_maxh', '_minw', '_minh', '_focus','_focus_policy', - '_layout', '_canvas') + '_layout', '_canvas', '_visible') def __init__(self, *args, **kwargs): self._name = kwargs.get('name', None ) @@ -87,6 +87,8 @@ class TTkWidget: self._minh = kwargs.get('minHeight', 0x00000) self._minw, self._minh = kwargs.get('minSize', (self._minw, self._minh)) + self._visible = kwargs.get('visible', True) + self._focus = False self._focus_policy = TTkWidget.NoFocus @@ -94,12 +96,11 @@ class TTkWidget: widget = self, width = self._width , height = self._height ) - - self.setLayout(TTkLayout()) + self.setLayout(kwargs.get('layout',TTkLayout())) if self._parent is not None and \ self._parent._layout is not None: self._parent._layout.addWidget(self) - self._parent._layout.update() + self._parent.update(repaint=True, updateLayout=True) self.update(repaint=True, updateLayout=True) @@ -181,12 +182,13 @@ class TTkWidget: x, y = evt.x, evt.y lx,ly,lw,lh =layout.geometry() # opt of bounds - if x<0 or x>lw or y<0 or y>lh: + if xlx+lw or ylh+ly: return True for i in range(layout.count()): item = layout.itemAt(i) if isinstance(item, TTkWidgetItem) and not item.isEmpty(): widget = item.widget() + if not widget._visible: continue wevt = None mouseEvent = False if isinstance(evt, lbt.MouseEvent): @@ -301,14 +303,14 @@ class TTkWidget: def maximumHeight(self): wMaxH = self._maxh if self._layout is not None: - lMaxH = self._layout.maximumHeight() + self._padl + self._padr + lMaxH = self._layout.maximumHeight() + self._padt + self._padb if lMaxH < wMaxH: return lMaxH return wMaxH def maximumWidth(self): wMaxW = self._maxw if self._layout is not None: - lMaxW = self._layout.maximumWidth() + self._padt + self._padb + lMaxW = self._layout.maximumWidth() + self._padl + self._padr if lMaxW < wMaxW: return lMaxW return wMaxW @@ -318,14 +320,14 @@ class TTkWidget: def minimumHeight(self): wMinH = self._minh if self._layout is not None: - lMinH = self._layout.minimumHeight() + self._padl + self._padr + lMinH = self._layout.minimumHeight() + self._padt + self._padb if lMinH > wMinH: return lMinH return wMinH def minimumWidth(self): wMinW = self._minw if self._layout is not None: - lMinW = self._layout.minimumWidth() + self._padt + self._padb + lMinW = self._layout.minimumWidth() + self._padl + self._padr if lMinW > wMinW: return lMinW return wMinW @@ -333,21 +335,67 @@ class TTkWidget: def setMaximumSize(self, maxw, maxh): self.setMaximumWidth(maxw) self.setMaximumHeight(maxh) - def setMaximumHeight(self, maxh): self._maxh = maxh - def setMaximumWidth(self, maxw): self._maxw = maxw + def setMaximumHeight(self, maxh): + self._maxh = maxh + self.update(updateLayout=True, updateParent=True) + def setMaximumWidth(self, maxw): + self._maxw = maxw + self.update(updateLayout=True, updateParent=True) def setMinimumSize(self, minw, minh): self.setMinimumWidth(minw) self.setMinimumHeight(minh) - def setMinimumHeight(self, minh): self._minh = minh - def setMinimumWidth(self, minw): self._minw = minw - - def update(self, repaint=True, updateLayout=False): + def setMinimumHeight(self, minh): + self._minh = minh + self.update(updateLayout=True, updateParent=True) + def setMinimumWidth(self, minw): + self._minw = minw + self.update(updateLayout=True, updateParent=True) + + #@staticmethod + #def _showHandle(layout): + # for i in range(layout.count()): + # item = layout.itemAt(i) + # if isinstance(item, CuWidgetItem) and not item.isEmpty(): + # item.widget().show() + # elif isinstance(item, CuLayout): + # CuWidget._showHandle(item) + + def show(self): + self._canvas.show() + self._visible = True + self.update() + # if self._data['layout'] is not None: + # CuWidget._showHandle(self._data['layout']) + + #@staticmethod + #def _hideHandle(layout): + # for i in range(layout.count()): + # item = layout.itemAt(i) + # if isinstance(item, CuWidgetItem) and not item.isEmpty(): + # item.widget().hide() + # elif isinstance(item, CuLayout): + # CuWidget._hideHandle(item) + + def hide(self): + self._canvas.hide() + self._visible = False + #self._parent._canvas.clean(self.pos(),self.size()) + self.update() + # if self._layout is not None: + # TTkWidget._hideHandle(self._layout]) + + def isVisible(self): + return self._visible + + def update(self, repaint=True, updateLayout=False, updateParent=False): if repaint: TTkHelper.addUpdateBuffer(self) TTkHelper.addUpdateWidget(self) if updateLayout and self._layout is not None: self._layout.update() + if updateParent and self._parent is not None: + self._parent.update(updateLayout=True) def setFocus(self): tmp = TTkHelper.getFocus() diff --git a/TermTk/TTkWidgets/window.py b/TermTk/TTkWidgets/window.py index 0870a9a2..4c5d276d 100644 --- a/TermTk/TTkWidgets/window.py +++ b/TermTk/TTkWidgets/window.py @@ -32,6 +32,7 @@ class TTkWindow(TTkWidget): __slots__ = ('_title', '_mouseDelta', '_draggable', '_resizable') def __init__(self, *args, **kwargs): TTkWidget.__init__(self, *args, **kwargs) + self._name = kwargs.get('name' , 'TTkWindow' ) self._title = kwargs.get('title' , 0 ) self.setPadding(3,1,1,1) self._mouseDelta = (0,0) @@ -44,9 +45,13 @@ class TTkWindow(TTkWidget): color = TTkColor.fg("#ffff55") else: color = TTkColor.RST - self._canvas.drawBox(pos=(0,0), color=color, size=(self._width,3)) - self._canvas.drawBox(pos=(0,2), color=color, size=(self._width,self._height-2)) - self._canvas.drawText(pos=(0,2), color=color, text="╟"+("─"*(self._width-2))+"╢") + self._canvas.drawGrid( + color=color, + pos=(0,0), size=self.size(), + hlines=[2]) + #self._canvas.drawBox(pos=(0,0), color=color, size=(self._width,3)) + #self._canvas.drawBox(pos=(0,2), color=color, size=(self._width,self._height-2)) + #self._canvas.drawText(pos=(0,2), color=color, text="╟"+("─"*(self._width-2))+"╢") self._canvas.drawText(pos=(2,1),text=self._title) def mousePressEvent(self, evt): @@ -85,18 +90,22 @@ class TTkWindow(TTkWidget): dy = evt.y-self._mouseDelta[1] if self._resizable & TTkWidget.LEFT: tmpw = w-dx - if minw < tmpw < maxw: - x += dx ; w -= tmpw + if minw > tmpw: tmpw=minw; dx= w-tmpw + elif maxw < tmpw: tmpw=minw; dx= w-tmpw + x += dx ; w = tmpw elif self._resizable & TTkWidget.RIGHT: - if minw < evt.x < maxw: - w = evt.x + if minw > evt.x: w = minw + elif maxw < evt.x: w = maxw + else: w = evt.x if self._resizable & TTkWidget.TOP: tmph = h-dy - if minh < tmph < maxh: - y += dy ; h = tmph + if minh > tmph: tmph=minh; dy= h-tmph + elif maxh < tmph: tmph=minh; dy= h-tmph + y += dy ; h = tmph elif self._resizable & TTkWidget.BOTTOM: - if minh < evt.y < maxh: - h = evt.y + if minh > evt.y: h = minh + elif maxh < evt.y: h = maxh + else: h = evt.y self.move(x,y) self.resize(w,h) diff --git a/TermTk/__init__.py b/TermTk/__init__.py index 9af0948e..8300a7cb 100644 --- a/TermTk/__init__.py +++ b/TermTk/__init__.py @@ -1,2 +1,3 @@ from .TTkCore import * +from .TTkGui import * from .TTkWidgets import * \ No newline at end of file diff --git a/TermTk/libbpytop/input.py b/TermTk/libbpytop/input.py index 36094da3..f8ac3380 100644 --- a/TermTk/libbpytop/input.py +++ b/TermTk/libbpytop/input.py @@ -27,26 +27,27 @@ except Exception as e: print(f'ERROR: {e}') exit(1) -import TermTk as ttk +from TermTk.TTkCore.log import TTkLog +from TermTk.TTkCore.constant import TTkK class MouseEvent: # Keys - NoButton = 0x00000000 # The button state does not refer to any button (see QMouseEvent::button()). - AllButtons = 0x07ffffff # This value corresponds to a mask of all possible mouse buttons. Use to set the 'acceptedButtons' property of a MouseArea to accept ALL mouse buttons. - LeftButton = 0x00000001 # The left button is pressed, or an event refers to the left button. (The left button may be the right button on left-handed mice.) - RightButton = 0x00000002 # The right button. - MidButton = 0x00000004 # The middle button. - MiddleButton = MidButton # The middle button. - Wheel = 0x00000008 + NoButton = TTkK.NoButton # The button state does not refer to any button (see QMouseEvent::button()). + AllButtons = TTkK.AllButtons # This value corresponds to a mask of all possible mouse buttons. Use to set the 'acceptedButtons' property of a MouseArea to accept ALL mouse buttons. + LeftButton = TTkK.LeftButton # The left button is pressed, or an event refers to the left button. (The left button may be the right button on left-handed mice.) + RightButton = TTkK.RightButton # The right button. + MidButton = TTkK.MidButton # The middle button. + MiddleButton = TTkK.MiddleButton # The middle button. + Wheel = TTkK.Wheel # Events - NoEvent = 0x00000000 - Press = 0x00010000 - Release = 0x00020000 - Drag = 0x00040000 - Move = 0x00080000 - Up = 0x00100000 # Wheel Up - Down = 0x00200000 # Wheel Down + NoEvent = TTkK.NoEvent + Press = TTkK.Press + Release = TTkK.Release + Drag = TTkK.Drag + Move = TTkK.Move + Up = TTkK.WHEEL_Up + Down = TTkK.WHEEL_Down __slots__ = ('x','y','key','evt','raw') def __init__(self, x: int, y: int, key: int, evt: int, raw: str): @@ -131,7 +132,7 @@ class Input: input_key += sys.stdin.read(20) if input_key.startswith("\033[<"): _ = sys.stdin.read(1000) - # ttk.debug("INPUT: "+input_key.replace("\033","")) + # TTkLog.debug("INPUT: "+input_key.replace("\033","")) mevt = None kevt = None if len(input_key) == 1: @@ -142,7 +143,7 @@ class Input: m = mouse_re.match(input_key) if not m: # TODO: Return Error - ttk.TTkLog.error("UNHANDLED: "+input_key.replace("\033","")) + TTkLog.error("UNHANDLED: "+input_key.replace("\033","")) continue code = int(m.group(1)) x = int(m.group(2))-1 @@ -176,7 +177,7 @@ class Input: evt = MouseEvent.Down mevt = MouseEvent(x, y, key, evt, m.group(0).replace("\033", "")) else: - ttk.TTkLog.error("UNHANDLED: "+input_key.replace("\033","")) + TTkLog.error("UNHANDLED: "+input_key.replace("\033","")) input_key = "" if callback is not None: if not callback(kevt, mevt): diff --git a/docs/TODO.md b/docs/TODO.md index 62c74ecc..9ba2f0b1 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -1,37 +1,41 @@ # TODO - [ ] Follow [PEP 8](https://www.python.org/dev/peps/pep-0008/) coding style +- [ ] Use @property/@setter when possible +- [ ] Move the Global Constants outside TTk object ## Terminal Helper - - [ ] Events - - [x] Window : SIGWINCH triggered when the terminal is resized +- [ ] Events + - [x] Window : SIGWINCH triggered when the terminal is resized ## Input Class - - [ ] Return Error if Mouse RE does not match - - [x] Handle the Paste Buffer - - [ ] Investigate the middle mouse button paste - *note: It works only in "INSERT" mode on Vim* - - [ ] Handle Special Keys (UP, Down, . . .) - - [ ] Events - https://tkinterexamples.com/events/events.html - https://www.pythontutorial.net/tkinter/tkinter-event-binding/ - - [x] Keyboard - - [x] Mouse +- [ ] Return Error if Mouse RE does not match +- [x] Handle the Paste Buffer +- [ ] Investigate the middle mouse button paste + *note: It works only in "INSERT" mode on Vim* +- [ ] Handle Special Keys (UP, Down, . . .) +- [ ] Events + https://tkinterexamples.com/events/events.html + https://www.pythontutorial.net/tkinter/tkinter-event-binding/ + - [x] Keyboard + - [x] Mouse ## Canvas Class - - [ ] Have a look to the Unicode chartable: https://www.utf8-chartable.de/unicode-utf8-table.pl +- [ ] Have a look to the Unicode chartable: https://www.utf8-chartable.de/unicode-utf8-table.pl -## Signal Slots -- [ ] Implement Signal Slots +## Signal/Slots +- [ ] Implement Signal/Slots ## Logs - - [x] Log Class - - [ ] Run Logger on a separate thread (push sring to a queue) - - [ ] Include option to force print - - [ ] Log helpers - - [x] File and Stdout logger - - [ ] logger auto integration - - [ ] stdout until mainLoop +- [x] Log Class +- [ ] Run Logger on a separate thread (push sring to a queue) + - [ ] Include option to force print +- [ ] Log helpers + - [x] File and Stdout logger +- [ ] logger auto integration + - [ ] stdout until mainLoop ## Widgets +- [ ] Add Size Policy (fixed minimum maximum expanding) +- [ ] Add Show/Hide ### Layout - [ ] Add Weight in V and H Layout \ No newline at end of file diff --git a/tests/test.ui.005.labels.py b/tests/test.ui.005.labels.py index 3cae8e23..13e36610 100755 --- a/tests/test.ui.005.labels.py +++ b/tests/test.ui.005.labels.py @@ -40,7 +40,7 @@ ttk.TTkLabel(parent=win1, text="Test Label 3") ttk.TTkLabel(parent=win1, text="Test Label 4") ttk.TTkLabel(parent=win1, text="Test Label 5") ttk.TTkLabel(parent=win1, text="Test Label 6") -ttk.TTkLabel(parent=win1, text="Test Very Long Label 7") +ttk.TTkLabel(parent=win1, text="Test Very Long Label 7 - abcdefghihjlmno") ttk.TTkLabel(parent=win1, text="Test Label 8") ttk.TTkLabel(parent=win1, text="Test Label 9") ttk.TTkLabel(parent=win1, text="Test Label 10") diff --git a/tests/test.ui.006.scroll.py b/tests/test.ui.006.scroll.py new file mode 100755 index 00000000..629b4a1e --- /dev/null +++ b/tests/test.ui.006.scroll.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +# MIT License +# +# Copyright (c) 2021 Eugenio Parodi +# +# 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 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. + +import sys, os + +sys.path.append(os.path.join(sys.path[0],'..')) +import TermTk as ttk + +ttk.TTkLog.use_default_file_logging() + +root = ttk.TTk() + +win1 = ttk.TTkWindow(parent=root,pos = (1,1), size=(30,40), title="Test Window 1", border=True) +win1.setLayout(ttk.TTkVBoxLayout()) +top = ttk.TTkFrame(parent=win1, layout=ttk.TTkHBoxLayout()) +ttk.TTkScrollBar(parent=win1, orientation=ttk.TTk.HORIZONTAL, value=0, color=ttk.TTkColor.bg('#990044')+ttk.TTkColor.fg('#ffff00')) +ttk.TTkScrollBar(parent=win1, orientation=ttk.TTk.HORIZONTAL, value=10, color=ttk.TTkColor.bg('#770044')+ttk.TTkColor.fg('#ccff00')) +ttk.TTkScrollBar(parent=win1, orientation=ttk.TTk.HORIZONTAL, value=50, color=ttk.TTkColor.bg('#660044')+ttk.TTkColor.fg('#88ff00')) +ttk.TTkScrollBar(parent=win1, orientation=ttk.TTk.HORIZONTAL, value=80, color=ttk.TTkColor.bg('#550044')+ttk.TTkColor.fg('#55ff00')) +ttk.TTkScrollBar(parent=win1, orientation=ttk.TTk.HORIZONTAL, value=99, color=ttk.TTkColor.bg('#330044')+ttk.TTkColor.fg('#33ff00')) + + +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=0) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=10) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=40) +ttk.TTkSpacer(parent=top) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=40) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=50) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=60) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=70) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=80) +ttk.TTkSpacer(parent=top) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=80) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=90) +ttk.TTkScrollBar(parent=top, orientation=ttk.TTk.VERTICAL, value=99) + + +root.mainloop() \ No newline at end of file diff --git a/tests/utf-8/utf-8.block.elements.txt b/tests/utf-8/utf-8.block.elements.txt new file mode 100644 index 00000000..08e632f9 --- /dev/null +++ b/tests/utf-8/utf-8.block.elements.txt @@ -0,0 +1,256 @@ +U+2580 ▀ e2 96 80 UPPER HALF BLOCK +U+2581 ▁ e2 96 81 LOWER ONE EIGHTH BLOCK +U+2582 ▂ e2 96 82 LOWER ONE QUARTER BLOCK +U+2583 ▃ e2 96 83 LOWER THREE EIGHTHS BLOCK +U+2584 ▄ e2 96 84 LOWER HALF BLOCK +U+2585 ▅ e2 96 85 LOWER FIVE EIGHTHS BLOCK +U+2586 ▆ e2 96 86 LOWER THREE QUARTERS BLOCK +U+2587 ▇ e2 96 87 LOWER SEVEN EIGHTHS BLOCK +U+2588 █ e2 96 88 FULL BLOCK +U+2589 ▉ e2 96 89 LEFT SEVEN EIGHTHS BLOCK +U+258A ▊ e2 96 8a LEFT THREE QUARTERS BLOCK +U+258B ▋ e2 96 8b LEFT FIVE EIGHTHS BLOCK +U+258C ▌ e2 96 8c LEFT HALF BLOCK +U+258D ▍ e2 96 8d LEFT THREE EIGHTHS BLOCK +U+258E ▎ e2 96 8e LEFT ONE QUARTER BLOCK +U+258F ▏ e2 96 8f LEFT ONE EIGHTH BLOCK +U+2590 ▐ e2 96 90 RIGHT HALF BLOCK +U+2591 ░ e2 96 91 LIGHT SHADE +U+2592 ▒ e2 96 92 MEDIUM SHADE +U+2593 ▓ e2 96 93 DARK SHADE +U+2594 ▔ e2 96 94 UPPER ONE EIGHTH BLOCK +U+2595 ▕ e2 96 95 RIGHT ONE EIGHTH BLOCK +U+2596 ▖ e2 96 96 QUADRANT LOWER LEFT +U+2597 ▗ e2 96 97 QUADRANT LOWER RIGHT +U+2598 ▘ e2 96 98 QUADRANT UPPER LEFT +U+2599 ▙ e2 96 99 QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT +U+259A ▚ e2 96 9a QUADRANT UPPER LEFT AND LOWER RIGHT +U+259B ▛ e2 96 9b QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT +U+259C ▜ e2 96 9c QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT +U+259D ▝ e2 96 9d QUADRANT UPPER RIGHT +U+259E ▞ e2 96 9e QUADRANT UPPER RIGHT AND LOWER LEFT +U+259F ▟ e2 96 9f QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT +U+25A0 ■ e2 96 a0 BLACK SQUARE +U+25A1 □ e2 96 a1 WHITE SQUARE +U+25A2 ▢ e2 96 a2 WHITE SQUARE WITH ROUNDED CORNERS +U+25A3 ▣ e2 96 a3 WHITE SQUARE CONTAINING BLACK SMALL SQUARE +U+25A4 ▤ e2 96 a4 SQUARE WITH HORIZONTAL FILL +U+25A5 ▥ e2 96 a5 SQUARE WITH VERTICAL FILL +U+25A6 ▦ e2 96 a6 SQUARE WITH ORTHOGONAL CROSSHATCH FILL +U+25A7 ▧ e2 96 a7 SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL +U+25A8 ▨ e2 96 a8 SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL +U+25A9 ▩ e2 96 a9 SQUARE WITH DIAGONAL CROSSHATCH FILL +U+25AA ▪ e2 96 aa BLACK SMALL SQUARE +U+25AB ▫ e2 96 ab WHITE SMALL SQUARE +U+25AC ▬ e2 96 ac BLACK RECTANGLE +U+25AD ▭ e2 96 ad WHITE RECTANGLE +U+25AE ▮ e2 96 ae BLACK VERTICAL RECTANGLE +U+25AF ▯ e2 96 af WHITE VERTICAL RECTANGLE +U+25B0 ▰ e2 96 b0 BLACK PARALLELOGRAM +U+25B1 ▱ e2 96 b1 WHITE PARALLELOGRAM +U+25B2 ▲ e2 96 b2 BLACK UP-POINTING TRIANGLE +U+25B3 △ e2 96 b3 WHITE UP-POINTING TRIANGLE +U+25B4 ▴ e2 96 b4 BLACK UP-POINTING SMALL TRIANGLE +U+25B5 ▵ e2 96 b5 WHITE UP-POINTING SMALL TRIANGLE +U+25B6 ▶ e2 96 b6 BLACK RIGHT-POINTING TRIANGLE +U+25B7 ▷ e2 96 b7 WHITE RIGHT-POINTING TRIANGLE +U+25B8 ▸ e2 96 b8 BLACK RIGHT-POINTING SMALL TRIANGLE +U+25B9 ▹ e2 96 b9 WHITE RIGHT-POINTING SMALL TRIANGLE +U+25BA ► e2 96 ba BLACK RIGHT-POINTING POINTER +U+25BB ▻ e2 96 bb WHITE RIGHT-POINTING POINTER +U+25BC ▼ e2 96 bc BLACK DOWN-POINTING TRIANGLE +U+25BD ▽ e2 96 bd WHITE DOWN-POINTING TRIANGLE +U+25BE ▾ e2 96 be BLACK DOWN-POINTING SMALL TRIANGLE +U+25BF ▿ e2 96 bf WHITE DOWN-POINTING SMALL TRIANGLE +U+25C0 ◀ e2 97 80 BLACK LEFT-POINTING TRIANGLE +U+25C1 ◁ e2 97 81 WHITE LEFT-POINTING TRIANGLE +U+25C2 ◂ e2 97 82 BLACK LEFT-POINTING SMALL TRIANGLE +U+25C3 ◃ e2 97 83 WHITE LEFT-POINTING SMALL TRIANGLE +U+25C4 ◄ e2 97 84 BLACK LEFT-POINTING POINTER +U+25C5 ◅ e2 97 85 WHITE LEFT-POINTING POINTER +U+25C6 ◆ e2 97 86 BLACK DIAMOND +U+25C7 ◇ e2 97 87 WHITE DIAMOND +U+25C8 ◈ e2 97 88 WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND +U+25C9 ◉ e2 97 89 FISHEYE +U+25CA ◊ e2 97 8a LOZENGE +U+25CB ○ e2 97 8b WHITE CIRCLE +U+25CC ◌ e2 97 8c DOTTED CIRCLE +U+25CD ◍ e2 97 8d CIRCLE WITH VERTICAL FILL +U+25CE ◎ e2 97 8e BULLSEYE +U+25CF ● e2 97 8f BLACK CIRCLE +U+25D0 ◐ e2 97 90 CIRCLE WITH LEFT HALF BLACK +U+25D1 ◑ e2 97 91 CIRCLE WITH RIGHT HALF BLACK +U+25D2 ◒ e2 97 92 CIRCLE WITH LOWER HALF BLACK +U+25D3 ◓ e2 97 93 CIRCLE WITH UPPER HALF BLACK +U+25D4 ◔ e2 97 94 CIRCLE WITH UPPER RIGHT QUADRANT BLACK +U+25D5 ◕ e2 97 95 CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK +U+25D6 ◖ e2 97 96 LEFT HALF BLACK CIRCLE +U+25D7 ◗ e2 97 97 RIGHT HALF BLACK CIRCLE +U+25D8 ◘ e2 97 98 INVERSE BULLET +U+25D9 ◙ e2 97 99 INVERSE WHITE CIRCLE +U+25DA ◚ e2 97 9a UPPER HALF INVERSE WHITE CIRCLE +U+25DB ◛ e2 97 9b LOWER HALF INVERSE WHITE CIRCLE +U+25DC ◜ e2 97 9c UPPER LEFT QUADRANT CIRCULAR ARC +U+25DD ◝ e2 97 9d UPPER RIGHT QUADRANT CIRCULAR ARC +U+25DE ◞ e2 97 9e LOWER RIGHT QUADRANT CIRCULAR ARC +U+25DF ◟ e2 97 9f LOWER LEFT QUADRANT CIRCULAR ARC +U+25E0 ◠ e2 97 a0 UPPER HALF CIRCLE +U+25E1 ◡ e2 97 a1 LOWER HALF CIRCLE +U+25E2 ◢ e2 97 a2 BLACK LOWER RIGHT TRIANGLE +U+25E3 ◣ e2 97 a3 BLACK LOWER LEFT TRIANGLE +U+25E4 ◤ e2 97 a4 BLACK UPPER LEFT TRIANGLE +U+25E5 ◥ e2 97 a5 BLACK UPPER RIGHT TRIANGLE +U+25E6 ◦ e2 97 a6 WHITE BULLET +U+25E7 ◧ e2 97 a7 SQUARE WITH LEFT HALF BLACK +U+25E8 ◨ e2 97 a8 SQUARE WITH RIGHT HALF BLACK +U+25E9 ◩ e2 97 a9 SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK +U+25EA ◪ e2 97 aa SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK +U+25EB ◫ e2 97 ab WHITE SQUARE WITH VERTICAL BISECTING LINE +U+25EC ◬ e2 97 ac WHITE UP-POINTING TRIANGLE WITH DOT +U+25ED ◭ e2 97 ad UP-POINTING TRIANGLE WITH LEFT HALF BLACK +U+25EE ◮ e2 97 ae UP-POINTING TRIANGLE WITH RIGHT HALF BLACK +U+25EF ◯ e2 97 af LARGE CIRCLE +U+25F0 ◰ e2 97 b0 WHITE SQUARE WITH UPPER LEFT QUADRANT +U+25F1 ◱ e2 97 b1 WHITE SQUARE WITH LOWER LEFT QUADRANT +U+25F2 ◲ e2 97 b2 WHITE SQUARE WITH LOWER RIGHT QUADRANT +U+25F3 ◳ e2 97 b3 WHITE SQUARE WITH UPPER RIGHT QUADRANT +U+25F4 ◴ e2 97 b4 WHITE CIRCLE WITH UPPER LEFT QUADRANT +U+25F5 ◵ e2 97 b5 WHITE CIRCLE WITH LOWER LEFT QUADRANT +U+25F6 ◶ e2 97 b6 WHITE CIRCLE WITH LOWER RIGHT QUADRANT +U+25F7 ◷ e2 97 b7 WHITE CIRCLE WITH UPPER RIGHT QUADRANT +U+25F8 ◸ e2 97 b8 UPPER LEFT TRIANGLE +U+25F9 ◹ e2 97 b9 UPPER RIGHT TRIANGLE +U+25FA ◺ e2 97 ba LOWER LEFT TRIANGLE +U+25FB ◻ e2 97 bb WHITE MEDIUM SQUARE +U+25FC ◼ e2 97 bc BLACK MEDIUM SQUARE +U+25FD ◽ e2 97 bd WHITE MEDIUM SMALL SQUARE +U+25FE ◾ e2 97 be BLACK MEDIUM SMALL SQUARE +U+25FF ◿ e2 97 bf LOWER RIGHT TRIANGLE +U+2600 ☀ e2 98 80 BLACK SUN WITH RAYS +U+2601 ☁ e2 98 81 CLOUD +U+2602 ☂ e2 98 82 UMBRELLA +U+2603 ☃ e2 98 83 SNOWMAN +U+2604 ☄ e2 98 84 COMET +U+2605 ★ e2 98 85 BLACK STAR +U+2606 ☆ e2 98 86 WHITE STAR +U+2607 ☇ e2 98 87 LIGHTNING +U+2608 ☈ e2 98 88 THUNDERSTORM +U+2609 ☉ e2 98 89 SUN +U+260A ☊ e2 98 8a ASCENDING NODE +U+260B ☋ e2 98 8b DESCENDING NODE +U+260C ☌ e2 98 8c CONJUNCTION +U+260D ☍ e2 98 8d OPPOSITION +U+260E ☎ e2 98 8e BLACK TELEPHONE +U+260F ☏ e2 98 8f WHITE TELEPHONE +U+2610 ☐ e2 98 90 BALLOT BOX +U+2611 ☑ e2 98 91 BALLOT BOX WITH CHECK +U+2612 ☒ e2 98 92 BALLOT BOX WITH X +U+2613 ☓ e2 98 93 SALTIRE +U+2614 ☔ e2 98 94 UMBRELLA WITH RAIN DROPS +U+2615 ☕ e2 98 95 HOT BEVERAGE +U+2616 ☖ e2 98 96 WHITE SHOGI PIECE +U+2617 ☗ e2 98 97 BLACK SHOGI PIECE +U+2618 ☘ e2 98 98 SHAMROCK +U+2619 ☙ e2 98 99 REVERSED ROTATED FLORAL HEART BULLET +U+261A ☚ e2 98 9a BLACK LEFT POINTING INDEX +U+261B ☛ e2 98 9b BLACK RIGHT POINTING INDEX +U+261C ☜ e2 98 9c WHITE LEFT POINTING INDEX +U+261D ☝ e2 98 9d WHITE UP POINTING INDEX +U+261E ☞ e2 98 9e WHITE RIGHT POINTING INDEX +U+261F ☟ e2 98 9f WHITE DOWN POINTING INDEX +U+2620 ☠ e2 98 a0 SKULL AND CROSSBONES +U+2621 ☡ e2 98 a1 CAUTION SIGN +U+2622 ☢ e2 98 a2 RADIOACTIVE SIGN +U+2623 ☣ e2 98 a3 BIOHAZARD SIGN +U+2624 ☤ e2 98 a4 CADUCEUS +U+2625 ☥ e2 98 a5 ANKH +U+2626 ☦ e2 98 a6 ORTHODOX CROSS +U+2627 ☧ e2 98 a7 CHI RHO +U+2628 ☨ e2 98 a8 CROSS OF LORRAINE +U+2629 ☩ e2 98 a9 CROSS OF JERUSALEM +U+262A ☪ e2 98 aa STAR AND CRESCENT +U+262B ☫ e2 98 ab FARSI SYMBOL +U+262C ☬ e2 98 ac ADI SHAKTI +U+262D ☭ e2 98 ad HAMMER AND SICKLE +U+262E ☮ e2 98 ae PEACE SYMBOL +U+262F ☯ e2 98 af YIN YANG +U+2630 ☰ e2 98 b0 TRIGRAM FOR HEAVEN +U+2631 ☱ e2 98 b1 TRIGRAM FOR LAKE +U+2632 ☲ e2 98 b2 TRIGRAM FOR FIRE +U+2633 ☳ e2 98 b3 TRIGRAM FOR THUNDER +U+2634 ☴ e2 98 b4 TRIGRAM FOR WIND +U+2635 ☵ e2 98 b5 TRIGRAM FOR WATER +U+2636 ☶ e2 98 b6 TRIGRAM FOR MOUNTAIN +U+2637 ☷ e2 98 b7 TRIGRAM FOR EARTH +U+2638 ☸ e2 98 b8 WHEEL OF DHARMA +U+2639 ☹ e2 98 b9 WHITE FROWNING FACE +U+263A ☺ e2 98 ba WHITE SMILING FACE +U+263B ☻ e2 98 bb BLACK SMILING FACE +U+263C ☼ e2 98 bc WHITE SUN WITH RAYS +U+263D ☽ e2 98 bd FIRST QUARTER MOON +U+263E ☾ e2 98 be LAST QUARTER MOON +U+263F ☿ e2 98 bf MERCURY +U+2640 ♀ e2 99 80 FEMALE SIGN +U+2641 ♁ e2 99 81 EARTH +U+2642 ♂ e2 99 82 MALE SIGN +U+2643 ♃ e2 99 83 JUPITER +U+2644 ♄ e2 99 84 SATURN +U+2645 ♅ e2 99 85 URANUS +U+2646 ♆ e2 99 86 NEPTUNE +U+2647 ♇ e2 99 87 PLUTO +U+2648 ♈ e2 99 88 ARIES +U+2649 ♉ e2 99 89 TAURUS +U+264A ♊ e2 99 8a GEMINI +U+264B ♋ e2 99 8b CANCER +U+264C ♌ e2 99 8c LEO +U+264D ♍ e2 99 8d VIRGO +U+264E ♎ e2 99 8e LIBRA +U+264F ♏ e2 99 8f SCORPIUS +U+2650 ♐ e2 99 90 SAGITTARIUS +U+2651 ♑ e2 99 91 CAPRICORN +U+2652 ♒ e2 99 92 AQUARIUS +U+2653 ♓ e2 99 93 PISCES +U+2654 ♔ e2 99 94 WHITE CHESS KING +U+2655 ♕ e2 99 95 WHITE CHESS QUEEN +U+2656 ♖ e2 99 96 WHITE CHESS ROOK +U+2657 ♗ e2 99 97 WHITE CHESS BISHOP +U+2658 ♘ e2 99 98 WHITE CHESS KNIGHT +U+2659 ♙ e2 99 99 WHITE CHESS PAWN +U+265A ♚ e2 99 9a BLACK CHESS KING +U+265B ♛ e2 99 9b BLACK CHESS QUEEN +U+265C ♜ e2 99 9c BLACK CHESS ROOK +U+265D ♝ e2 99 9d BLACK CHESS BISHOP +U+265E ♞ e2 99 9e BLACK CHESS KNIGHT +U+265F ♟ e2 99 9f BLACK CHESS PAWN +U+2660 ♠ e2 99 a0 BLACK SPADE SUIT +U+2661 ♡ e2 99 a1 WHITE HEART SUIT +U+2662 ♢ e2 99 a2 WHITE DIAMOND SUIT +U+2663 ♣ e2 99 a3 BLACK CLUB SUIT +U+2664 ♤ e2 99 a4 WHITE SPADE SUIT +U+2665 ♥ e2 99 a5 BLACK HEART SUIT +U+2666 ♦ e2 99 a6 BLACK DIAMOND SUIT +U+2667 ♧ e2 99 a7 WHITE CLUB SUIT +U+2668 ♨ e2 99 a8 HOT SPRINGS +U+2669 ♩ e2 99 a9 QUARTER NOTE +U+266A ♪ e2 99 aa EIGHTH NOTE +U+266B ♫ e2 99 ab BEAMED EIGHTH NOTES +U+266C ♬ e2 99 ac BEAMED SIXTEENTH NOTES +U+266D ♭ e2 99 ad MUSIC FLAT SIGN +U+266E ♮ e2 99 ae MUSIC NATURAL SIGN +U+266F ♯ e2 99 af MUSIC SHARP SIGN +U+2670 ♰ e2 99 b0 WEST SYRIAC CROSS +U+2671 ♱ e2 99 b1 EAST SYRIAC CROSS +U+2672 ♲ e2 99 b2 UNIVERSAL RECYCLING SYMBOL +U+2673 ♳ e2 99 b3 RECYCLING SYMBOL FOR TYPE-1 PLASTICS +U+2674 ♴ e2 99 b4 RECYCLING SYMBOL FOR TYPE-2 PLASTICS +U+2675 ♵ e2 99 b5 RECYCLING SYMBOL FOR TYPE-3 PLASTICS +U+2676 ♶ e2 99 b6 RECYCLING SYMBOL FOR TYPE-4 PLASTICS +U+2677 ♷ e2 99 b7 RECYCLING SYMBOL FOR TYPE-5 PLASTICS +U+2678 ♸ e2 99 b8 RECYCLING SYMBOL FOR TYPE-6 PLASTICS +U+2679 ♹ e2 99 b9 RECYCLING SYMBOL FOR TYPE-7 PLASTICS +U+267A ♺ e2 99 ba RECYCLING SYMBOL FOR GENERIC MATERIALS +U+267B ♻ e2 99 bb BLACK UNIVERSAL RECYCLING SYMBOL +U+267C ♼ e2 99 bc RECYCLED PAPER SYMBOL +U+267D ♽ e2 99 bd PARTIALLY-RECYCLED PAPER SYMBOL +U+267E ♾ e2 99 be PERMANENT PAPER SIGN +U+267F ♿ e2 99 bf WHEELCHAIR SYMBOL \ No newline at end of file diff --git a/tests/utf-8/utf-8.box.drawing.txt b/tests/utf-8/utf-8.box.drawing.txt new file mode 100644 index 00000000..184b60d9 --- /dev/null +++ b/tests/utf-8/utf-8.box.drawing.txt @@ -0,0 +1,256 @@ +U+2500 ─ e2 94 80 BOX DRAWINGS LIGHT HORIZONTAL +U+2501 ━ e2 94 81 BOX DRAWINGS HEAVY HORIZONTAL +U+2502 │ e2 94 82 BOX DRAWINGS LIGHT VERTICAL +U+2503 ┃ e2 94 83 BOX DRAWINGS HEAVY VERTICAL +U+2504 ┄ e2 94 84 BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL +U+2505 ┅ e2 94 85 BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL +U+2506 ┆ e2 94 86 BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL +U+2507 ┇ e2 94 87 BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL +U+2508 ┈ e2 94 88 BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL +U+2509 ┉ e2 94 89 BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL +U+250A ┊ e2 94 8a BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL +U+250B ┋ e2 94 8b BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL +U+250C ┌ e2 94 8c BOX DRAWINGS LIGHT DOWN AND RIGHT +U+250D ┍ e2 94 8d BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY +U+250E ┎ e2 94 8e BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT +U+250F ┏ e2 94 8f BOX DRAWINGS HEAVY DOWN AND RIGHT +U+2510 ┐ e2 94 90 BOX DRAWINGS LIGHT DOWN AND LEFT +U+2511 ┑ e2 94 91 BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY +U+2512 ┒ e2 94 92 BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT +U+2513 ┓ e2 94 93 BOX DRAWINGS HEAVY DOWN AND LEFT +U+2514 └ e2 94 94 BOX DRAWINGS LIGHT UP AND RIGHT +U+2515 ┕ e2 94 95 BOX DRAWINGS UP LIGHT AND RIGHT HEAVY +U+2516 ┖ e2 94 96 BOX DRAWINGS UP HEAVY AND RIGHT LIGHT +U+2517 ┗ e2 94 97 BOX DRAWINGS HEAVY UP AND RIGHT +U+2518 ┘ e2 94 98 BOX DRAWINGS LIGHT UP AND LEFT +U+2519 ┙ e2 94 99 BOX DRAWINGS UP LIGHT AND LEFT HEAVY +U+251A ┚ e2 94 9a BOX DRAWINGS UP HEAVY AND LEFT LIGHT +U+251B ┛ e2 94 9b BOX DRAWINGS HEAVY UP AND LEFT +U+251C ├ e2 94 9c BOX DRAWINGS LIGHT VERTICAL AND RIGHT +U+251D ┝ e2 94 9d BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY +U+251E ┞ e2 94 9e BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT +U+251F ┟ e2 94 9f BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT +U+2520 ┠ e2 94 a0 BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT +U+2521 ┡ e2 94 a1 BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY +U+2522 ┢ e2 94 a2 BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY +U+2523 ┣ e2 94 a3 BOX DRAWINGS HEAVY VERTICAL AND RIGHT +U+2524 ┤ e2 94 a4 BOX DRAWINGS LIGHT VERTICAL AND LEFT +U+2525 ┥ e2 94 a5 BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY +U+2526 ┦ e2 94 a6 BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT +U+2527 ┧ e2 94 a7 BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT +U+2528 ┨ e2 94 a8 BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT +U+2529 ┩ e2 94 a9 BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY +U+252A ┪ e2 94 aa BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY +U+252B ┫ e2 94 ab BOX DRAWINGS HEAVY VERTICAL AND LEFT +U+252C ┬ e2 94 ac BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +U+252D ┭ e2 94 ad BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT +U+252E ┮ e2 94 ae BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT +U+252F ┯ e2 94 af BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY +U+2530 ┰ e2 94 b0 BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT +U+2531 ┱ e2 94 b1 BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY +U+2532 ┲ e2 94 b2 BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY +U+2533 ┳ e2 94 b3 BOX DRAWINGS HEAVY DOWN AND HORIZONTAL +U+2534 ┴ e2 94 b4 BOX DRAWINGS LIGHT UP AND HORIZONTAL +U+2535 ┵ e2 94 b5 BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT +U+2536 ┶ e2 94 b6 BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT +U+2537 ┷ e2 94 b7 BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY +U+2538 ┸ e2 94 b8 BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT +U+2539 ┹ e2 94 b9 BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY +U+253A ┺ e2 94 ba BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY +U+253B ┻ e2 94 bb BOX DRAWINGS HEAVY UP AND HORIZONTAL +U+253C ┼ e2 94 bc BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +U+253D ┽ e2 94 bd BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT +U+253E ┾ e2 94 be BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT +U+253F ┿ e2 94 bf BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY +U+2540 ╀ e2 95 80 BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT +U+2541 ╁ e2 95 81 BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT +U+2542 ╂ e2 95 82 BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT +U+2543 ╃ e2 95 83 BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT +U+2544 ╄ e2 95 84 BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT +U+2545 ╅ e2 95 85 BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT +U+2546 ╆ e2 95 86 BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT +U+2547 ╇ e2 95 87 BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY +U+2548 ╈ e2 95 88 BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY +U+2549 ╉ e2 95 89 BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY +U+254A ╊ e2 95 8a BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY +U+254B ╋ e2 95 8b BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL +U+254C ╌ e2 95 8c BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL +U+254D ╍ e2 95 8d BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL +U+254E ╎ e2 95 8e BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL +U+254F ╏ e2 95 8f BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL +U+2550 ═ e2 95 90 BOX DRAWINGS DOUBLE HORIZONTAL +U+2551 ║ e2 95 91 BOX DRAWINGS DOUBLE VERTICAL +U+2552 ╒ e2 95 92 BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +U+2553 ╓ e2 95 93 BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +U+2554 ╔ e2 95 94 BOX DRAWINGS DOUBLE DOWN AND RIGHT +U+2555 ╕ e2 95 95 BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +U+2556 ╖ e2 95 96 BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +U+2557 ╗ e2 95 97 BOX DRAWINGS DOUBLE DOWN AND LEFT +U+2558 ╘ e2 95 98 BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +U+2559 ╙ e2 95 99 BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +U+255A ╚ e2 95 9a BOX DRAWINGS DOUBLE UP AND RIGHT +U+255B ╛ e2 95 9b BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +U+255C ╜ e2 95 9c BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +U+255D ╝ e2 95 9d BOX DRAWINGS DOUBLE UP AND LEFT +U+255E ╞ e2 95 9e BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +U+255F ╟ e2 95 9f BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +U+2560 ╠ e2 95 a0 BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +U+2561 ╡ e2 95 a1 BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +U+2562 ╢ e2 95 a2 BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +U+2563 ╣ e2 95 a3 BOX DRAWINGS DOUBLE VERTICAL AND LEFT +U+2564 ╤ e2 95 a4 BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +U+2565 ╥ e2 95 a5 BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +U+2566 ╦ e2 95 a6 BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +U+2567 ╧ e2 95 a7 BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +U+2568 ╨ e2 95 a8 BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +U+2569 ╩ e2 95 a9 BOX DRAWINGS DOUBLE UP AND HORIZONTAL +U+256A ╪ e2 95 aa BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +U+256B ╫ e2 95 ab BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +U+256C ╬ e2 95 ac BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +U+256D ╭ e2 95 ad BOX DRAWINGS LIGHT ARC DOWN AND RIGHT +U+256E ╮ e2 95 ae BOX DRAWINGS LIGHT ARC DOWN AND LEFT +U+256F ╯ e2 95 af BOX DRAWINGS LIGHT ARC UP AND LEFT +U+2570 ╰ e2 95 b0 BOX DRAWINGS LIGHT ARC UP AND RIGHT +U+2571 ╱ e2 95 b1 BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT +U+2572 ╲ e2 95 b2 BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT +U+2573 ╳ e2 95 b3 BOX DRAWINGS LIGHT DIAGONAL CROSS +U+2574 ╴ e2 95 b4 BOX DRAWINGS LIGHT LEFT +U+2575 ╵ e2 95 b5 BOX DRAWINGS LIGHT UP +U+2576 ╶ e2 95 b6 BOX DRAWINGS LIGHT RIGHT +U+2577 ╷ e2 95 b7 BOX DRAWINGS LIGHT DOWN +U+2578 ╸ e2 95 b8 BOX DRAWINGS HEAVY LEFT +U+2579 ╹ e2 95 b9 BOX DRAWINGS HEAVY UP +U+257A ╺ e2 95 ba BOX DRAWINGS HEAVY RIGHT +U+257B ╻ e2 95 bb BOX DRAWINGS HEAVY DOWN +U+257C ╼ e2 95 bc BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT +U+257D ╽ e2 95 bd BOX DRAWINGS LIGHT UP AND HEAVY DOWN +U+257E ╾ e2 95 be BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT +U+257F ╿ e2 95 bf BOX DRAWINGS HEAVY UP AND LIGHT DOWN +U+2580 ▀ e2 96 80 UPPER HALF BLOCK +U+2581 ▁ e2 96 81 LOWER ONE EIGHTH BLOCK +U+2582 ▂ e2 96 82 LOWER ONE QUARTER BLOCK +U+2583 ▃ e2 96 83 LOWER THREE EIGHTHS BLOCK +U+2584 ▄ e2 96 84 LOWER HALF BLOCK +U+2585 ▅ e2 96 85 LOWER FIVE EIGHTHS BLOCK +U+2586 ▆ e2 96 86 LOWER THREE QUARTERS BLOCK +U+2587 ▇ e2 96 87 LOWER SEVEN EIGHTHS BLOCK +U+2588 █ e2 96 88 FULL BLOCK +U+2589 ▉ e2 96 89 LEFT SEVEN EIGHTHS BLOCK +U+258A ▊ e2 96 8a LEFT THREE QUARTERS BLOCK +U+258B ▋ e2 96 8b LEFT FIVE EIGHTHS BLOCK +U+258C ▌ e2 96 8c LEFT HALF BLOCK +U+258D ▍ e2 96 8d LEFT THREE EIGHTHS BLOCK +U+258E ▎ e2 96 8e LEFT ONE QUARTER BLOCK +U+258F ▏ e2 96 8f LEFT ONE EIGHTH BLOCK +U+2590 ▐ e2 96 90 RIGHT HALF BLOCK +U+2591 ░ e2 96 91 LIGHT SHADE +U+2592 ▒ e2 96 92 MEDIUM SHADE +U+2593 ▓ e2 96 93 DARK SHADE +U+2594 ▔ e2 96 94 UPPER ONE EIGHTH BLOCK +U+2595 ▕ e2 96 95 RIGHT ONE EIGHTH BLOCK +U+2596 ▖ e2 96 96 QUADRANT LOWER LEFT +U+2597 ▗ e2 96 97 QUADRANT LOWER RIGHT +U+2598 ▘ e2 96 98 QUADRANT UPPER LEFT +U+2599 ▙ e2 96 99 QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT +U+259A ▚ e2 96 9a QUADRANT UPPER LEFT AND LOWER RIGHT +U+259B ▛ e2 96 9b QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT +U+259C ▜ e2 96 9c QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT +U+259D ▝ e2 96 9d QUADRANT UPPER RIGHT +U+259E ▞ e2 96 9e QUADRANT UPPER RIGHT AND LOWER LEFT +U+259F ▟ e2 96 9f QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT +U+25A0 ■ e2 96 a0 BLACK SQUARE +U+25A1 □ e2 96 a1 WHITE SQUARE +U+25A2 ▢ e2 96 a2 WHITE SQUARE WITH ROUNDED CORNERS +U+25A3 ▣ e2 96 a3 WHITE SQUARE CONTAINING BLACK SMALL SQUARE +U+25A4 ▤ e2 96 a4 SQUARE WITH HORIZONTAL FILL +U+25A5 ▥ e2 96 a5 SQUARE WITH VERTICAL FILL +U+25A6 ▦ e2 96 a6 SQUARE WITH ORTHOGONAL CROSSHATCH FILL +U+25A7 ▧ e2 96 a7 SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL +U+25A8 ▨ e2 96 a8 SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL +U+25A9 ▩ e2 96 a9 SQUARE WITH DIAGONAL CROSSHATCH FILL +U+25AA ▪ e2 96 aa BLACK SMALL SQUARE +U+25AB ▫ e2 96 ab WHITE SMALL SQUARE +U+25AC ▬ e2 96 ac BLACK RECTANGLE +U+25AD ▭ e2 96 ad WHITE RECTANGLE +U+25AE ▮ e2 96 ae BLACK VERTICAL RECTANGLE +U+25AF ▯ e2 96 af WHITE VERTICAL RECTANGLE +U+25B0 ▰ e2 96 b0 BLACK PARALLELOGRAM +U+25B1 ▱ e2 96 b1 WHITE PARALLELOGRAM +U+25B2 ▲ e2 96 b2 BLACK UP-POINTING TRIANGLE +U+25B3 △ e2 96 b3 WHITE UP-POINTING TRIANGLE +U+25B4 ▴ e2 96 b4 BLACK UP-POINTING SMALL TRIANGLE +U+25B5 ▵ e2 96 b5 WHITE UP-POINTING SMALL TRIANGLE +U+25B6 ▶ e2 96 b6 BLACK RIGHT-POINTING TRIANGLE +U+25B7 ▷ e2 96 b7 WHITE RIGHT-POINTING TRIANGLE +U+25B8 ▸ e2 96 b8 BLACK RIGHT-POINTING SMALL TRIANGLE +U+25B9 ▹ e2 96 b9 WHITE RIGHT-POINTING SMALL TRIANGLE +U+25BA ► e2 96 ba BLACK RIGHT-POINTING POINTER +U+25BB ▻ e2 96 bb WHITE RIGHT-POINTING POINTER +U+25BC ▼ e2 96 bc BLACK DOWN-POINTING TRIANGLE +U+25BD ▽ e2 96 bd WHITE DOWN-POINTING TRIANGLE +U+25BE ▾ e2 96 be BLACK DOWN-POINTING SMALL TRIANGLE +U+25BF ▿ e2 96 bf WHITE DOWN-POINTING SMALL TRIANGLE +U+25C0 ◀ e2 97 80 BLACK LEFT-POINTING TRIANGLE +U+25C1 ◁ e2 97 81 WHITE LEFT-POINTING TRIANGLE +U+25C2 ◂ e2 97 82 BLACK LEFT-POINTING SMALL TRIANGLE +U+25C3 ◃ e2 97 83 WHITE LEFT-POINTING SMALL TRIANGLE +U+25C4 ◄ e2 97 84 BLACK LEFT-POINTING POINTER +U+25C5 ◅ e2 97 85 WHITE LEFT-POINTING POINTER +U+25C6 ◆ e2 97 86 BLACK DIAMOND +U+25C7 ◇ e2 97 87 WHITE DIAMOND +U+25C8 ◈ e2 97 88 WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND +U+25C9 ◉ e2 97 89 FISHEYE +U+25CA ◊ e2 97 8a LOZENGE +U+25CB ○ e2 97 8b WHITE CIRCLE +U+25CC ◌ e2 97 8c DOTTED CIRCLE +U+25CD ◍ e2 97 8d CIRCLE WITH VERTICAL FILL +U+25CE ◎ e2 97 8e BULLSEYE +U+25CF ● e2 97 8f BLACK CIRCLE +U+25D0 ◐ e2 97 90 CIRCLE WITH LEFT HALF BLACK +U+25D1 ◑ e2 97 91 CIRCLE WITH RIGHT HALF BLACK +U+25D2 ◒ e2 97 92 CIRCLE WITH LOWER HALF BLACK +U+25D3 ◓ e2 97 93 CIRCLE WITH UPPER HALF BLACK +U+25D4 ◔ e2 97 94 CIRCLE WITH UPPER RIGHT QUADRANT BLACK +U+25D5 ◕ e2 97 95 CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK +U+25D6 ◖ e2 97 96 LEFT HALF BLACK CIRCLE +U+25D7 ◗ e2 97 97 RIGHT HALF BLACK CIRCLE +U+25D8 ◘ e2 97 98 INVERSE BULLET +U+25D9 ◙ e2 97 99 INVERSE WHITE CIRCLE +U+25DA ◚ e2 97 9a UPPER HALF INVERSE WHITE CIRCLE +U+25DB ◛ e2 97 9b LOWER HALF INVERSE WHITE CIRCLE +U+25DC ◜ e2 97 9c UPPER LEFT QUADRANT CIRCULAR ARC +U+25DD ◝ e2 97 9d UPPER RIGHT QUADRANT CIRCULAR ARC +U+25DE ◞ e2 97 9e LOWER RIGHT QUADRANT CIRCULAR ARC +U+25DF ◟ e2 97 9f LOWER LEFT QUADRANT CIRCULAR ARC +U+25E0 ◠ e2 97 a0 UPPER HALF CIRCLE +U+25E1 ◡ e2 97 a1 LOWER HALF CIRCLE +U+25E2 ◢ e2 97 a2 BLACK LOWER RIGHT TRIANGLE +U+25E3 ◣ e2 97 a3 BLACK LOWER LEFT TRIANGLE +U+25E4 ◤ e2 97 a4 BLACK UPPER LEFT TRIANGLE +U+25E5 ◥ e2 97 a5 BLACK UPPER RIGHT TRIANGLE +U+25E6 ◦ e2 97 a6 WHITE BULLET +U+25E7 ◧ e2 97 a7 SQUARE WITH LEFT HALF BLACK +U+25E8 ◨ e2 97 a8 SQUARE WITH RIGHT HALF BLACK +U+25E9 ◩ e2 97 a9 SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK +U+25EA ◪ e2 97 aa SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK +U+25EB ◫ e2 97 ab WHITE SQUARE WITH VERTICAL BISECTING LINE +U+25EC ◬ e2 97 ac WHITE UP-POINTING TRIANGLE WITH DOT +U+25ED ◭ e2 97 ad UP-POINTING TRIANGLE WITH LEFT HALF BLACK +U+25EE ◮ e2 97 ae UP-POINTING TRIANGLE WITH RIGHT HALF BLACK +U+25EF ◯ e2 97 af LARGE CIRCLE +U+25F0 ◰ e2 97 b0 WHITE SQUARE WITH UPPER LEFT QUADRANT +U+25F1 ◱ e2 97 b1 WHITE SQUARE WITH LOWER LEFT QUADRANT +U+25F2 ◲ e2 97 b2 WHITE SQUARE WITH LOWER RIGHT QUADRANT +U+25F3 ◳ e2 97 b3 WHITE SQUARE WITH UPPER RIGHT QUADRANT +U+25F4 ◴ e2 97 b4 WHITE CIRCLE WITH UPPER LEFT QUADRANT +U+25F5 ◵ e2 97 b5 WHITE CIRCLE WITH LOWER LEFT QUADRANT +U+25F6 ◶ e2 97 b6 WHITE CIRCLE WITH LOWER RIGHT QUADRANT +U+25F7 ◷ e2 97 b7 WHITE CIRCLE WITH UPPER RIGHT QUADRANT +U+25F8 ◸ e2 97 b8 UPPER LEFT TRIANGLE +U+25F9 ◹ e2 97 b9 UPPER RIGHT TRIANGLE +U+25FA ◺ e2 97 ba LOWER LEFT TRIANGLE +U+25FB ◻ e2 97 bb WHITE MEDIUM SQUARE +U+25FC ◼ e2 97 bc BLACK MEDIUM SQUARE +U+25FD ◽ e2 97 bd WHITE MEDIUM SMALL SQUARE +U+25FE ◾ e2 97 be BLACK MEDIUM SMALL SQUARE +U+25FF ◿ e2 97 bf LOWER RIGHT TRIANGLE \ No newline at end of file diff --git a/tests/utf-8/utf-8.emoticons.txt b/tests/utf-8/utf-8.emoticons.txt new file mode 100644 index 00000000..baac0906 --- /dev/null +++ b/tests/utf-8/utf-8.emoticons.txt @@ -0,0 +1,257 @@ + +U+1F600 😀 f0 9f 98 80 GRINNING FACE +U+1F601 😁 f0 9f 98 81 GRINNING FACE WITH SMILING EYES +U+1F602 😂 f0 9f 98 82 FACE WITH TEARS OF JOY +U+1F603 😃 f0 9f 98 83 SMILING FACE WITH OPEN MOUTH +U+1F604 😄 f0 9f 98 84 SMILING FACE WITH OPEN MOUTH AND SMILING EYES +U+1F605 😅 f0 9f 98 85 SMILING FACE WITH OPEN MOUTH AND COLD SWEAT +U+1F606 😆 f0 9f 98 86 SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES +U+1F607 😇 f0 9f 98 87 SMILING FACE WITH HALO +U+1F608 😈 f0 9f 98 88 SMILING FACE WITH HORNS +U+1F609 😉 f0 9f 98 89 WINKING FACE +U+1F60A 😊 f0 9f 98 8a SMILING FACE WITH SMILING EYES +U+1F60B 😋 f0 9f 98 8b FACE SAVOURING DELICIOUS FOOD +U+1F60C 😌 f0 9f 98 8c RELIEVED FACE +U+1F60D 😍 f0 9f 98 8d SMILING FACE WITH HEART-SHAPED EYES +U+1F60E 😎 f0 9f 98 8e SMILING FACE WITH SUNGLASSES +U+1F60F 😏 f0 9f 98 8f SMIRKING FACE +U+1F610 😐 f0 9f 98 90 NEUTRAL FACE +U+1F611 😑 f0 9f 98 91 EXPRESSIONLESS FACE +U+1F612 😒 f0 9f 98 92 UNAMUSED FACE +U+1F613 😓 f0 9f 98 93 FACE WITH COLD SWEAT +U+1F614 😔 f0 9f 98 94 PENSIVE FACE +U+1F615 😕 f0 9f 98 95 CONFUSED FACE +U+1F616 😖 f0 9f 98 96 CONFOUNDED FACE +U+1F617 😗 f0 9f 98 97 KISSING FACE +U+1F618 😘 f0 9f 98 98 FACE THROWING A KISS +U+1F619 😙 f0 9f 98 99 KISSING FACE WITH SMILING EYES +U+1F61A 😚 f0 9f 98 9a KISSING FACE WITH CLOSED EYES +U+1F61B 😛 f0 9f 98 9b FACE WITH STUCK-OUT TONGUE +U+1F61C 😜 f0 9f 98 9c FACE WITH STUCK-OUT TONGUE AND WINKING EYE +U+1F61D 😝 f0 9f 98 9d FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES +U+1F61E 😞 f0 9f 98 9e DISAPPOINTED FACE +U+1F61F 😟 f0 9f 98 9f WORRIED FACE +U+1F620 😠 f0 9f 98 a0 ANGRY FACE +U+1F621 😡 f0 9f 98 a1 POUTING FACE +U+1F622 😢 f0 9f 98 a2 CRYING FACE +U+1F623 😣 f0 9f 98 a3 PERSEVERING FACE +U+1F624 😤 f0 9f 98 a4 FACE WITH LOOK OF TRIUMPH +U+1F625 😥 f0 9f 98 a5 DISAPPOINTED BUT RELIEVED FACE +U+1F626 😦 f0 9f 98 a6 FROWNING FACE WITH OPEN MOUTH +U+1F627 😧 f0 9f 98 a7 ANGUISHED FACE +U+1F628 😨 f0 9f 98 a8 FEARFUL FACE +U+1F629 😩 f0 9f 98 a9 WEARY FACE +U+1F62A 😪 f0 9f 98 aa SLEEPY FACE +U+1F62B 😫 f0 9f 98 ab TIRED FACE +U+1F62C 😬 f0 9f 98 ac GRIMACING FACE +U+1F62D 😭 f0 9f 98 ad LOUDLY CRYING FACE +U+1F62E 😮 f0 9f 98 ae FACE WITH OPEN MOUTH +U+1F62F 😯 f0 9f 98 af HUSHED FACE +U+1F630 😰 f0 9f 98 b0 FACE WITH OPEN MOUTH AND COLD SWEAT +U+1F631 😱 f0 9f 98 b1 FACE SCREAMING IN FEAR +U+1F632 😲 f0 9f 98 b2 ASTONISHED FACE +U+1F633 😳 f0 9f 98 b3 FLUSHED FACE +U+1F634 😴 f0 9f 98 b4 SLEEPING FACE +U+1F635 😵 f0 9f 98 b5 DIZZY FACE +U+1F636 😶 f0 9f 98 b6 FACE WITHOUT MOUTH +U+1F637 😷 f0 9f 98 b7 FACE WITH MEDICAL MASK +U+1F638 😸 f0 9f 98 b8 GRINNING CAT FACE WITH SMILING EYES +U+1F639 😹 f0 9f 98 b9 CAT FACE WITH TEARS OF JOY +U+1F63A 😺 f0 9f 98 ba SMILING CAT FACE WITH OPEN MOUTH +U+1F63B 😻 f0 9f 98 bb SMILING CAT FACE WITH HEART-SHAPED EYES +U+1F63C 😼 f0 9f 98 bc CAT FACE WITH WRY SMILE +U+1F63D 😽 f0 9f 98 bd KISSING CAT FACE WITH CLOSED EYES +U+1F63E 😾 f0 9f 98 be POUTING CAT FACE +U+1F63F 😿 f0 9f 98 bf CRYING CAT FACE +U+1F640 🙀 f0 9f 99 80 WEARY CAT FACE +U+1F641 🙁 f0 9f 99 81 SLIGHTLY FROWNING FACE +U+1F642 🙂 f0 9f 99 82 SLIGHTLY SMILING FACE +U+1F643 🙃 f0 9f 99 83 UPSIDE-DOWN FACE +U+1F644 🙄 f0 9f 99 84 FACE WITH ROLLING EYES +U+1F645 🙅 f0 9f 99 85 FACE WITH NO GOOD GESTURE +U+1F646 🙆 f0 9f 99 86 FACE WITH OK GESTURE +U+1F647 🙇 f0 9f 99 87 PERSON BOWING DEEPLY +U+1F648 🙈 f0 9f 99 88 SEE-NO-EVIL MONKEY +U+1F649 🙉 f0 9f 99 89 HEAR-NO-EVIL MONKEY +U+1F64A 🙊 f0 9f 99 8a SPEAK-NO-EVIL MONKEY +U+1F64B 🙋 f0 9f 99 8b HAPPY PERSON RAISING ONE HAND +U+1F64C 🙌 f0 9f 99 8c PERSON RAISING BOTH HANDS IN CELEBRATION +U+1F64D 🙍 f0 9f 99 8d PERSON FROWNING +U+1F64E 🙎 f0 9f 99 8e PERSON WITH POUTING FACE +U+1F64F 🙏 f0 9f 99 8f PERSON WITH FOLDED HANDS +U+1F650 🙐 f0 9f 99 90 NORTH WEST POINTING LEAF +U+1F651 🙑 f0 9f 99 91 SOUTH WEST POINTING LEAF +U+1F652 🙒 f0 9f 99 92 NORTH EAST POINTING LEAF +U+1F653 🙓 f0 9f 99 93 SOUTH EAST POINTING LEAF +U+1F654 🙔 f0 9f 99 94 TURNED NORTH WEST POINTING LEAF +U+1F655 🙕 f0 9f 99 95 TURNED SOUTH WEST POINTING LEAF +U+1F656 🙖 f0 9f 99 96 TURNED NORTH EAST POINTING LEAF +U+1F657 🙗 f0 9f 99 97 TURNED SOUTH EAST POINTING LEAF +U+1F658 🙘 f0 9f 99 98 NORTH WEST POINTING VINE LEAF +U+1F659 🙙 f0 9f 99 99 SOUTH WEST POINTING VINE LEAF +U+1F65A 🙚 f0 9f 99 9a NORTH EAST POINTING VINE LEAF +U+1F65B 🙛 f0 9f 99 9b SOUTH EAST POINTING VINE LEAF +U+1F65C 🙜 f0 9f 99 9c HEAVY NORTH WEST POINTING VINE LEAF +U+1F65D 🙝 f0 9f 99 9d HEAVY SOUTH WEST POINTING VINE LEAF +U+1F65E 🙞 f0 9f 99 9e HEAVY NORTH EAST POINTING VINE LEAF +U+1F65F 🙟 f0 9f 99 9f HEAVY SOUTH EAST POINTING VINE LEAF +U+1F660 🙠 f0 9f 99 a0 NORTH WEST POINTING BUD +U+1F661 🙡 f0 9f 99 a1 SOUTH WEST POINTING BUD +U+1F662 🙢 f0 9f 99 a2 NORTH EAST POINTING BUD +U+1F663 🙣 f0 9f 99 a3 SOUTH EAST POINTING BUD +U+1F664 🙤 f0 9f 99 a4 HEAVY NORTH WEST POINTING BUD +U+1F665 🙥 f0 9f 99 a5 HEAVY SOUTH WEST POINTING BUD +U+1F666 🙦 f0 9f 99 a6 HEAVY NORTH EAST POINTING BUD +U+1F667 🙧 f0 9f 99 a7 HEAVY SOUTH EAST POINTING BUD +U+1F668 🙨 f0 9f 99 a8 HOLLOW QUILT SQUARE ORNAMENT +U+1F669 🙩 f0 9f 99 a9 HOLLOW QUILT SQUARE ORNAMENT IN BLACK SQUARE +U+1F66A 🙪 f0 9f 99 aa SOLID QUILT SQUARE ORNAMENT +U+1F66B 🙫 f0 9f 99 ab SOLID QUILT SQUARE ORNAMENT IN BLACK SQUARE +U+1F66C 🙬 f0 9f 99 ac LEFTWARDS ROCKET +U+1F66D 🙭 f0 9f 99 ad UPWARDS ROCKET +U+1F66E 🙮 f0 9f 99 ae RIGHTWARDS ROCKET +U+1F66F 🙯 f0 9f 99 af DOWNWARDS ROCKET +U+1F670 🙰 f0 9f 99 b0 SCRIPT LIGATURE ET ORNAMENT +U+1F671 🙱 f0 9f 99 b1 HEAVY SCRIPT LIGATURE ET ORNAMENT +U+1F672 🙲 f0 9f 99 b2 LIGATURE OPEN ET ORNAMENT +U+1F673 🙳 f0 9f 99 b3 HEAVY LIGATURE OPEN ET ORNAMENT +U+1F674 🙴 f0 9f 99 b4 HEAVY AMPERSAND ORNAMENT +U+1F675 🙵 f0 9f 99 b5 SWASH AMPERSAND ORNAMENT +U+1F676 🙶 f0 9f 99 b6 SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT +U+1F677 🙷 f0 9f 99 b7 SANS-SERIF HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT +U+1F678 🙸 f0 9f 99 b8 SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT +U+1F679 🙹 f0 9f 99 b9 HEAVY INTERROBANG ORNAMENT +U+1F67A 🙺 f0 9f 99 ba SANS-SERIF INTERROBANG ORNAMENT +U+1F67B 🙻 f0 9f 99 bb HEAVY SANS-SERIF INTERROBANG ORNAMENT +U+1F67C 🙼 f0 9f 99 bc VERY HEAVY SOLIDUS +U+1F67D 🙽 f0 9f 99 bd VERY HEAVY REVERSE SOLIDUS +U+1F67E 🙾 f0 9f 99 be CHECKER BOARD +U+1F67F 🙿 f0 9f 99 bf REVERSE CHECKER BOARD +U+1F680 🚀 f0 9f 9a 80 ROCKET +U+1F681 🚁 f0 9f 9a 81 HELICOPTER +U+1F682 🚂 f0 9f 9a 82 STEAM LOCOMOTIVE +U+1F683 🚃 f0 9f 9a 83 RAILWAY CAR +U+1F684 🚄 f0 9f 9a 84 HIGH-SPEED TRAIN +U+1F685 🚅 f0 9f 9a 85 HIGH-SPEED TRAIN WITH BULLET NOSE +U+1F686 🚆 f0 9f 9a 86 TRAIN +U+1F687 🚇 f0 9f 9a 87 METRO +U+1F688 🚈 f0 9f 9a 88 LIGHT RAIL +U+1F689 🚉 f0 9f 9a 89 STATION +U+1F68A 🚊 f0 9f 9a 8a TRAM +U+1F68B 🚋 f0 9f 9a 8b TRAM CAR +U+1F68C 🚌 f0 9f 9a 8c BUS +U+1F68D 🚍 f0 9f 9a 8d ONCOMING BUS +U+1F68E 🚎 f0 9f 9a 8e TROLLEYBUS +U+1F68F 🚏 f0 9f 9a 8f BUS STOP +U+1F690 🚐 f0 9f 9a 90 MINIBUS +U+1F691 🚑 f0 9f 9a 91 AMBULANCE +U+1F692 🚒 f0 9f 9a 92 FIRE ENGINE +U+1F693 🚓 f0 9f 9a 93 POLICE CAR +U+1F694 🚔 f0 9f 9a 94 ONCOMING POLICE CAR +U+1F695 🚕 f0 9f 9a 95 TAXI +U+1F696 🚖 f0 9f 9a 96 ONCOMING TAXI +U+1F697 🚗 f0 9f 9a 97 AUTOMOBILE +U+1F698 🚘 f0 9f 9a 98 ONCOMING AUTOMOBILE +U+1F699 🚙 f0 9f 9a 99 RECREATIONAL VEHICLE +U+1F69A 🚚 f0 9f 9a 9a DELIVERY TRUCK +U+1F69B 🚛 f0 9f 9a 9b ARTICULATED LORRY +U+1F69C 🚜 f0 9f 9a 9c TRACTOR +U+1F69D 🚝 f0 9f 9a 9d MONORAIL +U+1F69E 🚞 f0 9f 9a 9e MOUNTAIN RAILWAY +U+1F69F 🚟 f0 9f 9a 9f SUSPENSION RAILWAY +U+1F6A0 🚠 f0 9f 9a a0 MOUNTAIN CABLEWAY +U+1F6A1 🚡 f0 9f 9a a1 AERIAL TRAMWAY +U+1F6A2 🚢 f0 9f 9a a2 SHIP +U+1F6A3 🚣 f0 9f 9a a3 ROWBOAT +U+1F6A4 🚤 f0 9f 9a a4 SPEEDBOAT +U+1F6A5 🚥 f0 9f 9a a5 HORIZONTAL TRAFFIC LIGHT +U+1F6A6 🚦 f0 9f 9a a6 VERTICAL TRAFFIC LIGHT +U+1F6A7 🚧 f0 9f 9a a7 CONSTRUCTION SIGN +U+1F6A8 🚨 f0 9f 9a a8 POLICE CARS REVOLVING LIGHT +U+1F6A9 🚩 f0 9f 9a a9 TRIANGULAR FLAG ON POST +U+1F6AA 🚪 f0 9f 9a aa DOOR +U+1F6AB 🚫 f0 9f 9a ab NO ENTRY SIGN +U+1F6AC 🚬 f0 9f 9a ac SMOKING SYMBOL +U+1F6AD 🚭 f0 9f 9a ad NO SMOKING SYMBOL +U+1F6AE 🚮 f0 9f 9a ae PUT LITTER IN ITS PLACE SYMBOL +U+1F6AF 🚯 f0 9f 9a af DO NOT LITTER SYMBOL +U+1F6B0 🚰 f0 9f 9a b0 POTABLE WATER SYMBOL +U+1F6B1 🚱 f0 9f 9a b1 NON-POTABLE WATER SYMBOL +U+1F6B2 🚲 f0 9f 9a b2 BICYCLE +U+1F6B3 🚳 f0 9f 9a b3 NO BICYCLES +U+1F6B4 🚴 f0 9f 9a b4 BICYCLIST +U+1F6B5 🚵 f0 9f 9a b5 MOUNTAIN BICYCLIST +U+1F6B6 🚶 f0 9f 9a b6 PEDESTRIAN +U+1F6B7 🚷 f0 9f 9a b7 NO PEDESTRIANS +U+1F6B8 🚸 f0 9f 9a b8 CHILDREN CROSSING +U+1F6B9 🚹 f0 9f 9a b9 MENS SYMBOL +U+1F6BA 🚺 f0 9f 9a ba WOMENS SYMBOL +U+1F6BB 🚻 f0 9f 9a bb RESTROOM +U+1F6BC 🚼 f0 9f 9a bc BABY SYMBOL +U+1F6BD 🚽 f0 9f 9a bd TOILET +U+1F6BE 🚾 f0 9f 9a be WATER CLOSET +U+1F6BF 🚿 f0 9f 9a bf SHOWER +U+1F6C0 🛀 f0 9f 9b 80 BATH +U+1F6C1 🛁 f0 9f 9b 81 BATHTUB +U+1F6C2 🛂 f0 9f 9b 82 PASSPORT CONTROL +U+1F6C3 🛃 f0 9f 9b 83 CUSTOMS +U+1F6C4 🛄 f0 9f 9b 84 BAGGAGE CLAIM +U+1F6C5 🛅 f0 9f 9b 85 LEFT LUGGAGE +U+1F6C6 🛆 f0 9f 9b 86 TRIANGLE WITH ROUNDED CORNERS +U+1F6C7 🛇 f0 9f 9b 87 PROHIBITED SIGN +U+1F6C8 🛈 f0 9f 9b 88 CIRCLED INFORMATION SOURCE +U+1F6C9 🛉 f0 9f 9b 89 BOYS SYMBOL +U+1F6CA 🛊 f0 9f 9b 8a GIRLS SYMBOL +U+1F6CB 🛋 f0 9f 9b 8b COUCH AND LAMP +U+1F6CC 🛌 f0 9f 9b 8c SLEEPING ACCOMMODATION +U+1F6CD 🛍 f0 9f 9b 8d SHOPPING BAGS +U+1F6CE 🛎 f0 9f 9b 8e BELLHOP BELL +U+1F6CF 🛏 f0 9f 9b 8f BED +U+1F6D0 🛐 f0 9f 9b 90 PLACE OF WORSHIP +U+1F6D1 🛑 f0 9f 9b 91 OCTAGONAL SIGN +U+1F6D2 🛒 f0 9f 9b 92 SHOPPING TROLLEY +U+1F6D3 🛓 f0 9f 9b 93 STUPA +U+1F6D4 🛔 f0 9f 9b 94 PAGODA +U+1F6D5 🛕 f0 9f 9b 95 HINDU TEMPLE +U+1F6D6 🛖 f0 9f 9b 96 HUT +U+1F6D7 🛗 f0 9f 9b 97 ELEVATOR +U+1F6D8 🛘 f0 9f 9b 98 +U+1F6D9 🛙 f0 9f 9b 99 +U+1F6DA 🛚 f0 9f 9b 9a +U+1F6DB 🛛 f0 9f 9b 9b +U+1F6DC 🛜 f0 9f 9b 9c +U+1F6DD 🛝 f0 9f 9b 9d +U+1F6DE 🛞 f0 9f 9b 9e +U+1F6DF 🛟 f0 9f 9b 9f +U+1F6E0 🛠 f0 9f 9b a0 HAMMER AND WRENCH +U+1F6E1 🛡 f0 9f 9b a1 SHIELD +U+1F6E2 🛢 f0 9f 9b a2 OIL DRUM +U+1F6E3 🛣 f0 9f 9b a3 MOTORWAY +U+1F6E4 🛤 f0 9f 9b a4 RAILWAY TRACK +U+1F6E5 🛥 f0 9f 9b a5 MOTOR BOAT +U+1F6E6 🛦 f0 9f 9b a6 UP-POINTING MILITARY AIRPLANE +U+1F6E7 🛧 f0 9f 9b a7 UP-POINTING AIRPLANE +U+1F6E8 🛨 f0 9f 9b a8 UP-POINTING SMALL AIRPLANE +U+1F6E9 🛩 f0 9f 9b a9 SMALL AIRPLANE +U+1F6EA 🛪 f0 9f 9b aa NORTHEAST-POINTING AIRPLANE +U+1F6EB 🛫 f0 9f 9b ab AIRPLANE DEPARTURE +U+1F6EC 🛬 f0 9f 9b ac AIRPLANE ARRIVING +U+1F6ED 🛭 f0 9f 9b ad +U+1F6EE 🛮 f0 9f 9b ae +U+1F6EF 🛯 f0 9f 9b af +U+1F6F0 🛰 f0 9f 9b b0 SATELLITE +U+1F6F1 🛱 f0 9f 9b b1 ONCOMING FIRE ENGINE +U+1F6F2 🛲 f0 9f 9b b2 DIESEL LOCOMOTIVE +U+1F6F3 🛳 f0 9f 9b b3 PASSENGER SHIP +U+1F6F4 🛴 f0 9f 9b b4 SCOOTER +U+1F6F5 🛵 f0 9f 9b b5 MOTOR SCOOTER +U+1F6F6 🛶 f0 9f 9b b6 CANOE +U+1F6F7 🛷 f0 9f 9b b7 SLED +U+1F6F8 🛸 f0 9f 9b b8 FLYING SAUCER +U+1F6F9 🛹 f0 9f 9b b9 SKATEBOARD +U+1F6FA 🛺 f0 9f 9b ba AUTO RICKSHAW +U+1F6FB 🛻 f0 9f 9b bb PICKUP TRUCK +U+1F6FC 🛼 f0 9f 9b bc ROLLER SKATE +U+1F6FD 🛽 f0 9f 9b bd +U+1F6FE 🛾 f0 9f 9b be +U+1F6FF 🛿 f0 9f 9b bf \ No newline at end of file diff --git a/tests/utf-8/utf-8.misc.symbols.pictographs.txt b/tests/utf-8/utf-8.misc.symbols.pictographs.txt new file mode 100644 index 00000000..2c799ec1 --- /dev/null +++ b/tests/utf-8/utf-8.misc.symbols.pictographs.txt @@ -0,0 +1,256 @@ +U+1F300 🌀 f0 9f 8c 80 CYCLONE +U+1F301 🌁 f0 9f 8c 81 FOGGY +U+1F302 🌂 f0 9f 8c 82 CLOSED UMBRELLA +U+1F303 🌃 f0 9f 8c 83 NIGHT WITH STARS +U+1F304 🌄 f0 9f 8c 84 SUNRISE OVER MOUNTAINS +U+1F305 🌅 f0 9f 8c 85 SUNRISE +U+1F306 🌆 f0 9f 8c 86 CITYSCAPE AT DUSK +U+1F307 🌇 f0 9f 8c 87 SUNSET OVER BUILDINGS +U+1F308 🌈 f0 9f 8c 88 RAINBOW +U+1F309 🌉 f0 9f 8c 89 BRIDGE AT NIGHT +U+1F30A 🌊 f0 9f 8c 8a WATER WAVE +U+1F30B 🌋 f0 9f 8c 8b VOLCANO +U+1F30C 🌌 f0 9f 8c 8c MILKY WAY +U+1F30D 🌍 f0 9f 8c 8d EARTH GLOBE EUROPE-AFRICA +U+1F30E 🌎 f0 9f 8c 8e EARTH GLOBE AMERICAS +U+1F30F 🌏 f0 9f 8c 8f EARTH GLOBE ASIA-AUSTRALIA +U+1F310 🌐 f0 9f 8c 90 GLOBE WITH MERIDIANS +U+1F311 🌑 f0 9f 8c 91 NEW MOON SYMBOL +U+1F312 🌒 f0 9f 8c 92 WAXING CRESCENT MOON SYMBOL +U+1F313 🌓 f0 9f 8c 93 FIRST QUARTER MOON SYMBOL +U+1F314 🌔 f0 9f 8c 94 WAXING GIBBOUS MOON SYMBOL +U+1F315 🌕 f0 9f 8c 95 FULL MOON SYMBOL +U+1F316 🌖 f0 9f 8c 96 WANING GIBBOUS MOON SYMBOL +U+1F317 🌗 f0 9f 8c 97 LAST QUARTER MOON SYMBOL +U+1F318 🌘 f0 9f 8c 98 WANING CRESCENT MOON SYMBOL +U+1F319 🌙 f0 9f 8c 99 CRESCENT MOON +U+1F31A 🌚 f0 9f 8c 9a NEW MOON WITH FACE +U+1F31B 🌛 f0 9f 8c 9b FIRST QUARTER MOON WITH FACE +U+1F31C 🌜 f0 9f 8c 9c LAST QUARTER MOON WITH FACE +U+1F31D 🌝 f0 9f 8c 9d FULL MOON WITH FACE +U+1F31E 🌞 f0 9f 8c 9e SUN WITH FACE +U+1F31F 🌟 f0 9f 8c 9f GLOWING STAR +U+1F320 🌠 f0 9f 8c a0 SHOOTING STAR +U+1F321 🌡 f0 9f 8c a1 THERMOMETER +U+1F322 🌢 f0 9f 8c a2 BLACK DROPLET +U+1F323 🌣 f0 9f 8c a3 WHITE SUN +U+1F324 🌤 f0 9f 8c a4 WHITE SUN WITH SMALL CLOUD +U+1F325 🌥 f0 9f 8c a5 WHITE SUN BEHIND CLOUD +U+1F326 🌦 f0 9f 8c a6 WHITE SUN BEHIND CLOUD WITH RAIN +U+1F327 🌧 f0 9f 8c a7 CLOUD WITH RAIN +U+1F328 🌨 f0 9f 8c a8 CLOUD WITH SNOW +U+1F329 🌩 f0 9f 8c a9 CLOUD WITH LIGHTNING +U+1F32A 🌪 f0 9f 8c aa CLOUD WITH TORNADO +U+1F32B 🌫 f0 9f 8c ab FOG +U+1F32C 🌬 f0 9f 8c ac WIND BLOWING FACE +U+1F32D 🌭 f0 9f 8c ad HOT DOG +U+1F32E 🌮 f0 9f 8c ae TACO +U+1F32F 🌯 f0 9f 8c af BURRITO +U+1F330 🌰 f0 9f 8c b0 CHESTNUT +U+1F331 🌱 f0 9f 8c b1 SEEDLING +U+1F332 🌲 f0 9f 8c b2 EVERGREEN TREE +U+1F333 🌳 f0 9f 8c b3 DECIDUOUS TREE +U+1F334 🌴 f0 9f 8c b4 PALM TREE +U+1F335 🌵 f0 9f 8c b5 CACTUS +U+1F336 🌶 f0 9f 8c b6 HOT PEPPER +U+1F337 🌷 f0 9f 8c b7 TULIP +U+1F338 🌸 f0 9f 8c b8 CHERRY BLOSSOM +U+1F339 🌹 f0 9f 8c b9 ROSE +U+1F33A 🌺 f0 9f 8c ba HIBISCUS +U+1F33B 🌻 f0 9f 8c bb SUNFLOWER +U+1F33C 🌼 f0 9f 8c bc BLOSSOM +U+1F33D 🌽 f0 9f 8c bd EAR OF MAIZE +U+1F33E 🌾 f0 9f 8c be EAR OF RICE +U+1F33F 🌿 f0 9f 8c bf HERB +U+1F340 🍀 f0 9f 8d 80 FOUR LEAF CLOVER +U+1F341 🍁 f0 9f 8d 81 MAPLE LEAF +U+1F342 🍂 f0 9f 8d 82 FALLEN LEAF +U+1F343 🍃 f0 9f 8d 83 LEAF FLUTTERING IN WIND +U+1F344 🍄 f0 9f 8d 84 MUSHROOM +U+1F345 🍅 f0 9f 8d 85 TOMATO +U+1F346 🍆 f0 9f 8d 86 AUBERGINE +U+1F347 🍇 f0 9f 8d 87 GRAPES +U+1F348 🍈 f0 9f 8d 88 MELON +U+1F349 🍉 f0 9f 8d 89 WATERMELON +U+1F34A 🍊 f0 9f 8d 8a TANGERINE +U+1F34B 🍋 f0 9f 8d 8b LEMON +U+1F34C 🍌 f0 9f 8d 8c BANANA +U+1F34D 🍍 f0 9f 8d 8d PINEAPPLE +U+1F34E 🍎 f0 9f 8d 8e RED APPLE +U+1F34F 🍏 f0 9f 8d 8f GREEN APPLE +U+1F350 🍐 f0 9f 8d 90 PEAR +U+1F351 🍑 f0 9f 8d 91 PEACH +U+1F352 🍒 f0 9f 8d 92 CHERRIES +U+1F353 🍓 f0 9f 8d 93 STRAWBERRY +U+1F354 🍔 f0 9f 8d 94 HAMBURGER +U+1F355 🍕 f0 9f 8d 95 SLICE OF PIZZA +U+1F356 🍖 f0 9f 8d 96 MEAT ON BONE +U+1F357 🍗 f0 9f 8d 97 POULTRY LEG +U+1F358 🍘 f0 9f 8d 98 RICE CRACKER +U+1F359 🍙 f0 9f 8d 99 RICE BALL +U+1F35A 🍚 f0 9f 8d 9a COOKED RICE +U+1F35B 🍛 f0 9f 8d 9b CURRY AND RICE +U+1F35C 🍜 f0 9f 8d 9c STEAMING BOWL +U+1F35D 🍝 f0 9f 8d 9d SPAGHETTI +U+1F35E 🍞 f0 9f 8d 9e BREAD +U+1F35F 🍟 f0 9f 8d 9f FRENCH FRIES +U+1F360 🍠 f0 9f 8d a0 ROASTED SWEET POTATO +U+1F361 🍡 f0 9f 8d a1 DANGO +U+1F362 🍢 f0 9f 8d a2 ODEN +U+1F363 🍣 f0 9f 8d a3 SUSHI +U+1F364 🍤 f0 9f 8d a4 FRIED SHRIMP +U+1F365 🍥 f0 9f 8d a5 FISH CAKE WITH SWIRL DESIGN +U+1F366 🍦 f0 9f 8d a6 SOFT ICE CREAM +U+1F367 🍧 f0 9f 8d a7 SHAVED ICE +U+1F368 🍨 f0 9f 8d a8 ICE CREAM +U+1F369 🍩 f0 9f 8d a9 DOUGHNUT +U+1F36A 🍪 f0 9f 8d aa COOKIE +U+1F36B 🍫 f0 9f 8d ab CHOCOLATE BAR +U+1F36C 🍬 f0 9f 8d ac CANDY +U+1F36D 🍭 f0 9f 8d ad LOLLIPOP +U+1F36E 🍮 f0 9f 8d ae CUSTARD +U+1F36F 🍯 f0 9f 8d af HONEY POT +U+1F370 🍰 f0 9f 8d b0 SHORTCAKE +U+1F371 🍱 f0 9f 8d b1 BENTO BOX +U+1F372 🍲 f0 9f 8d b2 POT OF FOOD +U+1F373 🍳 f0 9f 8d b3 COOKING +U+1F374 🍴 f0 9f 8d b4 FORK AND KNIFE +U+1F375 🍵 f0 9f 8d b5 TEACUP WITHOUT HANDLE +U+1F376 🍶 f0 9f 8d b6 SAKE BOTTLE AND CUP +U+1F377 🍷 f0 9f 8d b7 WINE GLASS +U+1F378 🍸 f0 9f 8d b8 COCKTAIL GLASS +U+1F379 🍹 f0 9f 8d b9 TROPICAL DRINK +U+1F37A 🍺 f0 9f 8d ba BEER MUG +U+1F37B 🍻 f0 9f 8d bb CLINKING BEER MUGS +U+1F37C 🍼 f0 9f 8d bc BABY BOTTLE +U+1F37D 🍽 f0 9f 8d bd FORK AND KNIFE WITH PLATE +U+1F37E 🍾 f0 9f 8d be BOTTLE WITH POPPING CORK +U+1F37F 🍿 f0 9f 8d bf POPCORN +U+1F380 🎀 f0 9f 8e 80 RIBBON +U+1F381 🎁 f0 9f 8e 81 WRAPPED PRESENT +U+1F382 🎂 f0 9f 8e 82 BIRTHDAY CAKE +U+1F383 🎃 f0 9f 8e 83 JACK-O-LANTERN +U+1F384 🎄 f0 9f 8e 84 CHRISTMAS TREE +U+1F385 🎅 f0 9f 8e 85 FATHER CHRISTMAS +U+1F386 🎆 f0 9f 8e 86 FIREWORKS +U+1F387 🎇 f0 9f 8e 87 FIREWORK SPARKLER +U+1F388 🎈 f0 9f 8e 88 BALLOON +U+1F389 🎉 f0 9f 8e 89 PARTY POPPER +U+1F38A 🎊 f0 9f 8e 8a CONFETTI BALL +U+1F38B 🎋 f0 9f 8e 8b TANABATA TREE +U+1F38C 🎌 f0 9f 8e 8c CROSSED FLAGS +U+1F38D 🎍 f0 9f 8e 8d PINE DECORATION +U+1F38E 🎎 f0 9f 8e 8e JAPANESE DOLLS +U+1F38F 🎏 f0 9f 8e 8f CARP STREAMER +U+1F390 🎐 f0 9f 8e 90 WIND CHIME +U+1F391 🎑 f0 9f 8e 91 MOON VIEWING CEREMONY +U+1F392 🎒 f0 9f 8e 92 SCHOOL SATCHEL +U+1F393 🎓 f0 9f 8e 93 GRADUATION CAP +U+1F394 🎔 f0 9f 8e 94 HEART WITH TIP ON THE LEFT +U+1F395 🎕 f0 9f 8e 95 BOUQUET OF FLOWERS +U+1F396 🎖 f0 9f 8e 96 MILITARY MEDAL +U+1F397 🎗 f0 9f 8e 97 REMINDER RIBBON +U+1F398 🎘 f0 9f 8e 98 MUSICAL KEYBOARD WITH JACKS +U+1F399 🎙 f0 9f 8e 99 STUDIO MICROPHONE +U+1F39A 🎚 f0 9f 8e 9a LEVEL SLIDER +U+1F39B 🎛 f0 9f 8e 9b CONTROL KNOBS +U+1F39C 🎜 f0 9f 8e 9c BEAMED ASCENDING MUSICAL NOTES +U+1F39D 🎝 f0 9f 8e 9d BEAMED DESCENDING MUSICAL NOTES +U+1F39E 🎞 f0 9f 8e 9e FILM FRAMES +U+1F39F 🎟 f0 9f 8e 9f ADMISSION TICKETS +U+1F3A0 🎠 f0 9f 8e a0 CAROUSEL HORSE +U+1F3A1 🎡 f0 9f 8e a1 FERRIS WHEEL +U+1F3A2 🎢 f0 9f 8e a2 ROLLER COASTER +U+1F3A3 🎣 f0 9f 8e a3 FISHING POLE AND FISH +U+1F3A4 🎤 f0 9f 8e a4 MICROPHONE +U+1F3A5 🎥 f0 9f 8e a5 MOVIE CAMERA +U+1F3A6 🎦 f0 9f 8e a6 CINEMA +U+1F3A7 🎧 f0 9f 8e a7 HEADPHONE +U+1F3A8 🎨 f0 9f 8e a8 ARTIST PALETTE +U+1F3A9 🎩 f0 9f 8e a9 TOP HAT +U+1F3AA 🎪 f0 9f 8e aa CIRCUS TENT +U+1F3AB 🎫 f0 9f 8e ab TICKET +U+1F3AC 🎬 f0 9f 8e ac CLAPPER BOARD +U+1F3AD 🎭 f0 9f 8e ad PERFORMING ARTS +U+1F3AE 🎮 f0 9f 8e ae VIDEO GAME +U+1F3AF 🎯 f0 9f 8e af DIRECT HIT +U+1F3B0 🎰 f0 9f 8e b0 SLOT MACHINE +U+1F3B1 🎱 f0 9f 8e b1 BILLIARDS +U+1F3B2 🎲 f0 9f 8e b2 GAME DIE +U+1F3B3 🎳 f0 9f 8e b3 BOWLING +U+1F3B4 🎴 f0 9f 8e b4 FLOWER PLAYING CARDS +U+1F3B5 🎵 f0 9f 8e b5 MUSICAL NOTE +U+1F3B6 🎶 f0 9f 8e b6 MULTIPLE MUSICAL NOTES +U+1F3B7 🎷 f0 9f 8e b7 SAXOPHONE +U+1F3B8 🎸 f0 9f 8e b8 GUITAR +U+1F3B9 🎹 f0 9f 8e b9 MUSICAL KEYBOARD +U+1F3BA 🎺 f0 9f 8e ba TRUMPET +U+1F3BB 🎻 f0 9f 8e bb VIOLIN +U+1F3BC 🎼 f0 9f 8e bc MUSICAL SCORE +U+1F3BD 🎽 f0 9f 8e bd RUNNING SHIRT WITH SASH +U+1F3BE 🎾 f0 9f 8e be TENNIS RACQUET AND BALL +U+1F3BF 🎿 f0 9f 8e bf SKI AND SKI BOOT +U+1F3C0 🏀 f0 9f 8f 80 BASKETBALL AND HOOP +U+1F3C1 🏁 f0 9f 8f 81 CHEQUERED FLAG +U+1F3C2 🏂 f0 9f 8f 82 SNOWBOARDER +U+1F3C3 🏃 f0 9f 8f 83 RUNNER +U+1F3C4 🏄 f0 9f 8f 84 SURFER +U+1F3C5 🏅 f0 9f 8f 85 SPORTS MEDAL +U+1F3C6 🏆 f0 9f 8f 86 TROPHY +U+1F3C7 🏇 f0 9f 8f 87 HORSE RACING +U+1F3C8 🏈 f0 9f 8f 88 AMERICAN FOOTBALL +U+1F3C9 🏉 f0 9f 8f 89 RUGBY FOOTBALL +U+1F3CA 🏊 f0 9f 8f 8a SWIMMER +U+1F3CB 🏋 f0 9f 8f 8b WEIGHT LIFTER +U+1F3CC 🏌 f0 9f 8f 8c GOLFER +U+1F3CD 🏍 f0 9f 8f 8d RACING MOTORCYCLE +U+1F3CE 🏎 f0 9f 8f 8e RACING CAR +U+1F3CF 🏏 f0 9f 8f 8f CRICKET BAT AND BALL +U+1F3D0 🏐 f0 9f 8f 90 VOLLEYBALL +U+1F3D1 🏑 f0 9f 8f 91 FIELD HOCKEY STICK AND BALL +U+1F3D2 🏒 f0 9f 8f 92 ICE HOCKEY STICK AND PUCK +U+1F3D3 🏓 f0 9f 8f 93 TABLE TENNIS PADDLE AND BALL +U+1F3D4 🏔 f0 9f 8f 94 SNOW CAPPED MOUNTAIN +U+1F3D5 🏕 f0 9f 8f 95 CAMPING +U+1F3D6 🏖 f0 9f 8f 96 BEACH WITH UMBRELLA +U+1F3D7 🏗 f0 9f 8f 97 BUILDING CONSTRUCTION +U+1F3D8 🏘 f0 9f 8f 98 HOUSE BUILDINGS +U+1F3D9 🏙 f0 9f 8f 99 CITYSCAPE +U+1F3DA 🏚 f0 9f 8f 9a DERELICT HOUSE BUILDING +U+1F3DB 🏛 f0 9f 8f 9b CLASSICAL BUILDING +U+1F3DC 🏜 f0 9f 8f 9c DESERT +U+1F3DD 🏝 f0 9f 8f 9d DESERT ISLAND +U+1F3DE 🏞 f0 9f 8f 9e NATIONAL PARK +U+1F3DF 🏟 f0 9f 8f 9f STADIUM +U+1F3E0 🏠 f0 9f 8f a0 HOUSE BUILDING +U+1F3E1 🏡 f0 9f 8f a1 HOUSE WITH GARDEN +U+1F3E2 🏢 f0 9f 8f a2 OFFICE BUILDING +U+1F3E3 🏣 f0 9f 8f a3 JAPANESE POST OFFICE +U+1F3E4 🏤 f0 9f 8f a4 EUROPEAN POST OFFICE +U+1F3E5 🏥 f0 9f 8f a5 HOSPITAL +U+1F3E6 🏦 f0 9f 8f a6 BANK +U+1F3E7 🏧 f0 9f 8f a7 AUTOMATED TELLER MACHINE +U+1F3E8 🏨 f0 9f 8f a8 HOTEL +U+1F3E9 🏩 f0 9f 8f a9 LOVE HOTEL +U+1F3EA 🏪 f0 9f 8f aa CONVENIENCE STORE +U+1F3EB 🏫 f0 9f 8f ab SCHOOL +U+1F3EC 🏬 f0 9f 8f ac DEPARTMENT STORE +U+1F3ED 🏭 f0 9f 8f ad FACTORY +U+1F3EE 🏮 f0 9f 8f ae IZAKAYA LANTERN +U+1F3EF 🏯 f0 9f 8f af JAPANESE CASTLE +U+1F3F0 🏰 f0 9f 8f b0 EUROPEAN CASTLE +U+1F3F1 🏱 f0 9f 8f b1 WHITE PENNANT +U+1F3F2 🏲 f0 9f 8f b2 BLACK PENNANT +U+1F3F3 🏳 f0 9f 8f b3 WAVING WHITE FLAG +U+1F3F4 🏴 f0 9f 8f b4 WAVING BLACK FLAG +U+1F3F5 🏵 f0 9f 8f b5 ROSETTE +U+1F3F6 🏶 f0 9f 8f b6 BLACK ROSETTE +U+1F3F7 🏷 f0 9f 8f b7 LABEL +U+1F3F8 🏸 f0 9f 8f b8 BADMINTON RACQUET AND SHUTTLECOCK +U+1F3F9 🏹 f0 9f 8f b9 BOW AND ARROW +U+1F3FA 🏺 f0 9f 8f ba AMPHORA +U+1F3FB 🏻 f0 9f 8f bb EMOJI MODIFIER FITZPATRICK TYPE-1-2 +U+1F3FC 🏼 f0 9f 8f bc EMOJI MODIFIER FITZPATRICK TYPE-3 +U+1F3FD 🏽 f0 9f 8f bd EMOJI MODIFIER FITZPATRICK TYPE-4 +U+1F3FE 🏾 f0 9f 8f be EMOJI MODIFIER FITZPATRICK TYPE-5 +U+1F3FF 🏿 f0 9f 8f bf EMOJI MODIFIER FITZPATRICK TYPE-6 \ No newline at end of file diff --git a/tests/utf-8/utf-8.misc.tech.txt b/tests/utf-8/utf-8.misc.tech.txt new file mode 100644 index 00000000..7d9e9f68 --- /dev/null +++ b/tests/utf-8/utf-8.misc.tech.txt @@ -0,0 +1,256 @@ +U+2300 ⌀ e2 8c 80 DIAMETER SIGN +U+2301 ⌁ e2 8c 81 ELECTRIC ARROW +U+2302 ⌂ e2 8c 82 HOUSE +U+2303 ⌃ e2 8c 83 UP ARROWHEAD +U+2304 ⌄ e2 8c 84 DOWN ARROWHEAD +U+2305 ⌅ e2 8c 85 PROJECTIVE +U+2306 ⌆ e2 8c 86 PERSPECTIVE +U+2307 ⌇ e2 8c 87 WAVY LINE +U+2308 ⌈ e2 8c 88 LEFT CEILING +U+2309 ⌉ e2 8c 89 RIGHT CEILING +U+230A ⌊ e2 8c 8a LEFT FLOOR +U+230B ⌋ e2 8c 8b RIGHT FLOOR +U+230C ⌌ e2 8c 8c BOTTOM RIGHT CROP +U+230D ⌍ e2 8c 8d BOTTOM LEFT CROP +U+230E ⌎ e2 8c 8e TOP RIGHT CROP +U+230F ⌏ e2 8c 8f TOP LEFT CROP +U+2310 ⌐ e2 8c 90 REVERSED NOT SIGN +U+2311 ⌑ e2 8c 91 SQUARE LOZENGE +U+2312 ⌒ e2 8c 92 ARC +U+2313 ⌓ e2 8c 93 SEGMENT +U+2314 ⌔ e2 8c 94 SECTOR +U+2315 ⌕ e2 8c 95 TELEPHONE RECORDER +U+2316 ⌖ e2 8c 96 POSITION INDICATOR +U+2317 ⌗ e2 8c 97 VIEWDATA SQUARE +U+2318 ⌘ e2 8c 98 PLACE OF INTEREST SIGN +U+2319 ⌙ e2 8c 99 TURNED NOT SIGN +U+231A ⌚ e2 8c 9a WATCH +U+231B ⌛ e2 8c 9b HOURGLASS +U+231C ⌜ e2 8c 9c TOP LEFT CORNER +U+231D ⌝ e2 8c 9d TOP RIGHT CORNER +U+231E ⌞ e2 8c 9e BOTTOM LEFT CORNER +U+231F ⌟ e2 8c 9f BOTTOM RIGHT CORNER +U+2320 ⌠ e2 8c a0 TOP HALF INTEGRAL +U+2321 ⌡ e2 8c a1 BOTTOM HALF INTEGRAL +U+2322 ⌢ e2 8c a2 FROWN +U+2323 ⌣ e2 8c a3 SMILE +U+2324 ⌤ e2 8c a4 UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS +U+2325 ⌥ e2 8c a5 OPTION KEY +U+2326 ⌦ e2 8c a6 ERASE TO THE RIGHT +U+2327 ⌧ e2 8c a7 X IN A RECTANGLE BOX +U+2328 ⌨ e2 8c a8 KEYBOARD +U+2329 〈 e2 8c a9 LEFT-POINTING ANGLE BRACKET +U+232A 〉 e2 8c aa RIGHT-POINTING ANGLE BRACKET +U+232B ⌫ e2 8c ab ERASE TO THE LEFT +U+232C ⌬ e2 8c ac BENZENE RING +U+232D ⌭ e2 8c ad CYLINDRICITY +U+232E ⌮ e2 8c ae ALL AROUND-PROFILE +U+232F ⌯ e2 8c af SYMMETRY +U+2330 ⌰ e2 8c b0 TOTAL RUNOUT +U+2331 ⌱ e2 8c b1 DIMENSION ORIGIN +U+2332 ⌲ e2 8c b2 CONICAL TAPER +U+2333 ⌳ e2 8c b3 SLOPE +U+2334 ⌴ e2 8c b4 COUNTERBORE +U+2335 ⌵ e2 8c b5 COUNTERSINK +U+2336 ⌶ e2 8c b6 APL FUNCTIONAL SYMBOL I-BEAM +U+2337 ⌷ e2 8c b7 APL FUNCTIONAL SYMBOL SQUISH QUAD +U+2338 ⌸ e2 8c b8 APL FUNCTIONAL SYMBOL QUAD EQUAL +U+2339 ⌹ e2 8c b9 APL FUNCTIONAL SYMBOL QUAD DIVIDE +U+233A ⌺ e2 8c ba APL FUNCTIONAL SYMBOL QUAD DIAMOND +U+233B ⌻ e2 8c bb APL FUNCTIONAL SYMBOL QUAD JOT +U+233C ⌼ e2 8c bc APL FUNCTIONAL SYMBOL QUAD CIRCLE +U+233D ⌽ e2 8c bd APL FUNCTIONAL SYMBOL CIRCLE STILE +U+233E ⌾ e2 8c be APL FUNCTIONAL SYMBOL CIRCLE JOT +U+233F ⌿ e2 8c bf APL FUNCTIONAL SYMBOL SLASH BAR +U+2340 ⍀ e2 8d 80 APL FUNCTIONAL SYMBOL BACKSLASH BAR +U+2341 ⍁ e2 8d 81 APL FUNCTIONAL SYMBOL QUAD SLASH +U+2342 ⍂ e2 8d 82 APL FUNCTIONAL SYMBOL QUAD BACKSLASH +U+2343 ⍃ e2 8d 83 APL FUNCTIONAL SYMBOL QUAD LESS-THAN +U+2344 ⍄ e2 8d 84 APL FUNCTIONAL SYMBOL QUAD GREATER-THAN +U+2345 ⍅ e2 8d 85 APL FUNCTIONAL SYMBOL LEFTWARDS VANE +U+2346 ⍆ e2 8d 86 APL FUNCTIONAL SYMBOL RIGHTWARDS VANE +U+2347 ⍇ e2 8d 87 APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW +U+2348 ⍈ e2 8d 88 APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW +U+2349 ⍉ e2 8d 89 APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH +U+234A ⍊ e2 8d 8a APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR +U+234B ⍋ e2 8d 8b APL FUNCTIONAL SYMBOL DELTA STILE +U+234C ⍌ e2 8d 8c APL FUNCTIONAL SYMBOL QUAD DOWN CARET +U+234D ⍍ e2 8d 8d APL FUNCTIONAL SYMBOL QUAD DELTA +U+234E ⍎ e2 8d 8e APL FUNCTIONAL SYMBOL DOWN TACK JOT +U+234F ⍏ e2 8d 8f APL FUNCTIONAL SYMBOL UPWARDS VANE +U+2350 ⍐ e2 8d 90 APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW +U+2351 ⍑ e2 8d 91 APL FUNCTIONAL SYMBOL UP TACK OVERBAR +U+2352 ⍒ e2 8d 92 APL FUNCTIONAL SYMBOL DEL STILE +U+2353 ⍓ e2 8d 93 APL FUNCTIONAL SYMBOL QUAD UP CARET +U+2354 ⍔ e2 8d 94 APL FUNCTIONAL SYMBOL QUAD DEL +U+2355 ⍕ e2 8d 95 APL FUNCTIONAL SYMBOL UP TACK JOT +U+2356 ⍖ e2 8d 96 APL FUNCTIONAL SYMBOL DOWNWARDS VANE +U+2357 ⍗ e2 8d 97 APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW +U+2358 ⍘ e2 8d 98 APL FUNCTIONAL SYMBOL QUOTE UNDERBAR +U+2359 ⍙ e2 8d 99 APL FUNCTIONAL SYMBOL DELTA UNDERBAR +U+235A ⍚ e2 8d 9a APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR +U+235B ⍛ e2 8d 9b APL FUNCTIONAL SYMBOL JOT UNDERBAR +U+235C ⍜ e2 8d 9c APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR +U+235D ⍝ e2 8d 9d APL FUNCTIONAL SYMBOL UP SHOE JOT +U+235E ⍞ e2 8d 9e APL FUNCTIONAL SYMBOL QUOTE QUAD +U+235F ⍟ e2 8d 9f APL FUNCTIONAL SYMBOL CIRCLE STAR +U+2360 ⍠ e2 8d a0 APL FUNCTIONAL SYMBOL QUAD COLON +U+2361 ⍡ e2 8d a1 APL FUNCTIONAL SYMBOL UP TACK DIAERESIS +U+2362 ⍢ e2 8d a2 APL FUNCTIONAL SYMBOL DEL DIAERESIS +U+2363 ⍣ e2 8d a3 APL FUNCTIONAL SYMBOL STAR DIAERESIS +U+2364 ⍤ e2 8d a4 APL FUNCTIONAL SYMBOL JOT DIAERESIS +U+2365 ⍥ e2 8d a5 APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS +U+2366 ⍦ e2 8d a6 APL FUNCTIONAL SYMBOL DOWN SHOE STILE +U+2367 ⍧ e2 8d a7 APL FUNCTIONAL SYMBOL LEFT SHOE STILE +U+2368 ⍨ e2 8d a8 APL FUNCTIONAL SYMBOL TILDE DIAERESIS +U+2369 ⍩ e2 8d a9 APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS +U+236A ⍪ e2 8d aa APL FUNCTIONAL SYMBOL COMMA BAR +U+236B ⍫ e2 8d ab APL FUNCTIONAL SYMBOL DEL TILDE +U+236C ⍬ e2 8d ac APL FUNCTIONAL SYMBOL ZILDE +U+236D ⍭ e2 8d ad APL FUNCTIONAL SYMBOL STILE TILDE +U+236E ⍮ e2 8d ae APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR +U+236F ⍯ e2 8d af APL FUNCTIONAL SYMBOL QUAD NOT EQUAL +U+2370 ⍰ e2 8d b0 APL FUNCTIONAL SYMBOL QUAD QUESTION +U+2371 ⍱ e2 8d b1 APL FUNCTIONAL SYMBOL DOWN CARET TILDE +U+2372 ⍲ e2 8d b2 APL FUNCTIONAL SYMBOL UP CARET TILDE +U+2373 ⍳ e2 8d b3 APL FUNCTIONAL SYMBOL IOTA +U+2374 ⍴ e2 8d b4 APL FUNCTIONAL SYMBOL RHO +U+2375 ⍵ e2 8d b5 APL FUNCTIONAL SYMBOL OMEGA +U+2376 ⍶ e2 8d b6 APL FUNCTIONAL SYMBOL ALPHA UNDERBAR +U+2377 ⍷ e2 8d b7 APL FUNCTIONAL SYMBOL EPSILON UNDERBAR +U+2378 ⍸ e2 8d b8 APL FUNCTIONAL SYMBOL IOTA UNDERBAR +U+2379 ⍹ e2 8d b9 APL FUNCTIONAL SYMBOL OMEGA UNDERBAR +U+237A ⍺ e2 8d ba APL FUNCTIONAL SYMBOL ALPHA +U+237B ⍻ e2 8d bb NOT CHECK MARK +U+237C ⍼ e2 8d bc RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW +U+237D ⍽ e2 8d bd SHOULDERED OPEN BOX +U+237E ⍾ e2 8d be BELL SYMBOL +U+237F ⍿ e2 8d bf VERTICAL LINE WITH MIDDLE DOT +U+2380 ⎀ e2 8e 80 INSERTION SYMBOL +U+2381 ⎁ e2 8e 81 CONTINUOUS UNDERLINE SYMBOL +U+2382 ⎂ e2 8e 82 DISCONTINUOUS UNDERLINE SYMBOL +U+2383 ⎃ e2 8e 83 EMPHASIS SYMBOL +U+2384 ⎄ e2 8e 84 COMPOSITION SYMBOL +U+2385 ⎅ e2 8e 85 WHITE SQUARE WITH CENTRE VERTICAL LINE +U+2386 ⎆ e2 8e 86 ENTER SYMBOL +U+2387 ⎇ e2 8e 87 ALTERNATIVE KEY SYMBOL +U+2388 ⎈ e2 8e 88 HELM SYMBOL +U+2389 ⎉ e2 8e 89 CIRCLED HORIZONTAL BAR WITH NOTCH +U+238A ⎊ e2 8e 8a CIRCLED TRIANGLE DOWN +U+238B ⎋ e2 8e 8b BROKEN CIRCLE WITH NORTHWEST ARROW +U+238C ⎌ e2 8e 8c UNDO SYMBOL +U+238D ⎍ e2 8e 8d MONOSTABLE SYMBOL +U+238E ⎎ e2 8e 8e HYSTERESIS SYMBOL +U+238F ⎏ e2 8e 8f OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL +U+2390 ⎐ e2 8e 90 OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL +U+2391 ⎑ e2 8e 91 PASSIVE-PULL-DOWN-OUTPUT SYMBOL +U+2392 ⎒ e2 8e 92 PASSIVE-PULL-UP-OUTPUT SYMBOL +U+2393 ⎓ e2 8e 93 DIRECT CURRENT SYMBOL FORM TWO +U+2394 ⎔ e2 8e 94 SOFTWARE-FUNCTION SYMBOL +U+2395 ⎕ e2 8e 95 APL FUNCTIONAL SYMBOL QUAD +U+2396 ⎖ e2 8e 96 DECIMAL SEPARATOR KEY SYMBOL +U+2397 ⎗ e2 8e 97 PREVIOUS PAGE +U+2398 ⎘ e2 8e 98 NEXT PAGE +U+2399 ⎙ e2 8e 99 PRINT SCREEN SYMBOL +U+239A ⎚ e2 8e 9a CLEAR SCREEN SYMBOL +U+239B ⎛ e2 8e 9b LEFT PARENTHESIS UPPER HOOK +U+239C ⎜ e2 8e 9c LEFT PARENTHESIS EXTENSION +U+239D ⎝ e2 8e 9d LEFT PARENTHESIS LOWER HOOK +U+239E ⎞ e2 8e 9e RIGHT PARENTHESIS UPPER HOOK +U+239F ⎟ e2 8e 9f RIGHT PARENTHESIS EXTENSION +U+23A0 ⎠ e2 8e a0 RIGHT PARENTHESIS LOWER HOOK +U+23A1 ⎡ e2 8e a1 LEFT SQUARE BRACKET UPPER CORNER +U+23A2 ⎢ e2 8e a2 LEFT SQUARE BRACKET EXTENSION +U+23A3 ⎣ e2 8e a3 LEFT SQUARE BRACKET LOWER CORNER +U+23A4 ⎤ e2 8e a4 RIGHT SQUARE BRACKET UPPER CORNER +U+23A5 ⎥ e2 8e a5 RIGHT SQUARE BRACKET EXTENSION +U+23A6 ⎦ e2 8e a6 RIGHT SQUARE BRACKET LOWER CORNER +U+23A7 ⎧ e2 8e a7 LEFT CURLY BRACKET UPPER HOOK +U+23A8 ⎨ e2 8e a8 LEFT CURLY BRACKET MIDDLE PIECE +U+23A9 ⎩ e2 8e a9 LEFT CURLY BRACKET LOWER HOOK +U+23AA ⎪ e2 8e aa CURLY BRACKET EXTENSION +U+23AB ⎫ e2 8e ab RIGHT CURLY BRACKET UPPER HOOK +U+23AC ⎬ e2 8e ac RIGHT CURLY BRACKET MIDDLE PIECE +U+23AD ⎭ e2 8e ad RIGHT CURLY BRACKET LOWER HOOK +U+23AE ⎮ e2 8e ae INTEGRAL EXTENSION +U+23AF ⎯ e2 8e af HORIZONTAL LINE EXTENSION +U+23B0 ⎰ e2 8e b0 UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION +U+23B1 ⎱ e2 8e b1 UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION +U+23B2 ⎲ e2 8e b2 SUMMATION TOP +U+23B3 ⎳ e2 8e b3 SUMMATION BOTTOM +U+23B4 ⎴ e2 8e b4 TOP SQUARE BRACKET +U+23B5 ⎵ e2 8e b5 BOTTOM SQUARE BRACKET +U+23B6 ⎶ e2 8e b6 BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET +U+23B7 ⎷ e2 8e b7 RADICAL SYMBOL BOTTOM +U+23B8 ⎸ e2 8e b8 LEFT VERTICAL BOX LINE +U+23B9 ⎹ e2 8e b9 RIGHT VERTICAL BOX LINE +U+23BA ⎺ e2 8e ba HORIZONTAL SCAN LINE-1 +U+23BB ⎻ e2 8e bb HORIZONTAL SCAN LINE-3 +U+23BC ⎼ e2 8e bc HORIZONTAL SCAN LINE-7 +U+23BD ⎽ e2 8e bd HORIZONTAL SCAN LINE-9 +U+23BE ⎾ e2 8e be DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT +U+23BF ⎿ e2 8e bf DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT +U+23C0 ⏀ e2 8f 80 DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE +U+23C1 ⏁ e2 8f 81 DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE +U+23C2 ⏂ e2 8f 82 DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE +U+23C3 ⏃ e2 8f 83 DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE +U+23C4 ⏄ e2 8f 84 DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE +U+23C5 ⏅ e2 8f 85 DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE +U+23C6 ⏆ e2 8f 86 DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE +U+23C7 ⏇ e2 8f 87 DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE +U+23C8 ⏈ e2 8f 88 DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE +U+23C9 ⏉ e2 8f 89 DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL +U+23CA ⏊ e2 8f 8a DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL +U+23CB ⏋ e2 8f 8b DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT +U+23CC ⏌ e2 8f 8c DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT +U+23CD ⏍ e2 8f 8d SQUARE FOOT +U+23CE ⏎ e2 8f 8e RETURN SYMBOL +U+23CF ⏏ e2 8f 8f EJECT SYMBOL +U+23D0 ⏐ e2 8f 90 VERTICAL LINE EXTENSION +U+23D1 ⏑ e2 8f 91 METRICAL BREVE +U+23D2 ⏒ e2 8f 92 METRICAL LONG OVER SHORT +U+23D3 ⏓ e2 8f 93 METRICAL SHORT OVER LONG +U+23D4 ⏔ e2 8f 94 METRICAL LONG OVER TWO SHORTS +U+23D5 ⏕ e2 8f 95 METRICAL TWO SHORTS OVER LONG +U+23D6 ⏖ e2 8f 96 METRICAL TWO SHORTS JOINED +U+23D7 ⏗ e2 8f 97 METRICAL TRISEME +U+23D8 ⏘ e2 8f 98 METRICAL TETRASEME +U+23D9 ⏙ e2 8f 99 METRICAL PENTASEME +U+23DA ⏚ e2 8f 9a EARTH GROUND +U+23DB ⏛ e2 8f 9b FUSE +U+23DC ⏜ e2 8f 9c TOP PARENTHESIS +U+23DD ⏝ e2 8f 9d BOTTOM PARENTHESIS +U+23DE ⏞ e2 8f 9e TOP CURLY BRACKET +U+23DF ⏟ e2 8f 9f BOTTOM CURLY BRACKET +U+23E0 ⏠ e2 8f a0 TOP TORTOISE SHELL BRACKET +U+23E1 ⏡ e2 8f a1 BOTTOM TORTOISE SHELL BRACKET +U+23E2 ⏢ e2 8f a2 WHITE TRAPEZIUM +U+23E3 ⏣ e2 8f a3 BENZENE RING WITH CIRCLE +U+23E4 ⏤ e2 8f a4 STRAIGHTNESS +U+23E5 ⏥ e2 8f a5 FLATNESS +U+23E6 ⏦ e2 8f a6 AC CURRENT +U+23E7 ⏧ e2 8f a7 ELECTRICAL INTERSECTION +U+23E8 ⏨ e2 8f a8 DECIMAL EXPONENT SYMBOL +U+23E9 ⏩ e2 8f a9 BLACK RIGHT-POINTING DOUBLE TRIANGLE +U+23EA ⏪ e2 8f aa BLACK LEFT-POINTING DOUBLE TRIANGLE +U+23EB ⏫ e2 8f ab BLACK UP-POINTING DOUBLE TRIANGLE +U+23EC ⏬ e2 8f ac BLACK DOWN-POINTING DOUBLE TRIANGLE +U+23ED ⏭ e2 8f ad BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +U+23EE ⏮ e2 8f ae BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR +U+23EF ⏯ e2 8f af BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR +U+23F0 ⏰ e2 8f b0 ALARM CLOCK +U+23F1 ⏱ e2 8f b1 STOPWATCH +U+23F2 ⏲ e2 8f b2 TIMER CLOCK +U+23F3 ⏳ e2 8f b3 HOURGLASS WITH FLOWING SAND +U+23F4 ⏴ e2 8f b4 BLACK MEDIUM LEFT-POINTING TRIANGLE +U+23F5 ⏵ e2 8f b5 BLACK MEDIUM RIGHT-POINTING TRIANGLE +U+23F6 ⏶ e2 8f b6 BLACK MEDIUM UP-POINTING TRIANGLE +U+23F7 ⏷ e2 8f b7 BLACK MEDIUM DOWN-POINTING TRIANGLE +U+23F8 ⏸ e2 8f b8 DOUBLE VERTICAL BAR +U+23F9 ⏹ e2 8f b9 BLACK SQUARE FOR STOP +U+23FA ⏺ e2 8f ba BLACK CIRCLE FOR RECORD +U+23FB ⏻ e2 8f bb POWER SYMBOL +U+23FC ⏼ e2 8f bc POWER ON-OFF SYMBOL +U+23FD ⏽ e2 8f bd POWER ON SYMBOL +U+23FE ⏾ e2 8f be POWER SLEEP SYMBOL +U+23FF ⏿ e2 8f bf OBSERVER EYE SYMBOL \ No newline at end of file diff --git a/tests/utf-8/utf-8.numbers.arrows.txt b/tests/utf-8/utf-8.numbers.arrows.txt new file mode 100644 index 00000000..81626e62 --- /dev/null +++ b/tests/utf-8/utf-8.numbers.arrows.txt @@ -0,0 +1,256 @@ +U+2150 ⅐ e2 85 90 VULGAR FRACTION ONE SEVENTH +U+2151 ⅑ e2 85 91 VULGAR FRACTION ONE NINTH +U+2152 ⅒ e2 85 92 VULGAR FRACTION ONE TENTH +U+2153 ⅓ e2 85 93 VULGAR FRACTION ONE THIRD +U+2154 ⅔ e2 85 94 VULGAR FRACTION TWO THIRDS +U+2155 ⅕ e2 85 95 VULGAR FRACTION ONE FIFTH +U+2156 ⅖ e2 85 96 VULGAR FRACTION TWO FIFTHS +U+2157 ⅗ e2 85 97 VULGAR FRACTION THREE FIFTHS +U+2158 ⅘ e2 85 98 VULGAR FRACTION FOUR FIFTHS +U+2159 ⅙ e2 85 99 VULGAR FRACTION ONE SIXTH +U+215A ⅚ e2 85 9a VULGAR FRACTION FIVE SIXTHS +U+215B ⅛ e2 85 9b VULGAR FRACTION ONE EIGHTH +U+215C ⅜ e2 85 9c VULGAR FRACTION THREE EIGHTHS +U+215D ⅝ e2 85 9d VULGAR FRACTION FIVE EIGHTHS +U+215E ⅞ e2 85 9e VULGAR FRACTION SEVEN EIGHTHS +U+215F ⅟ e2 85 9f FRACTION NUMERATOR ONE +U+2160 Ⅰ e2 85 a0 ROMAN NUMERAL ONE +U+2161 Ⅱ e2 85 a1 ROMAN NUMERAL TWO +U+2162 Ⅲ e2 85 a2 ROMAN NUMERAL THREE +U+2163 Ⅳ e2 85 a3 ROMAN NUMERAL FOUR +U+2164 Ⅴ e2 85 a4 ROMAN NUMERAL FIVE +U+2165 Ⅵ e2 85 a5 ROMAN NUMERAL SIX +U+2166 Ⅶ e2 85 a6 ROMAN NUMERAL SEVEN +U+2167 Ⅷ e2 85 a7 ROMAN NUMERAL EIGHT +U+2168 Ⅸ e2 85 a8 ROMAN NUMERAL NINE +U+2169 Ⅹ e2 85 a9 ROMAN NUMERAL TEN +U+216A Ⅺ e2 85 aa ROMAN NUMERAL ELEVEN +U+216B Ⅻ e2 85 ab ROMAN NUMERAL TWELVE +U+216C Ⅼ e2 85 ac ROMAN NUMERAL FIFTY +U+216D Ⅽ e2 85 ad ROMAN NUMERAL ONE HUNDRED +U+216E Ⅾ e2 85 ae ROMAN NUMERAL FIVE HUNDRED +U+216F Ⅿ e2 85 af ROMAN NUMERAL ONE THOUSAND +U+2170 ⅰ e2 85 b0 SMALL ROMAN NUMERAL ONE +U+2171 ⅱ e2 85 b1 SMALL ROMAN NUMERAL TWO +U+2172 ⅲ e2 85 b2 SMALL ROMAN NUMERAL THREE +U+2173 ⅳ e2 85 b3 SMALL ROMAN NUMERAL FOUR +U+2174 ⅴ e2 85 b4 SMALL ROMAN NUMERAL FIVE +U+2175 ⅵ e2 85 b5 SMALL ROMAN NUMERAL SIX +U+2176 ⅶ e2 85 b6 SMALL ROMAN NUMERAL SEVEN +U+2177 ⅷ e2 85 b7 SMALL ROMAN NUMERAL EIGHT +U+2178 ⅸ e2 85 b8 SMALL ROMAN NUMERAL NINE +U+2179 ⅹ e2 85 b9 SMALL ROMAN NUMERAL TEN +U+217A ⅺ e2 85 ba SMALL ROMAN NUMERAL ELEVEN +U+217B ⅻ e2 85 bb SMALL ROMAN NUMERAL TWELVE +U+217C ⅼ e2 85 bc SMALL ROMAN NUMERAL FIFTY +U+217D ⅽ e2 85 bd SMALL ROMAN NUMERAL ONE HUNDRED +U+217E ⅾ e2 85 be SMALL ROMAN NUMERAL FIVE HUNDRED +U+217F ⅿ e2 85 bf SMALL ROMAN NUMERAL ONE THOUSAND +U+2180 ↀ e2 86 80 ROMAN NUMERAL ONE THOUSAND C D +U+2181 ↁ e2 86 81 ROMAN NUMERAL FIVE THOUSAND +U+2182 ↂ e2 86 82 ROMAN NUMERAL TEN THOUSAND +U+2183 Ↄ e2 86 83 ROMAN NUMERAL REVERSED ONE HUNDRED +U+2184 ↄ e2 86 84 LATIN SMALL LETTER REVERSED C +U+2185 ↅ e2 86 85 ROMAN NUMERAL SIX LATE FORM +U+2186 ↆ e2 86 86 ROMAN NUMERAL FIFTY EARLY FORM +U+2187 ↇ e2 86 87 ROMAN NUMERAL FIFTY THOUSAND +U+2188 ↈ e2 86 88 ROMAN NUMERAL ONE HUNDRED THOUSAND +U+2189 ↉ e2 86 89 VULGAR FRACTION ZERO THIRDS +U+218A ↊ e2 86 8a TURNED DIGIT TWO +U+218B ↋ e2 86 8b TURNED DIGIT THREE +U+218C ↌ e2 86 8c +U+218D ↍ e2 86 8d +U+218E ↎ e2 86 8e +U+218F ↏ e2 86 8f +U+2190 ← e2 86 90 LEFTWARDS ARROW +U+2191 ↑ e2 86 91 UPWARDS ARROW +U+2192 → e2 86 92 RIGHTWARDS ARROW +U+2193 ↓ e2 86 93 DOWNWARDS ARROW +U+2194 ↔ e2 86 94 LEFT RIGHT ARROW +U+2195 ↕ e2 86 95 UP DOWN ARROW +U+2196 ↖ e2 86 96 NORTH WEST ARROW +U+2197 ↗ e2 86 97 NORTH EAST ARROW +U+2198 ↘ e2 86 98 SOUTH EAST ARROW +U+2199 ↙ e2 86 99 SOUTH WEST ARROW +U+219A ↚ e2 86 9a LEFTWARDS ARROW WITH STROKE +U+219B ↛ e2 86 9b RIGHTWARDS ARROW WITH STROKE +U+219C ↜ e2 86 9c LEFTWARDS WAVE ARROW +U+219D ↝ e2 86 9d RIGHTWARDS WAVE ARROW +U+219E ↞ e2 86 9e LEFTWARDS TWO HEADED ARROW +U+219F ↟ e2 86 9f UPWARDS TWO HEADED ARROW +U+21A0 ↠ e2 86 a0 RIGHTWARDS TWO HEADED ARROW +U+21A1 ↡ e2 86 a1 DOWNWARDS TWO HEADED ARROW +U+21A2 ↢ e2 86 a2 LEFTWARDS ARROW WITH TAIL +U+21A3 ↣ e2 86 a3 RIGHTWARDS ARROW WITH TAIL +U+21A4 ↤ e2 86 a4 LEFTWARDS ARROW FROM BAR +U+21A5 ↥ e2 86 a5 UPWARDS ARROW FROM BAR +U+21A6 ↦ e2 86 a6 RIGHTWARDS ARROW FROM BAR +U+21A7 ↧ e2 86 a7 DOWNWARDS ARROW FROM BAR +U+21A8 ↨ e2 86 a8 UP DOWN ARROW WITH BASE +U+21A9 ↩ e2 86 a9 LEFTWARDS ARROW WITH HOOK +U+21AA ↪ e2 86 aa RIGHTWARDS ARROW WITH HOOK +U+21AB ↫ e2 86 ab LEFTWARDS ARROW WITH LOOP +U+21AC ↬ e2 86 ac RIGHTWARDS ARROW WITH LOOP +U+21AD ↭ e2 86 ad LEFT RIGHT WAVE ARROW +U+21AE ↮ e2 86 ae LEFT RIGHT ARROW WITH STROKE +U+21AF ↯ e2 86 af DOWNWARDS ZIGZAG ARROW +U+21B0 ↰ e2 86 b0 UPWARDS ARROW WITH TIP LEFTWARDS +U+21B1 ↱ e2 86 b1 UPWARDS ARROW WITH TIP RIGHTWARDS +U+21B2 ↲ e2 86 b2 DOWNWARDS ARROW WITH TIP LEFTWARDS +U+21B3 ↳ e2 86 b3 DOWNWARDS ARROW WITH TIP RIGHTWARDS +U+21B4 ↴ e2 86 b4 RIGHTWARDS ARROW WITH CORNER DOWNWARDS +U+21B5 ↵ e2 86 b5 DOWNWARDS ARROW WITH CORNER LEFTWARDS +U+21B6 ↶ e2 86 b6 ANTICLOCKWISE TOP SEMICIRCLE ARROW +U+21B7 ↷ e2 86 b7 CLOCKWISE TOP SEMICIRCLE ARROW +U+21B8 ↸ e2 86 b8 NORTH WEST ARROW TO LONG BAR +U+21B9 ↹ e2 86 b9 LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR +U+21BA ↺ e2 86 ba ANTICLOCKWISE OPEN CIRCLE ARROW +U+21BB ↻ e2 86 bb CLOCKWISE OPEN CIRCLE ARROW +U+21BC ↼ e2 86 bc LEFTWARDS HARPOON WITH BARB UPWARDS +U+21BD ↽ e2 86 bd LEFTWARDS HARPOON WITH BARB DOWNWARDS +U+21BE ↾ e2 86 be UPWARDS HARPOON WITH BARB RIGHTWARDS +U+21BF ↿ e2 86 bf UPWARDS HARPOON WITH BARB LEFTWARDS +U+21C0 ⇀ e2 87 80 RIGHTWARDS HARPOON WITH BARB UPWARDS +U+21C1 ⇁ e2 87 81 RIGHTWARDS HARPOON WITH BARB DOWNWARDS +U+21C2 ⇂ e2 87 82 DOWNWARDS HARPOON WITH BARB RIGHTWARDS +U+21C3 ⇃ e2 87 83 DOWNWARDS HARPOON WITH BARB LEFTWARDS +U+21C4 ⇄ e2 87 84 RIGHTWARDS ARROW OVER LEFTWARDS ARROW +U+21C5 ⇅ e2 87 85 UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW +U+21C6 ⇆ e2 87 86 LEFTWARDS ARROW OVER RIGHTWARDS ARROW +U+21C7 ⇇ e2 87 87 LEFTWARDS PAIRED ARROWS +U+21C8 ⇈ e2 87 88 UPWARDS PAIRED ARROWS +U+21C9 ⇉ e2 87 89 RIGHTWARDS PAIRED ARROWS +U+21CA ⇊ e2 87 8a DOWNWARDS PAIRED ARROWS +U+21CB ⇋ e2 87 8b LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON +U+21CC ⇌ e2 87 8c RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON +U+21CD ⇍ e2 87 8d LEFTWARDS DOUBLE ARROW WITH STROKE +U+21CE ⇎ e2 87 8e LEFT RIGHT DOUBLE ARROW WITH STROKE +U+21CF ⇏ e2 87 8f RIGHTWARDS DOUBLE ARROW WITH STROKE +U+21D0 ⇐ e2 87 90 LEFTWARDS DOUBLE ARROW +U+21D1 ⇑ e2 87 91 UPWARDS DOUBLE ARROW +U+21D2 ⇒ e2 87 92 RIGHTWARDS DOUBLE ARROW +U+21D3 ⇓ e2 87 93 DOWNWARDS DOUBLE ARROW +U+21D4 ⇔ e2 87 94 LEFT RIGHT DOUBLE ARROW +U+21D5 ⇕ e2 87 95 UP DOWN DOUBLE ARROW +U+21D6 ⇖ e2 87 96 NORTH WEST DOUBLE ARROW +U+21D7 ⇗ e2 87 97 NORTH EAST DOUBLE ARROW +U+21D8 ⇘ e2 87 98 SOUTH EAST DOUBLE ARROW +U+21D9 ⇙ e2 87 99 SOUTH WEST DOUBLE ARROW +U+21DA ⇚ e2 87 9a LEFTWARDS TRIPLE ARROW +U+21DB ⇛ e2 87 9b RIGHTWARDS TRIPLE ARROW +U+21DC ⇜ e2 87 9c LEFTWARDS SQUIGGLE ARROW +U+21DD ⇝ e2 87 9d RIGHTWARDS SQUIGGLE ARROW +U+21DE ⇞ e2 87 9e UPWARDS ARROW WITH DOUBLE STROKE +U+21DF ⇟ e2 87 9f DOWNWARDS ARROW WITH DOUBLE STROKE +U+21E0 ⇠ e2 87 a0 LEFTWARDS DASHED ARROW +U+21E1 ⇡ e2 87 a1 UPWARDS DASHED ARROW +U+21E2 ⇢ e2 87 a2 RIGHTWARDS DASHED ARROW +U+21E3 ⇣ e2 87 a3 DOWNWARDS DASHED ARROW +U+21E4 ⇤ e2 87 a4 LEFTWARDS ARROW TO BAR +U+21E5 ⇥ e2 87 a5 RIGHTWARDS ARROW TO BAR +U+21E6 ⇦ e2 87 a6 LEFTWARDS WHITE ARROW +U+21E7 ⇧ e2 87 a7 UPWARDS WHITE ARROW +U+21E8 ⇨ e2 87 a8 RIGHTWARDS WHITE ARROW +U+21E9 ⇩ e2 87 a9 DOWNWARDS WHITE ARROW +U+21EA ⇪ e2 87 aa UPWARDS WHITE ARROW FROM BAR +U+21EB ⇫ e2 87 ab UPWARDS WHITE ARROW ON PEDESTAL +U+21EC ⇬ e2 87 ac UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR +U+21ED ⇭ e2 87 ad UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR +U+21EE ⇮ e2 87 ae UPWARDS WHITE DOUBLE ARROW +U+21EF ⇯ e2 87 af UPWARDS WHITE DOUBLE ARROW ON PEDESTAL +U+21F0 ⇰ e2 87 b0 RIGHTWARDS WHITE ARROW FROM WALL +U+21F1 ⇱ e2 87 b1 NORTH WEST ARROW TO CORNER +U+21F2 ⇲ e2 87 b2 SOUTH EAST ARROW TO CORNER +U+21F3 ⇳ e2 87 b3 UP DOWN WHITE ARROW +U+21F4 ⇴ e2 87 b4 RIGHT ARROW WITH SMALL CIRCLE +U+21F5 ⇵ e2 87 b5 DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW +U+21F6 ⇶ e2 87 b6 THREE RIGHTWARDS ARROWS +U+21F7 ⇷ e2 87 b7 LEFTWARDS ARROW WITH VERTICAL STROKE +U+21F8 ⇸ e2 87 b8 RIGHTWARDS ARROW WITH VERTICAL STROKE +U+21F9 ⇹ e2 87 b9 LEFT RIGHT ARROW WITH VERTICAL STROKE +U+21FA ⇺ e2 87 ba LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE +U+21FB ⇻ e2 87 bb RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE +U+21FC ⇼ e2 87 bc LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE +U+21FD ⇽ e2 87 bd LEFTWARDS OPEN-HEADED ARROW +U+21FE ⇾ e2 87 be RIGHTWARDS OPEN-HEADED ARROW +U+21FF ⇿ e2 87 bf LEFT RIGHT OPEN-HEADED ARROW +U+2200 ∀ e2 88 80 FOR ALL +U+2201 ∁ e2 88 81 COMPLEMENT +U+2202 ∂ e2 88 82 PARTIAL DIFFERENTIAL +U+2203 ∃ e2 88 83 THERE EXISTS +U+2204 ∄ e2 88 84 THERE DOES NOT EXIST +U+2205 ∅ e2 88 85 EMPTY SET +U+2206 ∆ e2 88 86 INCREMENT +U+2207 ∇ e2 88 87 NABLA +U+2208 ∈ e2 88 88 ELEMENT OF +U+2209 ∉ e2 88 89 NOT AN ELEMENT OF +U+220A ∊ e2 88 8a SMALL ELEMENT OF +U+220B ∋ e2 88 8b CONTAINS AS MEMBER +U+220C ∌ e2 88 8c DOES NOT CONTAIN AS MEMBER +U+220D ∍ e2 88 8d SMALL CONTAINS AS MEMBER +U+220E ∎ e2 88 8e END OF PROOF +U+220F ∏ e2 88 8f N-ARY PRODUCT +U+2210 ∐ e2 88 90 N-ARY COPRODUCT +U+2211 ∑ e2 88 91 N-ARY SUMMATION +U+2212 − e2 88 92 MINUS SIGN +U+2213 ∓ e2 88 93 MINUS-OR-PLUS SIGN +U+2214 ∔ e2 88 94 DOT PLUS +U+2215 ∕ e2 88 95 DIVISION SLASH +U+2216 ∖ e2 88 96 SET MINUS +U+2217 ∗ e2 88 97 ASTERISK OPERATOR +U+2218 ∘ e2 88 98 RING OPERATOR +U+2219 ∙ e2 88 99 BULLET OPERATOR +U+221A √ e2 88 9a SQUARE ROOT +U+221B ∛ e2 88 9b CUBE ROOT +U+221C ∜ e2 88 9c FOURTH ROOT +U+221D ∝ e2 88 9d PROPORTIONAL TO +U+221E ∞ e2 88 9e INFINITY +U+221F ∟ e2 88 9f RIGHT ANGLE +U+2220 ∠ e2 88 a0 ANGLE +U+2221 ∡ e2 88 a1 MEASURED ANGLE +U+2222 ∢ e2 88 a2 SPHERICAL ANGLE +U+2223 ∣ e2 88 a3 DIVIDES +U+2224 ∤ e2 88 a4 DOES NOT DIVIDE +U+2225 ∥ e2 88 a5 PARALLEL TO +U+2226 ∦ e2 88 a6 NOT PARALLEL TO +U+2227 ∧ e2 88 a7 LOGICAL AND +U+2228 ∨ e2 88 a8 LOGICAL OR +U+2229 ∩ e2 88 a9 INTERSECTION +U+222A ∪ e2 88 aa UNION +U+222B ∫ e2 88 ab INTEGRAL +U+222C ∬ e2 88 ac DOUBLE INTEGRAL +U+222D ∭ e2 88 ad TRIPLE INTEGRAL +U+222E ∮ e2 88 ae CONTOUR INTEGRAL +U+222F ∯ e2 88 af SURFACE INTEGRAL +U+2230 ∰ e2 88 b0 VOLUME INTEGRAL +U+2231 ∱ e2 88 b1 CLOCKWISE INTEGRAL +U+2232 ∲ e2 88 b2 CLOCKWISE CONTOUR INTEGRAL +U+2233 ∳ e2 88 b3 ANTICLOCKWISE CONTOUR INTEGRAL +U+2234 ∴ e2 88 b4 THEREFORE +U+2235 ∵ e2 88 b5 BECAUSE +U+2236 ∶ e2 88 b6 RATIO +U+2237 ∷ e2 88 b7 PROPORTION +U+2238 ∸ e2 88 b8 DOT MINUS +U+2239 ∹ e2 88 b9 EXCESS +U+223A ∺ e2 88 ba GEOMETRIC PROPORTION +U+223B ∻ e2 88 bb HOMOTHETIC +U+223C ∼ e2 88 bc TILDE OPERATOR +U+223D ∽ e2 88 bd REVERSED TILDE +U+223E ∾ e2 88 be INVERTED LAZY S +U+223F ∿ e2 88 bf SINE WAVE +U+2240 ≀ e2 89 80 WREATH PRODUCT +U+2241 ≁ e2 89 81 NOT TILDE +U+2242 ≂ e2 89 82 MINUS TILDE +U+2243 ≃ e2 89 83 ASYMPTOTICALLY EQUAL TO +U+2244 ≄ e2 89 84 NOT ASYMPTOTICALLY EQUAL TO +U+2245 ≅ e2 89 85 APPROXIMATELY EQUAL TO +U+2246 ≆ e2 89 86 APPROXIMATELY BUT NOT ACTUALLY EQUAL TO +U+2247 ≇ e2 89 87 NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO +U+2248 ≈ e2 89 88 ALMOST EQUAL TO +U+2249 ≉ e2 89 89 NOT ALMOST EQUAL TO +U+224A ≊ e2 89 8a ALMOST EQUAL OR EQUAL TO +U+224B ≋ e2 89 8b TRIPLE TILDE +U+224C ≌ e2 89 8c ALL EQUAL TO +U+224D ≍ e2 89 8d EQUIVALENT TO +U+224E ≎ e2 89 8e GEOMETRICALLY EQUIVALENT TO +U+224F ≏ e2 89 8f DIFFERENCE BETWEEN \ No newline at end of file diff --git a/tests/utf-8.txt b/tests/utf-8/utf-8.txt similarity index 100% rename from tests/utf-8.txt rename to tests/utf-8/utf-8.txt