summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOle Loots <ole@monochrom.net>2013-01-31 18:28:26 (GMT)
committer Ole Loots <ole@monochrom.net>2013-01-31 18:28:26 (GMT)
commit0703404654d2a40cacae2d94c6e0e22ca28b4acf (patch)
treebfdbe1e8952814f73a6b0e190ae0a77fd0cfc7bd
parent54f719aa960159c5b1978846223732c9669ca7fa (diff)
parent89856f55929907642013e45435b9d18cd1fafe36 (diff)
downloadnetsurf-mono/removing-windom-dependency.tar.gz
netsurf-mono/removing-windom-dependency.tar.bz2
Merge branch 'master' into mono/removing-windom-dependencymono/removing-windom-dependency
Conflicts: atari/toolbar.c
-rw-r--r--!NetSurf/!Boot,feb11
-rw-r--r--!NetSurf/ChkSprites,ffbbin0 -> 881 bytes
-rw-r--r--.gitignore1
-rw-r--r--Makefile.defaults4
-rw-r--r--Makefile.sources18
-rw-r--r--amiga/Makefile.target7
-rwxr-xr-xamiga/agclass/amigaguide_class.c346
-rwxr-xr-xamiga/agclass/amigaguide_class.h40
-rw-r--r--amiga/bitmap.c5
-rw-r--r--amiga/clipboard.c44
-rwxr-xr-xamiga/dist/Install18
-rwxr-xr-xamiga/dist/NetSurf.guide106
-rw-r--r--amiga/font.c6
-rwxr-xr-xamiga/gui.c84
-rwxr-xr-xamiga/gui.h2
-rwxr-xr-xamiga/gui_options.c30
-rwxr-xr-xamiga/help.c66
-rwxr-xr-xamiga/help.h36
-rwxr-xr-xamiga/plotters.c22
-rwxr-xr-xamiga/search.c42
-rw-r--r--amiga/theme.c6
-rw-r--r--atari/toolbar.c271
-rw-r--r--beos/scaffolding.cpp6
-rw-r--r--beos/window.cpp82
-rw-r--r--desktop/mouse.h40
-rw-r--r--desktop/textarea.c1069
-rw-r--r--desktop/textarea.h109
-rw-r--r--desktop/tree.c114
-rw-r--r--gtk/treeview.c2
-rw-r--r--image/png.c3
-rw-r--r--javascript/jsapi.h28
-rw-r--r--javascript/jsapi/htmldocument.bnd50
-rw-r--r--javascript/jsapi/htmlelement.bnd178
-rw-r--r--javascript/jsapi/nodelist.bnd41
-rw-r--r--render/textinput.c8
-rw-r--r--riscos/distribution/!System/310/Modules/Iconv,ffabin57476 -> 66240 bytes
-rw-r--r--riscos/distribution/3rdParty/Iconv/ReadMe2
-rw-r--r--riscos/distribution/3rdParty/Iconv/doc/ChangeLog7
-rw-r--r--riscos/filetype.c14
-rw-r--r--riscos/font.c25
-rw-r--r--riscos/gui.c39
-rw-r--r--riscos/save.c5
-rw-r--r--riscos/scripts/Run11
-rw-r--r--riscos/textselection.c232
-rw-r--r--riscos/textselection.h8
-rw-r--r--riscos/window.c11
-rw-r--r--test/js/dom-getElementsByTagName.html10
-rw-r--r--utils/corestrings.c3
-rw-r--r--utils/corestrings.h1
-rw-r--r--utils/nsurl.c3
-rw-r--r--utils/transtab1688
-rwxr-xr-xutils/tt2code60
-rw-r--r--utils/useragent.c10
-rw-r--r--utils/utils.h1
54 files changed, 2552 insertions, 2473 deletions
diff --git a/!NetSurf/!Boot,feb b/!NetSurf/!Boot,feb
index b1d9edc..1ba2ebd 100644
--- a/!NetSurf/!Boot,feb
+++ b/!NetSurf/!Boot,feb
@@ -43,14 +43,9 @@ If (("<NetSurf$Publisher>" = "") OR ("<NetSurf$ForceVars>" = "1")) Then Set NetS
If (("<NetSurf$Description>" = "") OR ("<NetSurf$ForceVars>" = "1")) Then Set NetSurf$Description "Web browser"
| NetSurf Sprites
-|
-| The sprite file used is based on the OS and SpriteExtend versions:
-| RO <> 5 and SpriteExtend < 1.50 uses !Sprites<nn>
-| RO <> 5 and SpriteExtend >= 1.50 uses ASprites<nn>
-| RO = 5 uses 5Sprites<nn>
-Set NetSurf$Sprites <NetSurf$Dir>.ASprites
-RMEnsure SpriteExtend 1.50 Set NetSurf$Sprites <NetSurf$Dir>.!Sprites
-If (("<Boot$OSVersion>" >= "500") AND ("<Boot$OSVersion>" < "600")) Then IconSprites <NetSurf$Dir>.5Sprites Else IconSprites <NetSurf$Sprites>
+Set NetSurf$Sprites "!Sprites"
+/<NetSurf$Dir>.ChkSprites
+IconSprites <NetSurf$Dir>.<NetSurf$Sprites>
Unset NetSurf$Sprites
| Acorn URI protocol
diff --git a/!NetSurf/ChkSprites,ffb b/!NetSurf/ChkSprites,ffb
new file mode 100644
index 0000000..52e456c
--- a/dev/null
+++ b/!NetSurf/ChkSprites,ffb
Binary files differ
diff --git a/.gitignore b/.gitignore
index 4002e54..84eca23 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,7 +15,6 @@ windows/res/preferences
test/nsurl
test/urldbtest
test/llcache
-utils/translit.c
utils/testament.h
codedocs
nsgtk
diff --git a/Makefile.defaults b/Makefile.defaults
index 7650b38..d8f5b9b 100644
--- a/Makefile.defaults
+++ b/Makefile.defaults
@@ -78,9 +78,9 @@ NETSURF_USE_HARU_PDF := NO
NETSURF_STRIP_BINARY := NO
# Template used for constructing the User Agent: string. The first two
-# replacements are major/minor version, second two are OS and architecture.
+# replacements are major/minor version, next is OS.
# Please don't be tempted to mention Mozilla here! Let's let that lie die.
-NETSURF_UA_FORMAT_STRING := "NetSurf/%d.%d (%s; %s)"
+NETSURF_UA_FORMAT_STRING := "NetSurf/%d.%d (%s)"
# Default home page, if one is not defined by the user. Note that this
# option does not apply to the RISC OS version, as it has its own local
diff --git a/Makefile.sources b/Makefile.sources
index 32db5e6..a38290d 100644
--- a/Makefile.sources
+++ b/Makefile.sources
@@ -74,21 +74,3 @@ S_BROWSER := $(addprefix desktop/,$(S_BROWSER))
content/fetchers/about.c: testament utils/testament.h
desktop/version.c: testament utils/testament.h
-# Some extra rules for building the transliteration table.
-ifeq ($(HOST),riscos)
-utils/translit.c: transtab
- $(VQ)echo "TRANSTAB: utils/translit.c"
- $(Q)dir utils
- $(Q)$(PERL) tt2code < transtab > translit.c
- $(Q)dir ^
-else
-utils/translit.c: transtab
- $(VQ)echo "TRANSTAB: utils/translit.c"
- $(Q)cd utils; $(PERL) tt2code < transtab > translit.c
-endif
-
-clean-intermediates:
- $(VQ)echo " CLEAN: intermediates"
- $(Q)$(RM) utils/translit.c
-
-CLEANS += clean-intermediates
diff --git a/amiga/Makefile.target b/amiga/Makefile.target
index f2c4299..dc79479 100644
--- a/amiga/Makefile.target
+++ b/amiga/Makefile.target
@@ -59,7 +59,7 @@ else
LDFLAGS += -L$(GCCSDK_INSTALL_ENV)/lib
ifeq ($(SUBTARGET),os3)
- LDFLAGS += -liconv
+ LDFLAGS += -lpbl -liconv
else
LDFLAGS += -lauto -lpbl -liconv
endif
@@ -75,11 +75,12 @@ EXETARGET := NetSurf
S_AMIGA := gui.c tree.c history.c hotlist.c schedule.c file.c \
thumbnail.c misc.c bitmap.c font.c filetype.c utf8.c login.c \
plotters.c object.c menu.c save_pdf.c arexx.c version.c \
- cookies.c context_menu.c clipboard.c \
+ cookies.c context_menu.c clipboard.c help.c font_scan.c \
launch.c search.c history_local.c download.c iff_dr2d.c \
sslcert.c gui_options.c print.c theme.c drag.c icon.c system_colour.c \
datatypes.c dt_picture.c dt_anim.c dt_sound.c plugin_hack.c \
- stringview/stringview.c stringview/urlhistory.c font_scan.c
+ stringview/stringview.c stringview/urlhistory.c \
+ agclass/amigaguide_class.c
S_AMIGA := $(addprefix amiga/,$(S_AMIGA))
# This is the final source build list
diff --git a/amiga/agclass/amigaguide_class.c b/amiga/agclass/amigaguide_class.c
new file mode 100755
index 0000000..dfac7ad
--- a/dev/null
+++ b/amiga/agclass/amigaguide_class.c
@@ -0,0 +1,346 @@
+/*
+ * AmigaGuide Class
+ * A BOOPSI class for displaying AmigaGuide files.
+ * by Daniel "Trixie" Jedlicka
+ */
+
+#undef __USE_INLINE__
+
+#include "amigaguide_class.h"
+
+struct localObjectData
+{
+ struct NewAmigaGuide nag;
+ struct AmigaGuideMsg *agm;
+ AMIGAGUIDECONTEXT agHandle;
+ uint32 agContextID;
+ uint32 agSignal;
+ BOOL agActive;
+};
+
+struct Library *AmigaGuideBase = NULL;
+struct AmigaGuideIFace *IAmigaGuide = NULL;
+
+
+/* ********************************** function prototypes ************************************ */
+
+static uint32 dispatchAGClass(Class *, Object *, Msg);
+BOOL freeAGClass(Class *);
+
+// class methods
+uint32 om_new(Class *, Object *, struct opSet *);
+uint32 om_dispose(Class *, Object *, Msg);
+uint32 om_set(Class *, Object *, struct opSet *);
+uint32 om_get(Class *, Object *, struct opGet *);
+uint32 agm_open(Class *, Object *, Msg);
+uint32 agm_close(Class *, Object *, Msg);
+
+
+/* *************************** class initialization and disposal ***************************** */
+
+
+Class *initAGClass(void)
+{
+ Class *cl = NULL;
+
+
+ // Open amigaguide.library and its interface.
+ if ( (AmigaGuideBase = IExec->OpenLibrary("amigaguide.library", 52)) )
+ {
+ if ( (IAmigaGuide = (struct AmigaGuideIFace *)IExec->GetInterface(AmigaGuideBase, "main", 1L, NULL)) )
+ {
+ if ( (cl = IIntuition->MakeClass(NULL, "rootclass", NULL, sizeof(struct localObjectData), 0)) )
+ {
+ cl->cl_Dispatcher.h_Entry = (HOOKFUNC)dispatchAGClass;
+ IIntuition->AddClass(cl);
+ }
+ else freeAGClass(NULL);
+ }
+ else freeAGClass(NULL);
+ }
+
+ return cl;
+
+}
+
+
+
+BOOL freeAGClass(Class *cl)
+{
+ BOOL retVal = FALSE;
+
+
+ // Close amigaguide.library and free the class.
+ if (IAmigaGuide) IExec->DropInterface((struct Interface *)IAmigaGuide);
+ if (AmigaGuideBase) IExec->CloseLibrary(AmigaGuideBase);
+ if (cl) retVal = IIntuition->FreeClass(cl);
+
+ return retVal;
+}
+
+
+
+/* ************************************** class dispatcher ************************************ */
+
+
+static uint32 dispatchAGClass(Class *cl, Object *o, Msg msg)
+{
+
+ switch (msg->MethodID)
+ {
+ case OM_NEW:
+ return om_new(cl, o, (struct opSet *)msg);
+
+ case OM_DISPOSE:
+ return om_dispose(cl, o, msg);
+
+ case OM_UPDATE:
+ case OM_SET:
+ return om_set(cl, o, (struct opSet *)msg);
+
+ case OM_GET:
+ return om_get(cl, o, (struct opGet *)msg);
+
+ case AGM_OPEN:
+ return agm_open(cl, o, msg);
+
+ case AGM_CLOSE:
+ return agm_close(cl, o, msg);
+
+ default:
+ return IIntuition->IDoSuperMethodA(cl, o, msg);
+ }
+
+}
+
+
+/* *************************************** class methods ************************************** */
+
+uint32 om_new(Class *cl, Object *o, struct opSet *msg)
+{
+ struct localObjectData *lod = NULL;
+ uint32 retVal = 0L;
+
+
+ if ( (retVal = IIntuition->IDoSuperMethodA(cl, o, (Msg)msg)) )
+ {
+ // Obtain pointer to our object's local instance data.
+ if ( (lod = (struct localObjectData *)INST_DATA(cl, retVal)) )
+ {
+ // Initialize values.
+ lod->agActive = FALSE;
+ lod->agHandle = NULL;
+ lod->agContextID = 0;
+ lod->nag.nag_Name = NULL;
+ lod->nag.nag_Screen = NULL;
+ lod->nag.nag_PubScreen = NULL;
+ lod->nag.nag_BaseName = NULL;
+ lod->nag.nag_Context = NULL;
+ lod->nag.nag_Client = NULL; // private, must be NULL!
+
+ // Set initial object attributes based on the tags from NewObject().
+ om_set(cl, (Object *)retVal, msg);
+ }
+ }
+
+ return retVal;
+
+}
+
+
+
+
+
+uint32 om_dispose(Class *cl, Object *o, Msg msg)
+{
+
+ // Close the document, should it still be opened.
+ agm_close(cl, o, msg);
+
+ // Let superclass dispose of the object.
+ return IIntuition->IDoSuperMethodA(cl, o, msg);
+
+}
+
+
+
+
+
+uint32 om_set(Class *cl, Object *o, struct opSet *msg)
+{
+ struct localObjectData *lod = (struct localObjectData *)INST_DATA(cl, o);
+ struct TagItem *tags, *ti;
+
+
+ tags = msg->ops_AttrList;
+
+ while ((ti = IUtility->NextTagItem (&tags)))
+ {
+ switch (ti->ti_Tag)
+ {
+ case AMIGAGUIDE_Name:
+ lod->nag.nag_Name = (STRPTR)ti->ti_Data;
+ lod->agActive = FALSE; // Database name has changed, we must setup the help system again.
+ break;
+
+ case AMIGAGUIDE_Screen:
+ lod->nag.nag_Screen = (struct Screen *)ti->ti_Data;
+ lod->agActive = FALSE; // Screen pointer has changed, we must setup the help system again.
+ break;
+
+ case AMIGAGUIDE_PubScreen:
+ lod->nag.nag_PubScreen = (STRPTR)ti->ti_Data;
+ lod->agActive = FALSE; // Pubscreen name has changed, we must setup the help system again.
+ break;
+
+ case AMIGAGUIDE_BaseName:
+ lod->nag.nag_BaseName = (STRPTR)ti->ti_Data;
+ lod->agActive = FALSE; // Application basename has changed, we must setup the help system again.
+ break;
+
+ case AMIGAGUIDE_ContextArray:
+ lod->nag.nag_Context = (STRPTR *)ti->ti_Data;
+ lod->agActive = FALSE; // Context array has changed, we must setup the help system again.
+ break;
+
+ case AMIGAGUIDE_ContextID:
+ lod->agContextID = (uint32)ti->ti_Data;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+ // Setup the help system, if not ready yet or needs changing.
+ if ( lod->agActive == FALSE )
+ {
+ // Shut down help system should it already be running.
+ if ( lod->agHandle ) agm_close(cl, o, (Msg)msg);
+
+ // (Re)establish the AmigaGuide context and open the database asynchronously.
+ if ( (lod->agHandle = IAmigaGuide->OpenAmigaGuideAsync(&(lod->nag), NULL)) )
+ {
+ if ( (lod->agSignal = IAmigaGuide->AmigaGuideSignal(lod->agHandle)) )
+ {
+ // Wait until the help system is up and running.
+ IExec->Wait(lod->agSignal);
+ while ( !(lod->agActive) )
+ {
+ while ( (lod->agm = IAmigaGuide->GetAmigaGuideMsg(lod->agHandle)) )
+ {
+ // The AmigaGuide process started OK.
+ if ( lod->agm->agm_Type == ActiveToolID ) lod->agActive = TRUE;
+
+ // Opening the guide file failed for some reason, continue as usual.
+ if ( lod->agm->agm_Type == ToolStatusID && lod->agm->agm_Pri_Ret ) lod->agActive = TRUE;
+
+ IAmigaGuide->ReplyAmigaGuideMsg(lod->agm);
+ }
+ }
+ }
+ }
+ }
+
+ return (uint32)lod->agHandle;
+
+}
+
+
+
+
+
+uint32 om_get(Class *cl, Object *o, struct opGet *msg)
+{
+ struct localObjectData *lod = (struct localObjectData *)INST_DATA(cl, o);
+ uint32 retVal = 0L;
+
+
+ switch (msg->opg_AttrID)
+ {
+ case AMIGAGUIDE_Name:
+ *(msg->opg_Storage) = (uint32)lod->nag.nag_Name;
+ retVal = 1;
+ break;
+
+ case AMIGAGUIDE_Screen:
+ *(msg->opg_Storage) = (uint32)lod->nag.nag_Screen;
+ retVal = 1;
+ break;
+
+ case AMIGAGUIDE_PubScreen:
+ *(msg->opg_Storage) = (uint32)lod->nag.nag_PubScreen;
+ retVal = 1;
+ break;
+
+ case AMIGAGUIDE_BaseName:
+ *(msg->opg_Storage) = (uint32)lod->nag.nag_BaseName;
+ retVal = 1;
+ break;
+
+ case AMIGAGUIDE_ContextArray:
+ *(msg->opg_Storage) = (uint32)lod->nag.nag_Context;
+ retVal = 1;
+ break;
+
+ case AMIGAGUIDE_ContextID:
+ *(msg->opg_Storage) = (uint32)lod->agContextID;
+ retVal = 1;
+ break;
+
+ default:
+ retVal = IIntuition->IDoSuperMethodA(cl, o, (Msg)msg);
+ }
+
+ return retVal;
+
+}
+
+
+
+
+
+uint32 agm_open(Class *cl, Object *o, Msg msg)
+{
+ struct localObjectData *lod = (struct localObjectData *)INST_DATA(cl, o);
+ uint32 retVal = 0;
+
+
+ if ( (lod->agHandle) && (lod->agActive) )
+ {
+ if ( lod->nag.nag_Context )
+ {
+ // A context node array is provided = open the current context node.
+ IAmigaGuide->SetAmigaGuideContext(lod->agHandle, lod->agContextID, NULL);
+ retVal = IAmigaGuide->SendAmigaGuideContext(lod->agHandle, NULL);
+ }
+ else
+ {
+ // No context array is provided = open the main node.
+ retVal = IAmigaGuide->SendAmigaGuideCmd(lod->agHandle, "LINK MAIN", TAG_DONE);
+ }
+ }
+
+ return retVal;
+}
+
+
+
+
+
+uint32 agm_close(Class *cl, Object *o, Msg msg)
+{
+ struct localObjectData *lod = (struct localObjectData *)INST_DATA(cl, o);
+
+
+ if ( lod->agHandle )
+ {
+ IAmigaGuide->CloseAmigaGuide(lod->agHandle);
+ lod->agHandle = NULL;
+ lod->agActive = FALSE;
+ }
+
+ return (uint32)lod->agHandle;
+
+}
diff --git a/amiga/agclass/amigaguide_class.h b/amiga/agclass/amigaguide_class.h
new file mode 100755
index 0000000..f122f35
--- a/dev/null
+++ b/amiga/agclass/amigaguide_class.h
@@ -0,0 +1,40 @@
+/*
+ * AmigaGuide Class
+ *
+ */
+
+#ifndef AMIGAGUIDE_CLASS_H
+#define AMIGAGUIDE_CLASS_H
+
+#include <exec/types.h>
+#include <intuition/classes.h>
+
+#include <classes/window.h>
+
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <proto/amigaguide.h>
+#include <proto/utility.h>
+
+
+
+// tag definitions
+#define AMIGAGUIDE_Dummy (TAG_USER+0x05000000)
+
+#define AMIGAGUIDE_Name (AMIGAGUIDE_Dummy + 1) // Name of the AmigaGuide database.
+#define AMIGAGUIDE_Screen (AMIGAGUIDE_Dummy + 2) // Pointer of the screen to open on.
+#define AMIGAGUIDE_PubScreen (AMIGAGUIDE_Dummy + 3) // Name of the public screen to open on.
+#define AMIGAGUIDE_BaseName (AMIGAGUIDE_Dummy + 4) // Basename of the application that opens the help file.
+#define AMIGAGUIDE_ContextArray (AMIGAGUIDE_Dummy + 5) // Context node array (must be NULL-terminated).
+#define AMIGAGUIDE_ContextID (AMIGAGUIDE_Dummy + 6) // Index value of the node to display.
+
+// method definition
+#define AGM_OPEN WM_OPEN
+#define AGM_CLOSE WM_CLOSE
+
+// function prototypes
+Class *initAGClass(void);
+BOOL freeAGClass(Class *);
+
+#endif // AMIGAGUIDE_CLASS_H
+
diff --git a/amiga/bitmap.c b/amiga/bitmap.c
index 3a2bc70..2fa8eb7 100644
--- a/amiga/bitmap.c
+++ b/amiga/bitmap.c
@@ -402,6 +402,7 @@ static struct BitMap *ami_bitmap_get_truecolour(struct bitmap *bitmap,int width,
if(GfxBase->LibNode.lib_Version >= 53) // AutoDoc says v52, but this function isn't in OS4.0, so checking for v53 (OS4.1)
{
+#ifdef __amigaos4__
uint32 comptype = COMPOSITE_Src;
uint32 flags = 0;
@@ -420,9 +421,9 @@ static struct BitMap *ami_bitmap_get_truecolour(struct bitmap *bitmap,int width,
COMPTAG_OffsetY,0,
COMPTAG_FriendBitMap,friendbm,
TAG_DONE);
+#endif
}
- else /* do it the old-fashioned way. This is pretty slow, but probably
- uses Composite() on OS4.1 anyway, so we're only saving a blit really. */
+ else /* Do it the old-fashioned way. This is pretty slow, even on OS4.1 */
{
bsa.bsa_SrcX = 0;
bsa.bsa_SrcY = 0;
diff --git a/amiga/clipboard.c b/amiga/clipboard.c
index 5e51efc..3897851 100644
--- a/amiga/clipboard.c
+++ b/amiga/clipboard.c
@@ -122,7 +122,7 @@ char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codeset, size
{
struct CollectionItem *ci_new = NULL, *ci_next, *ci_curr = ci;
size_t len = 0;
- char *text = NULL, *p, *clip;
+ char *text = NULL, *p;
/* Scan the collected chunks to find out the total size.
* If they are not in UTF-8, convert the chunks first and create a new CollectionItem list.
@@ -142,7 +142,7 @@ char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codeset, size
ci_next = ci_new;
}
- utf8_from_local_encoding(ci_curr->ci_Data, ci_curr->ci_Size, &ci_next->ci_Data);
+ utf8_from_local_encoding(ci_curr->ci_Data, ci_curr->ci_Size, (char **)&ci_next->ci_Data);
ci_next->ci_Size = strlen(ci_next->ci_Data);
len += ci_next->ci_Size;
break;
@@ -159,7 +159,7 @@ char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codeset, size
utf8_from_enc(ci_curr->ci_Data,
(const char *)ObtainCharsetInfo(DFCS_NUMBER,
codeset, DFCS_MIMENAME),
- ci_curr->ci_Size, &clip);
+ ci_curr->ci_Size, (char **)&ci_next->ci_Data);
ci_next->ci_Size = strlen(ci_next->ci_Data);
len += ci_next->ci_Size;
break;
@@ -175,9 +175,9 @@ char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codeset, size
p = text + len;
if(ci_new) {
- ci_curr = ci;
- } else {
ci_curr = ci_new;
+ } else {
+ ci_curr = ci;
}
do {
@@ -199,43 +199,27 @@ void gui_get_clipboard(char **buffer, size_t *length)
{
struct ContextNode *cn;
struct CollectionItem *ci = NULL;
+ struct StoredProperty *sp = NULL;
ULONG rlen=0,error;
- struct CSet cset;
+ struct CSet *cset;
LONG codeset = 0;
- cset.CodeSet = 0;
-
if(OpenIFF(iffh,IFFF_READ)) return;
if(CollectionChunk(iffh,ID_FTXT,ID_CHRS)) return;
- if(StopChunk(iffh,ID_FTXT,ID_CSET)) return;
+ if(PropChunk(iffh,ID_FTXT,ID_CSET)) return;
if(CollectionChunk(iffh,ID_FTXT,ID_UTF8)) return;
+ if(StopOnExit(iffh, ID_FTXT, ID_FORM)) return;
- while(1)
- {
- error = ParseIFF(iffh,IFFPARSE_SCAN);
- if(error == IFFERR_EOC) continue;
- else if(error) break;
-
- cn = CurrentChunk(iffh);
-
- if((cn)&&(cn->cn_Type == ID_FTXT)&&(cn->cn_ID == ID_CSET))
- {
- /* Ideally when we stop here, we need to convert all CHRS chunks up to this
- * point based on the previous codeset. However, for simplicity, we just
- * assume only one CSET chunk is present and only take note of the last
- * CSET chunk if there is more than one.
- */
-
- rlen = ReadChunkBytes(iffh, &cset, 32);
- if(cset.CodeSet == 1) codeset = 106;
- else codeset = cset.CodeSet;
- }
- }
+ error = ParseIFF(iffh,IFFPARSE_SCAN);
if(ci = FindCollection(iffh, ID_FTXT, ID_UTF8)) {
*buffer = ami_clipboard_cat_collection(ci, 106, length);
} else if(ci = FindCollection(iffh, ID_FTXT, ID_CHRS)) {
+ if(sp = FindProp(iffh, ID_FTXT, ID_CSET)) {
+ cset = (struct CSet *)sp->sp_Data;
+ codeset = cset->CodeSet;
+ }
*buffer = ami_clipboard_cat_collection(ci, codeset, length);
}
diff --git a/amiga/dist/Install b/amiga/dist/Install
index e320964..0191429 100755
--- a/amiga/dist/Install
+++ b/amiga/dist/Install
@@ -382,6 +382,10 @@
(set #user-options (tackon #user-dir "Choices"))
(set #options-exist (exists #user-options))
(set #searchengines-exist (exists (tackon @default-dest "Resources/SearchEngines")))
+(set #user-hotlist (tackon #user-dir "Hotlist"))
+(set #hotlist-exist (exists #user-hotlist))
+(set #old-hotlist (tackon @default-dest "Resources/Hotlist"))
+(set #old-hotlist-exist (exists #old-hotlist))
(set #aiss-theme "")
(if (= #options-exist 0)
@@ -411,6 +415,20 @@
)
)
+(if (= #hotlist-exist 0)
+ (if (= #old-hotlist-exist 1)
+ (
+ (copyfiles
+ (prompt "Migrating NetSurf 2.x Hotlist")
+ (help @copyfiles-help)
+ (source #old-hotlist)
+ (dest #user-dir)
+ (optional "askuser" "force" "oknodelete")
+ )
+ )
+ )
+)
+
(complete 18)
(if (>= osver 53)
diff --git a/amiga/dist/NetSurf.guide b/amiga/dist/NetSurf.guide
index 8759b2b..e38f9f7 100755
--- a/amiga/dist/NetSurf.guide
+++ b/amiga/dist/NetSurf.guide
@@ -7,14 +7,18 @@
http://www.netsurf-browser.org
@{" Change Log " link ChangeLog/Main}
-
@{" Licence " link COPYING/Main}
+
+@{" GUI " link GUI}
+@{" Preferences GUI " link Prefs}
+
@{" Command line options " link CLI}
@{" Options file " link Options}
@{" Fonts " link Fonts}
@{" ARexx port " link ARexx}
@{" OpenURL/URL Prefs " link OpenURL}
@{" Hotlist menu " link Hotlist}
+@{" Hotlist toolbar " link HotlistToolbar}
@{" Local MIME types " link MIMETypes}
@{" Keyboard controls " link Keyboard}
@@ -23,6 +27,81 @@ http://www.netsurf-browser.org
@{" Credits " link Contact}
@endnode
+@node GUI "Main window"
+NetSurf's main GUI consists of a toolbar across the top, an (optional) tab bar, an (optional) hotlist toolbar and the main browser area. It also encompasses a pull-down @{"menu" link Menu}.
+
+The toolbar buttons are, from left to right:
+@{b}Back@{ub} Go back one page in history. Right-clicking gives a menu showing the last ten pages visited.
+@{b}Forward@{ub} Go forward one page in history. Right-clicking gives a menu showing up to ten pages available.
+@{b}Stop@{ub} Stop loading the page.
+@{b}Reload@{ub} Reload the current page. Shift-clicking will reload all elements on the page.
+@{b}Home@{ub} Load the home page.
+
+The gadget to the right of the buttons is the URL bar to type web addresses into. On the far right is the search bar. Typing into here will search for the text using your default search provider (see preferences @{"Advanced tab" link Prefs-Advanced}.
+
+Below these is the (optional) @{"hotlist toolbar" link HotlistToolbar}.
+Below this is the (optional) tab bar. This usually only displays when more than one tab is open, but can be set in @{"preferences" link Prefs-Tabs} to be always present. At the far right is a button to open a new tab. On OS4.0 the current tab can be closed using the button on the far left. On OS4.1 the close gadget for the tab is embedded in the tab itself.
+
+The rest of the window is taken up with the @{"browser rendering area" link Browser}. This is where the pages visited will be displayed.
+@endnode
+
+@node Browser
+@toc GUI
+This is the main browser rendering area.
+
+Drag and drop is supported throughout, so files can be dropped onto text fields, text on pages can be highlighted and dragged to Workbench or text fields. Other elements can be saved by dragging them to Workbench with Ctrl or Shift held down.
+
+Note that dragging to Workbench only works when NetSurf is running on the Workbench screen.
+@endnode
+
+@node Menu "Menu"
+@toc GUI
+Project Browser Edit @{"Hotlist" link Hotlist} @{"ARexx" link arexx}
+
+@endnode
+
+@node Prefs "Preferences GUI"
+@{"General" link Prefs-General} @{"Display" link Prefs-Display} @{"Connection" link Prefs-Connection} @{"Rendering" link Prefs-Rendering} @{"Fonts" link Prefs-Fonts} @{"Cache" link Prefs-Cache} @{"Tabs" link Prefs-Tabs} @{"Advanced" link Prefs-Advanced} @{"Export" link Prefs-Export}
+@endnode
+
+@node Prefs-General "Prefs - General"
+@toc Prefs
+@endnode
+
+@node Prefs-Display "Prefs - Display"
+@toc Prefs
+@endnode
+
+@node Prefs-Connection "Prefs - Connection"
+@toc Prefs
+@endnode
+
+@node Prefs-Rendering "Prefs - Rendering"
+@toc Prefs
+@endnode
+
+@node Prefs-Fonts "Prefs - Fonts"
+@toc Prefs
+See @{"Fonts" link Fonts}
+@endnode
+
+@node Prefs-Cache "Prefs - Cache"
+@toc Prefs
+@endnode
+
+@node Prefs-Tabs "Prefs - Tabs"
+@toc Prefs
+@endnode
+
+@node Prefs-Advanced "Prefs - Advanced"
+@toc Prefs
+@endnode
+
+@node Prefs-Export "Prefs - Export"
+@toc Prefs
+This section contains options for exporting to PDF. It is not enabled in current builds of NetSurf.
+@endnode
+
@node cli "Command line options"
NetSurf URL/K,FORCE/S
@@ -44,13 +123,10 @@ There are a couple of Amiga-specific options which can only be changed directly
@{b}drag_save_icons@{ub} Enables displaying Workbench-style transparent icons under the pointer when performing drag saves (ctrl-drag of objects available if NetSurf is running on the Workbench screen) and text selection drags. If set to 0 the pointer style will change instead. OS 4.0 users may want to set this to 0 as icons will appear opaque and obscure the drop position.
@{b}cairo_renderer@{ub} Set rendering engine. -1 = palette-mapped (set automatically when required), 0 = graphics.library (default), 1 = Cairo/graphics.library mixed, 2 = Full Cairo.
@{b}monitor_aspect_x@{ub}/@{b}monitor_aspect_y@{ub} Correct aspect ratio for displays (default of 0 means "assume square pixels").
-@{b}screen_compositing@{ub} Use compositing on NetSurf's own screen. 0=disable, 1=enable, 2=default
+@{b}screen_compositing@{ub} Use compositing on NetSurf's own screen. 0=disable, 1=enable, 2=default (NB: This is indirectly modified by changing the "simple refresh" option in the GUI)
@{b}redraw_tile_size_x@{ub}/@{b}redraw_tile_size_y@{ub} Specify the size of the off-screen bitmap. Higher will speed up redraws at the expense of memory. 0 disables tiling (will use a bitmap at least the size of the screen NetSurf is running on)
-@{b}font_antialiasing@{ub} Switch text anti-aliasing on or off. Defaults to on in true-colour modes, but text rendering performance can be improved by setting to 0.
-@{b}window_simple_refresh@{ub} If set to 1, NetSurf will use SimpleRefresh rather than SmartRefresh windows. These have slower redraw but use less memory. Note that this setting has no noticeable effect if compositing is enabled. Defaults to 0 (SmartRefresh)
@{b}web_search_width@{ub} Defaults to 0. Larger values will increase the size of the web search gadget next to the URL bar.
-@{b}dithering_quality@{ub} Specify the dithering quality from all values supported by picture.datatype. Currently these are 0=None, 1=Normal, 2=High quality. Other values are undefined. This is only used when NetSurf is running in palette-mapped mode.
@{b}mask_alpha@{ub} Threshold to use when determining which alpha values to convert to full transparency (0 - 255, where 255 will convert even opaque pixels to transparent). Defaults to 50 (0x32). This is only used in palette-mapped modes where alpha blending is not currently supported.
@{b}url_file@{ub} Path to URL database file
@@ -61,7 +137,7 @@ There are a couple of Amiga-specific options which can only be changed directly
@endnode
@node Fonts
-The font to use for each font type can be defined in NetSurf's options. OS4 NetSurf supports soft styles for bold and italic, however designed fonts look better and it is highly recommend to set them as follows:
+The font to use for each font type can be defined in NetSurf's options. OS4 NetSurf supports soft styles for bold and italic, however designed fonts look better and it is highly recommended to set them as follows:
Within @{"TypeManager" system "SYS:System/TypeManager"} select a font being used by NetSurf and click on Modify.
On the Files tab, Font family section, choose the @{b}bold@{ub}, @{i}italic@{ui} and @{b}@{i}bold-italic@{ui}@{ub} version of the font.
@@ -194,7 +270,7 @@ Folders with no items in them will show up disabled in the menu. If they are na
eg.
-- Menu
+- Hotlist Menu
|
+- Netsurf
| |
@@ -216,6 +292,20 @@ Will look something like the following within the menu:
@endnode
+@node HotlistToolbar "Hotlist toolbar"
+A toolbar for frequently-accessed sites can be added to the main window. To do show, follow these steps:
+
+* Select Show Hotlist from the Hotlist menu
+The Hotlist window will be displayed.
+
+* Locate the "Hotlist toolbar" folder in the tree (NetSurf creates this when it starts up)
+
+* Move or create entries in this folder. Any entries directly inside the Hotlist toolbar folder will appear on the toolbar when the hotlist window is closed. If it is empty the toolbar will disappear to save space.
+
+Note that sub-folders are not currently supported on the toolbar.
+
+@endnode
+
@node mimetypes "Local MIME Types"
NetSurf determines the MIME types of local files primarily by checking the icon of the file. If the icon is not found it will check the default icon for the file type.
@@ -294,5 +384,5 @@ The default theme icon was adapted from the NetSurf logo by Marko K. Seppänen.
All other code and files are the same for all platforms and credited in the files and/or on the NetSurf website.
http://www.netsurf-browser.org
-The source code can be obtained from http://www.netsurf-browser.org SVN or (in the event the service is unavailable) chris@unsatisfactorysoftware.co.uk or any other of the NetSurf developers.
+The source code can be obtained from http://source.netsurf-browser.org or (in the event the service is unavailable) chris@unsatisfactorysoftware.co.uk or any other of the NetSurf developers.
@endnode
diff --git a/amiga/font.c b/amiga/font.c
index ffecf85..33f71a9 100644
--- a/amiga/font.c
+++ b/amiga/font.c
@@ -156,7 +156,7 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
for(i=0;i<len;i++)
{
- if (*utf16 < 0xD800 || 0xDFFF < *utf16)
+ if ((*utf16 < 0xD800) || (0xDFFF < *utf16))
utf16charlen = 1;
else
utf16charlen = 2;
@@ -263,7 +263,7 @@ bool nsfont_split(const plot_font_style_t *fstyle,
{
utf8len = utf8_char_byte_length(string+utf8clen);
- if (*utf16 < 0xD800 || 0xDFFF < *utf16)
+ if ((*utf16 < 0xD800) || (0xDFFF < *utf16))
utf16charlen = 1;
else
utf16charlen = 2;
@@ -722,7 +722,7 @@ ULONG ami_unicode_text(struct RastPort *rp, const char *string, ULONG length,
while(*utf16 != 0)
{
- if (*utf16 < 0xD800 || 0xDFFF < *utf16)
+ if ((*utf16 < 0xD800) || (0xDFFF < *utf16))
utf16charlen = 1;
else
utf16charlen = 2;
diff --git a/amiga/gui.c b/amiga/gui.c
index 4341270..eb5af26 100755
--- a/amiga/gui.c
+++ b/amiga/gui.c
@@ -53,6 +53,7 @@
#include "amiga/font.h"
#include "amiga/gui.h"
#include "amiga/gui_options.h"
+#include "amiga/help.h"
#include "amiga/history.h"
#include "amiga/history_local.h"
#include "amiga/hotlist.h"
@@ -385,6 +386,7 @@ void ami_open_resources(void)
TAG_DONE))) die(messages_get("NoMemory"));
ami_file_req_init();
+ //ami_help_init(NULL);
}
void ami_set_options(void)
@@ -475,15 +477,19 @@ void ami_set_options(void)
tree_set_icon_dir(strdup("ENV:Sys"));
-
nsoption_setnull_charp(arexx_dir, (char *)strdup("Rexx"));
-
nsoption_setnull_charp(arexx_startup, (char *)strdup("Startup.nsrx"));
-
nsoption_setnull_charp(arexx_shutdown, (char *)strdup("Shutdown.nsrx"));
if(!nsoption_int(window_width)) nsoption_set_int(window_width, 800);
if(!nsoption_int(window_height)) nsoption_set_int(window_height, 600);
+
+#ifndef __amigaos4__
+ nsoption_set_bool(download_notify, false);
+ nsoption_set_bool(context_menu, false);
+ nsoption_set_bool(font_antialiasing, false);
+ nsoption_set_bool(truecolour_mouse_pointers, false);
+#endif
}
void ami_amiupdate(void)
@@ -666,6 +672,8 @@ void ami_openscreen(void)
gui_system_colour_finalize();
gui_system_colour_init();
+
+ //ami_help_new_screen(scrn);
}
void ami_openscreenfirst(void)
@@ -1002,6 +1010,7 @@ int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie)
else nskey = KEY_TAB;
break;
case RAWKEY_F5:
+ case RAWKEY_HELP:
// don't translate
nskey = keycode;
break;
@@ -1823,6 +1832,10 @@ void ami_handle_msg(void)
if(browser_window_reload_available(gwin->bw))
browser_window_reload(gwin->bw,false);
break;
+
+ case RAWKEY_HELP: // help
+ //ami_help_open(AMI_HELP_GUI);
+ break;
}
}
}
@@ -2362,11 +2375,13 @@ void ami_quit_netsurf_delayed(void)
}
}
-void ami_gui_close_screen(struct Screen *scrn)
+void ami_gui_close_screen(struct Screen *scrn, BOOL locked_screen)
{
if(scrn == NULL) return;
if(CloseScreen(scrn)) return;
+ if(locked_screen == TRUE) return;
+ /* If this is our own screen, wait for visitor windows to close */
LOG(("Waiting for visitor windows to close..."));
do {
Delay(50);
@@ -2395,10 +2410,7 @@ void gui_quit(void)
FreeScreenDrawInfo(scrn, dri);
ami_close_fonts();
-
- /* If it is our public screen, close it or wait until the visitor windows leave */
- if(locked_screen == FALSE) ami_gui_close_screen(scrn);
-
+ ami_gui_close_screen(scrn, locked_screen);
FreeVec(nsscreentitle);
ami_context_menu_free();
@@ -2410,6 +2422,7 @@ void gui_quit(void)
FreeSysObject(ASOT_PORT,appport);
FreeSysObject(ASOT_PORT,sport);
+ //ami_help_free();
ami_file_req_free();
ami_openurl_close();
@@ -3591,7 +3604,7 @@ void gui_window_set_title(struct gui_window *g, const char *title)
}
}
-void ami_do_redraw_tiled(struct gui_window_2 *gwin,
+void ami_do_redraw_tiled(struct gui_window_2 *gwin, bool busy,
int left, int top, int width, int height,
int sx, int sy, struct IBox *bbox, struct redraw_context *ctx)
{
@@ -3630,24 +3643,22 @@ void ami_do_redraw_tiled(struct gui_window_2 *gwin,
if(width <= 0) return;
if(height <= 0) return;
-// printf("%ld %ld %ld %ld\n",left, top, width, height);
-
- ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
+ if(busy) ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
for(y = top; y < (top + height); y += tile_y_scale) {
clip.y0 = 0;
clip.y1 = nsoption_int(redraw_tile_size_y);
+ if(clip.y1 > height) clip.y1 = height;
if((((y - sy) * gwin->bw->scale) + clip.y1) > bbox->Height)
clip.y1 = bbox->Height - ((y - sy) * gwin->bw->scale);
for(x = left; x < (left + width); x += tile_x_scale) {
clip.x0 = 0;
clip.x1 = nsoption_int(redraw_tile_size_x);
+ if(clip.x1 > width) clip.x1 = width;
if((((x - sx) * gwin->bw->scale) + clip.x1) > bbox->Width)
clip.x1 = bbox->Width - ((x - sx) * gwin->bw->scale);
-//printf("%ld %ld -> %ld %ld\n",clip.x0 - (int)(x), clip.y0 - (int)(y), clip.x1, clip.y1);
-
if(browser_window_redraw(gwin->bw,
clip.x0 - (int)x,
clip.y0 - (int)y,
@@ -3670,7 +3681,7 @@ void ami_do_redraw_tiled(struct gui_window_2 *gwin,
}
}
- ami_reset_pointer(gwin);
+ if(busy) ami_reset_pointer(gwin);
}
@@ -3685,7 +3696,7 @@ void ami_do_redraw_tiled(struct gui_window_2 *gwin,
* \param y1 bottom-right co-ordinate (in document co-ordinates)
*/
-void ami_do_redraw_limits(struct gui_window *g, struct browser_window *bw,
+void ami_do_redraw_limits(struct gui_window *g, struct browser_window *bw, bool busy,
int x0, int y0, int x1, int y1)
{
ULONG xoffset,yoffset,width=800,height=600;
@@ -3716,7 +3727,7 @@ void ami_do_redraw_limits(struct gui_window *g, struct browser_window *bw,
GetAttr(SPACE_AreaBox, g->shared->objects[GID_BROWSER], (ULONG *)&bbox);
- ami_do_redraw_tiled(g->shared, x0, y0, x1 - x0, y1 - y0, sx, sy, bbox, &ctx);
+ ami_do_redraw_tiled(g->shared, busy, x0, y0, x1 - x0, y1 - y0, sx, sy, bbox, &ctx);
return;
}
@@ -3737,7 +3748,7 @@ void gui_window_update_box(struct gui_window *g, const struct rect *rect)
{
if(!g) return;
- ami_do_redraw_limits(g, g->shared->bw,
+ ami_do_redraw_limits(g, g->shared->bw, true,
rect->x0, rect->y0,
rect->x1, rect->y1);
}
@@ -3796,14 +3807,14 @@ void ami_do_redraw(struct gui_window_2 *gwin)
if(vcurrent>oldv) /* Going down */
{
- ami_do_redraw_limits(gwin->bw->window, gwin->bw,
+ ami_do_redraw_limits(gwin->bw->window, gwin->bw, true,
hcurrent, (height / gwin->bw->scale) + oldv - 1,
hcurrent + (width / gwin->bw->scale),
vcurrent + (height / gwin->bw->scale) + 1);
}
else if(vcurrent<oldv) /* Going up */
{
- ami_do_redraw_limits(gwin->bw->window, gwin->bw,
+ ami_do_redraw_limits(gwin->bw->window, gwin->bw, true,
hcurrent, vcurrent,
hcurrent + (width / gwin->bw->scale),
oldv);
@@ -3811,14 +3822,14 @@ void ami_do_redraw(struct gui_window_2 *gwin)
if(hcurrent>oldh) /* Going right */
{
- ami_do_redraw_limits(gwin->bw->window, gwin->bw,
+ ami_do_redraw_limits(gwin->bw->window, gwin->bw, true,
(width / gwin->bw->scale) + oldh , vcurrent,
hcurrent + (width / gwin->bw->scale),
vcurrent + (height / gwin->bw->scale));
}
else if(hcurrent<oldh) /* Going left */
{
- ami_do_redraw_limits(gwin->bw->window, gwin->bw,
+ ami_do_redraw_limits(gwin->bw->window, gwin->bw, true,
hcurrent, vcurrent,
oldh, vcurrent + (height / gwin->bw->scale));
}
@@ -3836,7 +3847,7 @@ void ami_do_redraw(struct gui_window_2 *gwin)
if(nsoption_bool(direct_render) == false)
{
- ami_do_redraw_tiled(gwin, hcurrent, vcurrent, width, height, hcurrent, vcurrent, bbox, &ctx);
+ ami_do_redraw_tiled(gwin, true, hcurrent, vcurrent, width, height, hcurrent, vcurrent, bbox, &ctx);
}
else
{
@@ -3882,39 +3893,42 @@ void ami_refresh_window(struct gui_window_2 *gwin)
sy = gwin->bw->window->scrolly;
GetAttr(SPACE_AreaBox, (Object *)gwin->objects[GID_BROWSER], (ULONG *)&bbox);
-
+ ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
+
BeginRefresh(gwin->win);
x0 = ((gwin->win->RPort->Layer->DamageList->bounds.MinX - bbox->Left) /
- browser_window_get_scale(gwin->bw)) + sx;
+ browser_window_get_scale(gwin->bw)) + sx - 1;
x1 = ((gwin->win->RPort->Layer->DamageList->bounds.MaxX - bbox->Left) /
- browser_window_get_scale(gwin->bw)) + sx;
+ browser_window_get_scale(gwin->bw)) + sx + 2;
y0 = ((gwin->win->RPort->Layer->DamageList->bounds.MinY - bbox->Top) /
- browser_window_get_scale(gwin->bw)) + sy;
+ browser_window_get_scale(gwin->bw)) + sy - 1;
y1 = ((gwin->win->RPort->Layer->DamageList->bounds.MaxY - bbox->Top) /
- browser_window_get_scale(gwin->bw)) + sy;
+ browser_window_get_scale(gwin->bw)) + sy + 2;
regrect = gwin->win->RPort->Layer->DamageList->RegionRectangle;
- ami_do_redraw_limits(gwin->bw->window, gwin->bw, x0, y0, x1, y1);
+ ami_do_redraw_limits(gwin->bw->window, gwin->bw, false, x0, y0, x1, y1);
while(regrect)
{
x0 = ((regrect->bounds.MinX - bbox->Left) /
- browser_window_get_scale(gwin->bw)) + sx;
+ browser_window_get_scale(gwin->bw)) + sx - 1;
x1 = ((regrect->bounds.MaxX - bbox->Left) /
- browser_window_get_scale(gwin->bw)) + sx;
+ browser_window_get_scale(gwin->bw)) + sx + 2;
y0 = ((regrect->bounds.MinY - bbox->Top) /
- browser_window_get_scale(gwin->bw)) + sy;
+ browser_window_get_scale(gwin->bw)) + sy - 1;
y1 = ((regrect->bounds.MaxY - bbox->Top) /
- browser_window_get_scale(gwin->bw)) + sy;
+ browser_window_get_scale(gwin->bw)) + sy + 2;
regrect = regrect->Next;
- ami_do_redraw_limits(gwin->bw->window, gwin->bw, x0, y0, x1, y1);
+ ami_do_redraw_limits(gwin->bw->window, gwin->bw, false, x0, y0, x1, y1);
}
EndRefresh(gwin->win, TRUE);
+
+ ami_reset_pointer(gwin);
}
void ami_get_hscroll_pos(struct gui_window_2 *gwin, ULONG *xs)
@@ -4332,7 +4346,7 @@ void gui_window_remove_caret(struct gui_window *g)
if((nsoption_bool(kiosk_mode) == false))
OffMenu(g->shared->win, AMI_MENU_PASTE);
- ami_do_redraw_limits(g, g->shared->bw, g->c_x, g->c_y,
+ ami_do_redraw_limits(g, g->shared->bw, false, g->c_x, g->c_y,
g->c_x + g->c_w + 1, g->c_y + g->c_h + 1);
g->c_h = 0;
diff --git a/amiga/gui.h b/amiga/gui.h
index ff46797..60ea7d9 100755
--- a/amiga/gui.h
+++ b/amiga/gui.h
@@ -147,8 +147,6 @@ void ami_get_msg(void);
void ami_close_all_tabs(struct gui_window_2 *gwin);
void ami_quit_netsurf(void);
void ami_do_redraw(struct gui_window_2 *g);
-void ami_do_redraw_limits(struct gui_window *g, struct browser_window *bw,
- int x0, int y0, int x1, int y1);
STRPTR ami_locale_langs(void);
int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie);
bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y);
diff --git a/amiga/gui_options.c b/amiga/gui_options.c
index e54ad15..bfee479 100755
--- a/amiga/gui_options.c
+++ b/amiga/gui_options.c
@@ -33,10 +33,12 @@
#include "amiga/font.h"
#include "amiga/gui.h"
#include "amiga/gui_options.h"
+#include "amiga/help.h"
+#include "amiga/theme.h"
+#include "amiga/utf8.h"
#include "utils/messages.h"
#include "desktop/browser_private.h"
#include "desktop/options.h"
-#include "amiga/utf8.h"
#include "desktop/searchweb.h"
#include <proto/window.h>
@@ -729,12 +731,14 @@ void ami_gui_opts_open(void)
LAYOUT_SpaceOuter, TRUE,
LAYOUT_BevelStyle, BVS_GROUP,
LAYOUT_Label, gadlab[GRP_OPTS_MOUSE],
+#ifdef __amigaos4__
LAYOUT_AddChild, gow->objects[GID_OPTS_PTRTRUE] = CheckBoxObject,
GA_ID, GID_OPTS_PTRTRUE,
GA_RelVerify, TRUE,
GA_Text, gadlab[GID_OPTS_PTRTRUE],
GA_Selected, nsoption_bool(truecolour_mouse_pointers),
CheckBoxEnd,
+#endif
LAYOUT_AddChild, gow->objects[GID_OPTS_PTROS] = CheckBoxObject,
GA_ID, GID_OPTS_PTROS,
GA_RelVerify, TRUE,
@@ -1070,6 +1074,7 @@ void ami_gui_opts_open(void)
LABEL_Text, gadlab[GID_OPTS_FONT_MINSIZE],
LabelEnd,
LayoutEnd,
+#ifdef __amigaos4__
LAYOUT_AddChild,VGroupObject,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_BevelStyle, BVS_GROUP,
@@ -1081,6 +1086,7 @@ void ami_gui_opts_open(void)
GA_Selected, nsoption_bool(font_antialiasing),
CheckBoxEnd,
LayoutEnd,
+#endif
LayoutEnd,
CHILD_WeightedHeight, 0,
LayoutEnd, // page vgroup
@@ -1205,6 +1211,7 @@ void ami_gui_opts_open(void)
GA_Text, gadlab[GID_OPTS_OVERWRITE],
GA_Selected, nsoption_bool(ask_overwrite),
CheckBoxEnd,
+#ifdef __amigaos4__
LAYOUT_AddChild, gow->objects[GID_OPTS_NOTIFY] = CheckBoxObject,
GA_ID, GID_OPTS_NOTIFY,
GA_RelVerify, TRUE,
@@ -1212,6 +1219,7 @@ void ami_gui_opts_open(void)
GA_Text, gadlab[GID_OPTS_NOTIFY],
GA_Selected, nsoption_bool(download_notify),
CheckBoxEnd,
+#endif
LayoutEnd,
LAYOUT_AddChild, gow->objects[GID_OPTS_DLDIR] = GetFileObject,
GA_ID, GID_OPTS_DLDIR,
@@ -1244,12 +1252,14 @@ void ami_gui_opts_open(void)
GA_Text, gadlab[GID_OPTS_CLOSE_NO_QUIT],
GA_Selected, nsoption_bool(close_no_quit),
CheckBoxEnd,
+#ifdef __amigaos4__
LAYOUT_AddChild, gow->objects[GID_OPTS_DOCKY] = CheckBoxObject,
GA_ID, GID_OPTS_DOCKY,
GA_RelVerify, TRUE,
GA_Text, gadlab[GID_OPTS_DOCKY],
GA_Selected, !nsoption_bool(hide_docky_icon),
CheckBoxEnd,
+#endif
LayoutEnd, // behaviour
CHILD_WeightedHeight, 0,
@@ -1292,12 +1302,14 @@ void ami_gui_opts_open(void)
LAYOUT_BevelStyle, BVS_GROUP,
LAYOUT_Label, gadlab[GRP_OPTS_MISC],
LAYOUT_SpaceOuter, TRUE,
+#ifdef __amigaos4__
LAYOUT_AddChild, gow->objects[GID_OPTS_CONTEXTMENU] = CheckBoxObject,
GA_ID, GID_OPTS_CONTEXTMENU,
GA_RelVerify, TRUE,
GA_Text, gadlab[GID_OPTS_CONTEXTMENU],
GA_Selected, nsoption_bool(context_menu),
CheckBoxEnd,
+#endif
LAYOUT_AddChild, gow->objects[GID_OPTS_FASTSCROLL] = CheckBoxObject,
GA_ID, GID_OPTS_FASTSCROLL,
GA_RelVerify, TRUE,
@@ -1582,10 +1594,12 @@ void ami_gui_opts_use(bool save)
}
GetAttr(GA_Selected,gow->objects[GID_OPTS_WIN_SIMPLE],(ULONG *)&data);
- if (data) {
+ if ((data == TRUE) && (nsoption_bool(window_simple_refresh) == false)) {
nsoption_set_bool(window_simple_refresh, true);
- } else {
+ nsoption_set_int(screen_compositing, 0);
+ } else if ((data == FALSE) && (nsoption_bool(window_simple_refresh) == true)) {
nsoption_set_bool(window_simple_refresh, false);
+ nsoption_set_int(screen_compositing, -1);
}
GetAttr(GETFILE_Drawer,gow->objects[GID_OPTS_THEME],(ULONG *)&data);
@@ -1887,6 +1901,16 @@ BOOL ami_gui_opts_event(void)
return TRUE;
break;
+ case WMHI_GADGETHELP:
+ if((result & WMHI_GADGETMASK) == 0) {
+ /* Pointer not over our window */
+ ami_help_open(AMI_HELP_MAIN);
+ } else {
+ /* TODO: Make this sensitive to the tab the user is currently on */
+ ami_help_open(AMI_HELP_PREFS);
+ }
+ break;
+
case WMHI_GADGETUP:
switch(result & WMHI_GADGETMASK)
{
diff --git a/amiga/help.c b/amiga/help.c
new file mode 100755
index 0000000..214e59d
--- a/dev/null
+++ b/amiga/help.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2013 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "amiga/help.h"
+
+/* AmigaGuide class */
+#include "amiga/agclass/amigaguide_class.h"
+
+Class *AmigaGuideClass = NULL;
+Object *AmigaGuideObject = NULL;
+
+/* This array needs to match the enum in help.h */
+STRPTR context_nodes[] = {
+ "Main",
+ "GUI",
+ "Prefs",
+ NULL
+};
+
+void ami_help_init(struct Screen *screen)
+{
+ AmigaGuideClass = initAGClass();
+
+ AmigaGuideObject = NewObject(AmigaGuideClass, NULL,
+ AMIGAGUIDE_Name, "PROGDIR:NetSurf.guide",
+ AMIGAGUIDE_BaseName, "NetSurf",
+ AMIGAGUIDE_Screen, screen,
+ AMIGAGUIDE_ContextArray, context_nodes,
+ AMIGAGUIDE_ContextID, AMI_HELP_MAIN,
+ TAG_DONE);
+}
+
+void ami_help_open(ULONG node)
+{
+ SetAttrs(AmigaGuideObject, AMIGAGUIDE_ContextID, node, TAG_DONE);
+ IDoMethod(AmigaGuideObject, AGM_OPEN, NULL);
+}
+
+void ami_help_free(void)
+{
+ if (AmigaGuideObject) DisposeObject(AmigaGuideObject);
+ if (AmigaGuideClass) freeAGClass(AmigaGuideClass);
+
+ AmigaGuideObject = NULL;
+ AmigaGuideClass = NULL;
+}
+
+void ami_help_new_screen(struct Screen *screen)
+{
+ SetAttrs(AmigaGuideObject, AMIGAGUIDE_Screen, screen, TAG_DONE);
+}
diff --git a/amiga/help.h b/amiga/help.h
new file mode 100755
index 0000000..4baa2a0
--- a/dev/null
+++ b/amiga/help.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2013 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef AMIGA_HELP_H
+#define AMIGA_HELP_H
+#include <exec/types.h>
+
+/* This enum needs to match context_array in help.c */
+enum {
+ AMI_HELP_MAIN,
+ AMI_HELP_GUI,
+ AMI_HELP_PREFS,
+};
+
+struct Screen;
+
+void ami_help_init(struct Screen *screen);
+void ami_help_open(ULONG node);
+void ami_help_free(void);
+void ami_help_new_screen(struct Screen *screen);
+#endif
diff --git a/amiga/plotters.c b/amiga/plotters.c
index 7347f06..ace3c3b 100755
--- a/amiga/plotters.c
+++ b/amiga/plotters.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008, 2009, 2012 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ * Copyright 2008-09, 2012-13 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -101,6 +101,18 @@ const struct plotter_table amiplot = {
.option_knockout = true,
};
+colour ami_abgr_to_argb(colour c) {
+ colour argb = 0x00000000;
+
+ /* NB: We force the alpha byte to be 0xff, as it is not set by the core. */
+ argb = 0xff000000 |
+ ((c & 0x00ff0000) >> 16) |
+ (c & 0x0000ff00) |
+ ((c & 0x000000ff) << 16);
+
+ return argb;
+}
+
#ifdef NS_AMIGA_CAIRO
void ami_cairo_set_colour(cairo_t *cr,colour c)
{
@@ -285,7 +297,7 @@ static void ami_plot_setapen(ULONG colour)
{
if(palette_mapped == false) {
SetRPAttrs(glob->rp, RPTAG_APenColor,
- p96EncodeColor(RGBFB_A8B8G8R8, colour),
+ ami_abgr_to_argb(colour),
TAG_DONE);
} else {
ULONG pen = ami_plot_obtain_pen(glob->shared_pens, colour);
@@ -297,7 +309,7 @@ static void ami_plot_setopen(ULONG colour)
{
if(palette_mapped == false) {
SetRPAttrs(glob->rp, RPTAG_OPenColor,
- p96EncodeColor(RGBFB_A8B8G8R8, colour),
+ ami_abgr_to_argb(colour),
TAG_DONE);
} else {
ULONG pen = ami_plot_obtain_pen(glob->shared_pens, colour);
@@ -695,6 +707,7 @@ static bool ami_bitmap(int x, int y, int width, int height, struct bitmap *bitma
if((GfxBase->LibNode.lib_Version >= 53) && (palette_mapped == false))
{
+#ifdef __amigaos4__
uint32 comptype = COMPOSITE_Src;
if(!bitmap->opaque)
comptype = COMPOSITE_Src_Over_Dest;
@@ -710,6 +723,7 @@ static bool ami_bitmap(int x, int y, int width, int height, struct bitmap *bitma
COMPTAG_OffsetX,x,
COMPTAG_OffsetY,y,
TAG_DONE);
+#endif
}
else
{
@@ -859,6 +873,7 @@ static void ami_bitmap_tile_hook(struct Hook *hook,struct RastPort *rp,struct Ba
if((GfxBase->LibNode.lib_Version >= 53) && (palette_mapped == false))
{
+#ifdef __amigaos4__
CompositeTags(COMPOSITE_Src_Over_Dest,bfbm->bm, rp->BitMap,
COMPTAG_Flags,COMPFLAG_IgnoreDestAlpha,
COMPTAG_DestX,bfmsg->Bounds.MinX,
@@ -870,6 +885,7 @@ static void ami_bitmap_tile_hook(struct Hook *hook,struct RastPort *rp,struct Ba
COMPTAG_OffsetX,xf,
COMPTAG_OffsetY,yf,
TAG_DONE);
+#endif
}
else
{
diff --git a/amiga/search.c b/amiga/search.c
index 1148f6d..f1fad60 100755
--- a/amiga/search.c
+++ b/amiga/search.c
@@ -174,6 +174,9 @@ void ami_search_open(struct gui_window *gwin)
fwin->node = AddObject(window_list,AMINS_FINDWINDOW);
fwin->node->objstruct = fwin;
gwin->shared->searchwin = fwin;
+
+ ActivateLayoutGadget((struct Gadget *)fwin->objects[GID_MAIN], fwin->win,
+ NULL, fwin->objects[GID_SEARCHSTRING]);
}
void ami_search_close(void)
@@ -202,6 +205,26 @@ BOOL ami_search_event(void)
case WMHI_GADGETUP:
switch(result & WMHI_GADGETMASK)
{
+ case GID_SEARCHSTRING:
+ browser_window_search_destroy_context(
+ fwin->gwin->shared->bw);
+ ami_search_set_forward_state(
+ true, NULL);
+ ami_search_set_back_state(
+ true, NULL);
+
+ RefreshSetGadgetAttrs((struct Gadget *)fwin->objects[GID_PREV],
+ fwin->win, NULL,
+ GA_Disabled, FALSE,
+ TAG_DONE);
+
+ RefreshSetGadgetAttrs((struct Gadget *)fwin->objects[GID_NEXT],
+ fwin->win, NULL,
+ GA_Disabled, FALSE,
+ TAG_DONE);
+
+ /* fall through */
+
case GID_NEXT:
search_insert = true;
flags = SEARCH_FLAG_FORWARDS |
@@ -228,25 +251,6 @@ BOOL ami_search_event(void)
flags,
ami_search_string());
ActivateWindow(fwin->gwin->shared->win);
- break;
-
- case GID_SEARCHSTRING:
- browser_window_search_destroy_context(
- fwin->gwin->shared->bw);
- ami_search_set_forward_state(
- true, NULL);
- ami_search_set_back_state(
- true, NULL);
-
- RefreshSetGadgetAttrs((struct Gadget *)fwin->objects[GID_PREV],
- fwin->win, NULL,
- GA_Disabled, FALSE,
- TAG_DONE);
-
- RefreshSetGadgetAttrs((struct Gadget *)fwin->objects[GID_NEXT],
- fwin->win, NULL,
- GA_Disabled, FALSE,
- TAG_DONE);
break;
}
break;
diff --git a/amiga/theme.c b/amiga/theme.c
index 65d2f51..fa058e0 100644
--- a/amiga/theme.c
+++ b/amiga/theme.c
@@ -265,6 +265,7 @@ void ami_init_mouse_pointers(void)
mouseptrobj[i] = NULL;
char ptrfname[1024];
+#ifdef __amigaos4__
if(nsoption_bool(truecolour_mouse_pointers))
{
ami_get_theme_filename((char *)&ptrfname,ptrs32[i], false);
@@ -316,6 +317,7 @@ void ami_init_mouse_pointers(void)
}
}
}
+#endif
if(!mouseptrobj[i])
{
@@ -370,8 +372,8 @@ void ami_mouse_pointers_free(void)
{
if(mouseptrbm[i])
{
- FreeRaster(mouseptrbm[i]->Planes[0],16,16);
- FreeRaster(mouseptrbm[i]->Planes[1],16,16);
+ FreeRaster(mouseptrbm[i]->Planes[0],32,32);
+ FreeRaster(mouseptrbm[i]->Planes[1],32,32);
FreeVec(mouseptrbm[i]);
}
}
diff --git a/atari/toolbar.c b/atari/toolbar.c
index 56d3b04..0f032b2 100644
--- a/atari/toolbar.c
+++ b/atari/toolbar.c
@@ -269,10 +269,73 @@ struct s_toolbar *toolbar_create(struct s_gui_win_root *owner)
assert(init == true);
+<<<<<<< HEAD
t = calloc(sizeof(struct s_toolbar), 1);
+=======
+static
+void __CDECL evnt_url_click( COMPONENT *c, long buff[8] )
+{
+ LGRECT work;
+ short pxy[4];
+ short mx, my, mb, kstat;
+ int old;
+ graf_mkstate( &mx, &my, &mb, &kstat );
+ struct gui_window * gw = (struct gui_window *)mt_CompDataSearch(&app, c, CDT_OWNER);
+ assert( gw != NULL );
+ CMP_TOOLBAR tb = gw->root->toolbar;
+ mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
+ mx = evnt.mx - (work.g_x + TOOLBAR_URL_MARGIN_LEFT);
+ my = evnt.my - (work.g_y + TOOLBAR_URL_MARGIN_TOP);
+
+ /* TODO: reset mouse state of browser window? */
+ /* select whole text when newly focused, otherwise set caret to end of text */
+ if( !window_url_widget_has_focus(gw) ) {
+ window_set_focus( gw, URL_WIDGET, (void*)&tb->url );
+ } else {
+ if( mb & 1 ) {
+ textarea_mouse_action( tb->url.textarea, BROWSER_MOUSE_DRAG_1,
+ mx, my );
+ short prev_x = mx;
+ short prev_y = my;
+ do{
+ if( abs(prev_x-mx) > 5 || abs(prev_y-my) > 5 ){
+ textarea_mouse_action( tb->url.textarea,
+ BROWSER_MOUSE_HOLDING_1, mx, my );
+ prev_x = mx;
+ prev_y = my;
+ if( tb->url.redraw ){
+ tb_url_redraw( gw );
+ }
+ }
+ graf_mkstate( &mx, &my, &mb, &kstat );
+ mx = mx - (work.g_x + TOOLBAR_URL_MARGIN_LEFT);
+ my = my - (work.g_y + TOOLBAR_URL_MARGIN_TOP);
+ }while( mb & 1 );
+ textarea_mouse_action( tb->url.textarea, BROWSER_MOUSE_HOVER, mx, my );
+ } else {
+ /* TODO: recognize click + shift key */
+ int mstate = BROWSER_MOUSE_PRESS_1;
+ if( (kstat & (K_LSHIFT|K_RSHIFT)) != 0 )
+ mstate = BROWSER_MOUSE_MOD_1;
+ if( evnt.nb_click == 2 ){
+ textarea_mouse_action( tb->url.textarea,
+ BROWSER_MOUSE_DOUBLE_CLICK | BROWSER_MOUSE_CLICK_1,
+ mx, my );
+ } else {
+ textarea_mouse_action( tb->url.textarea,
+ BROWSER_MOUSE_PRESS_1, mx, my );
+ }
+ }
+ }
+ // TODO: do not send an complete redraw!
+ ApplWrite( _AESapid, WM_REDRAW, gw->root->handle->handle,
+ work.g_x, work.g_y, work.g_w, work.g_h );
+}
+>>>>>>> master
assert(t);
+<<<<<<< HEAD
/* initialize the toolbar values: */
t->owner = owner;
t->style = 1;
@@ -282,6 +345,183 @@ struct s_toolbar *toolbar_create(struct s_gui_win_root *owner)
/* dublicate the form template: */
t->form = gemtk_obj_tree_copy(aes_toolbar);
+=======
+void tb_adjust_size( struct gui_window * gw )
+{
+ LGRECT work;
+ CMP_TOOLBAR t = gw->root->toolbar;
+
+ mt_CompGetLGrect( &app, t->url.comp, WF_WORKXYWH, &work);
+ work.g_w -= (TOOLBAR_URL_MARGIN_LEFT + TOOLBAR_URL_MARGIN_RIGHT);
+ /* do not overwrite the black border, because of that, add 1 */
+ work.g_h -= (TOOLBAR_URL_MARGIN_TOP + TOOLBAR_URL_MARGIN_BOTTOM+1);
+ textarea_set_dimensions( t->url.textarea, work.g_w, work.g_h );
+ tb_txt_request_redraw( t, 0,0, work.g_w-1, work.g_h-1);
+}
+
+static void __CDECL evnt_toolbar_redraw( COMPONENT *c, long buff[8], void *data )
+{
+ LGRECT work, clip;
+ short pxy[4];
+ const plot_style_t plot_style_background = {
+ .fill_type = PLOT_OP_TYPE_SOLID,
+ .fill_colour = toolbar_bg_color,
+ .stroke_type = PLOT_OP_TYPE_NONE
+ };
+
+ mt_CompGetLGrect(&app, c, WF_WORKXYWH, &work);
+ clip = work;
+ if( !rc_lintersect( (LGRECT*)&buff[4], &clip ) ) return;
+ if( work.g_y + work.g_h != clip.g_y + clip.g_h ) return;
+
+ vswr_mode(atari_plot_vdi_handle, MD_REPLACE );
+ vsl_color(atari_plot_vdi_handle, BLACK );
+ vsl_type(atari_plot_vdi_handle, 1 );
+ vsl_width(atari_plot_vdi_handle, 1 );
+ pxy[0] = clip.g_x;
+ pxy[1] = pxy[3] = work.g_y + work.g_h-1 ;
+ pxy[2] = clip.g_x + clip.g_w;
+ v_pline(atari_plot_vdi_handle, 2, (short*)&pxy );
+}
+
+
+static void tb_txt_request_redraw(void *data, int x, int y, int w, int h)
+{
+ LGRECT work;
+ if( data == NULL )
+ return;
+ CMP_TOOLBAR t = data;
+ if( t->url.redraw == false ){
+ t->url.redraw = true;
+ //t->redraw = true;
+ t->url.rdw_area.g_x = x;
+ t->url.rdw_area.g_y = y;
+ t->url.rdw_area.g_w = w;
+ t->url.rdw_area.g_h = h;
+ } else {
+ /* merge the redraw area to the new area.: */
+ int newx1 = x+w;
+ int newy1 = y+h;
+ int oldx1 = t->url.rdw_area.g_x + t->url.rdw_area.g_w;
+ int oldy1 = t->url.rdw_area.g_y + t->url.rdw_area.g_h;
+ t->url.rdw_area.g_x = MIN(t->url.rdw_area.g_x, x);
+ t->url.rdw_area.g_y = MIN(t->url.rdw_area.g_y, y);
+ t->url.rdw_area.g_w = ( oldx1 > newx1 ) ?
+ oldx1 - t->url.rdw_area.g_x : newx1 - t->url.rdw_area.g_x;
+ t->url.rdw_area.g_h = ( oldy1 > newy1 ) ?
+ oldy1 - t->url.rdw_area.g_y : newy1 - t->url.rdw_area.g_y;
+ }
+}
+
+
+static void tb_txt_callback(void *data, struct textarea_msg *msg)
+{
+ switch (msg->type) {
+ case TEXTAREA_MSG_DRAG_REPORT:
+ break;
+
+ case TEXTAREA_MSG_REDRAW_REQUEST:
+ tb_txt_request_redraw(data,
+ msg->data.redraw.x0, msg->data.redraw.y0,
+ msg->data.redraw.x1 - msg->data.redraw.x0,
+ msg->data.redraw.y1 - msg->data.redraw.y0);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void tb_url_redraw( struct gui_window * gw )
+{
+
+ CMP_TOOLBAR t = gw->root->toolbar;
+ if (t != NULL) {
+ if( t->url.redraw && ((atari_plot_flags & PLOT_FLAG_OFFSCREEN) == 0) ) {
+
+ const struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &atari_plotters
+ };
+ short todo[4];
+ LGRECT work;
+
+ mt_CompGetLGrect(&app, gw->root->toolbar->url.comp, WF_WORKXYWH, &work);
+ work.g_x += TOOLBAR_URL_MARGIN_RIGHT;
+ work.g_y += TOOLBAR_URL_MARGIN_LEFT;
+ work.g_w -= TOOLBAR_URL_MARGIN_RIGHT;
+ work.g_h -= TOOLBAR_URL_MARGIN_BOTTOM;
+
+ plot_set_dimensions( work.g_x, work.g_y, work.g_w, work.g_h );
+ if(plot_lock() == false)
+ return;
+
+ todo[0] = work.g_x;
+ todo[1] = work.g_y;
+ todo[2] = todo[0] + work.g_w-1;
+ todo[3] = todo[1] + work.g_h-1;
+ vs_clip(atari_plot_vdi_handle, 1, (short*)&todo );
+
+ if( wind_get(gw->root->handle->handle, WF_FIRSTXYWH,
+ &todo[0], &todo[1], &todo[2], &todo[3] )!=0 ) {
+ while (todo[2] && todo[3]) {
+
+ /* convert screen to relative coords: */
+ todo[0] = todo[0] - work.g_x;
+ todo[1] = todo[1] - work.g_y;
+ if( todo[0] < 0 ){
+ todo[2] = todo[2] + todo[0];
+ todo[0] = 0;
+ }
+ if( todo[1] < 0 ){
+ todo[3] = todo[3] + todo[1];
+ todo[1] = 0;
+ }
+
+ if (rc_intersect(&t->url.rdw_area,(GRECT *)&todo)) {
+ struct rect clip = {
+ .x0 = todo[0],
+ .y0 = todo[1],
+ .x1 = todo[0]+todo[2],
+ .y1 = todo[1]+todo[3]
+ };
+ textarea_redraw( t->url.textarea, 0, 0, 0xffffff, &clip, &ctx );
+ }
+ if (wind_get(gw->root->handle->handle, WF_NEXTXYWH,
+ &todo[0], &todo[1], &todo[2], &todo[3])==0) {
+ break;
+ }
+ }
+ } else {
+ plot_unlock();
+ return;
+ }
+ plot_unlock();
+ vs_clip(atari_plot_vdi_handle, 0, (short*)&todo);
+ t->url.redraw = false;
+ t->url.rdw_area.g_x = 65000;
+ t->url.rdw_area.g_y = 65000;
+ t->url.rdw_area.g_w = -1;
+ t->url.rdw_area.g_h = -1;
+ } else {
+ /* just copy stuff from the offscreen buffer */
+ }
+ }
+}
+
+CMP_TOOLBAR tb_create( struct gui_window * gw )
+{
+ int i;
+
+
+ CMP_TOOLBAR t = malloc( sizeof(struct s_toolbar) );
+ if( t == NULL )
+ return( NULL );
+
+ t->owner = gw;
+ t->style = 1;
+>>>>>>> master
/* count buttons and add them as components: */
@@ -300,10 +540,41 @@ struct s_toolbar *toolbar_create(struct s_gui_win_root *owner)
font_style_url.size =
toolbar_styles[t->style].font_height_pt * FONT_SIZE_SCALE;
+<<<<<<< HEAD
toolbar_get_grect(t, TOOLBAR_AREA_URL, &url_area);
url_area.g_h -= (TOOLBAR_URL_MARGIN_TOP + TOOLBAR_URL_MARGIN_BOTTOM);
t->url.textarea = textarea_create(300, url_area.g_h, 0, &font_style_url,
tb_txt_request_redraw, t);
+=======
+ int ta_height = toolbar_styles[t->style].height;
+ ta_height -= (TOOLBAR_URL_MARGIN_TOP + TOOLBAR_URL_MARGIN_BOTTOM);
+ textarea_setup ta_setup;
+ ta_setup.flags = TEXTAREA_INTERNAL_CARET;
+ ta_setup.width = 300;
+ ta_setup.height = ta_height;
+ ta_setup.pad_top = 0;
+ ta_setup.pad_right = 4;
+ ta_setup.pad_bottom = 0;
+ ta_setup.pad_left = 4;
+ ta_setup.border_width = 1;
+ ta_setup.border_col = 0x000000;
+ ta_setup.selected_text = 0xffffff;
+ ta_setup.selected_bg = 0x000000;
+ ta_setup.text = font_style_url;
+ ta_setup.text.foreground = 0x000000;
+ ta_setup.text.background = 0xffffff;
+ t->url.textarea = textarea_create( &ta_setup, tb_txt_callback, t );
+ if( t->url.textarea != NULL ){
+ textarea_set_text(t->url.textarea, "http://");
+ }
+
+ t->url.comp = (COMPONENT*)mt_CompCreate(&app, CLT_HORIZONTAL,
+ toolbar_styles[t->style].height, 1);
+ mt_CompEvntDataAttach( &app, t->url.comp, WM_REDRAW, evnt_url_redraw, t);
+ mt_CompEvntAttach( &app, t->url.comp, WM_XBUTTON, evnt_url_click );
+ mt_CompDataAttach( &app, t->url.comp, CDT_OWNER, gw );
+ mt_CompAttach( &app, t->comp, t->url.comp );
+>>>>>>> master
/* create the throbber widget: */
t->throbber.index = THROBBER_INACTIVE_INDEX;
diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp
index bcd9943..709795b 100644
--- a/beos/scaffolding.cpp
+++ b/beos/scaffolding.cpp
@@ -812,13 +812,13 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m
break;
}
case B_COPY:
- gui_copy_to_clipboard(browser_window_get_selection(bw));
+ browser_window_key_press(bw, KEY_COPY_SELECTION);
break;
case B_CUT:
- browser_window_key_press(bw, 24);
+ browser_window_key_press(bw, KEY_CUT_SELECTION);
break;
case B_PASTE:
- gui_paste_from_clipboard(scaffold->top_level, 0, 0);
+ browser_window_key_press(bw, KEY_PASTE);
break;
case B_SELECT_ALL:
LOG(("Selecting all text"));
diff --git a/beos/window.cpp b/beos/window.cpp
index f26ba91..d187e33 100644
--- a/beos/window.cpp
+++ b/beos/window.cpp
@@ -1662,12 +1662,6 @@ void gui_drag_save_selection(struct selection *s, struct gui_window *g)
void gui_start_selection(struct gui_window *g)
{
- current_selection.Truncate(0);
- while (current_selection_textruns.ItemAt(0)) {
- text_run *run = (text_run *)current_selection_textruns.RemoveItem(0L);
- delete run;
- }
-
if (!g->view->LockLooper())
return;
@@ -1680,9 +1674,12 @@ void gui_clear_selection(struct gui_window *g)
{
}
-void gui_paste_from_clipboard(struct gui_window *g, int x, int y)
+void gui_get_clipboard(char **buffer, size_t *length)
{
BMessage *clip;
+ *length = 0;
+ *buffer = NULL;
+
if (be_clipboard->Lock()) {
clip = be_clipboard->Data();
if (clip) {
@@ -1690,84 +1687,47 @@ void gui_paste_from_clipboard(struct gui_window *g, int x, int y)
int32 textlen;
if (clip->FindData("text/plain", B_MIME_TYPE,
(const void **)&text, &textlen) >= B_OK) {
- browser_window_paste_text(g->bw,text,textlen,true);
+ *buffer = (char *)malloc(textlen);
+ *length = textlen;
+ memcpy(*buffer, text, textlen);
}
}
be_clipboard->Unlock();
}
}
-bool gui_empty_clipboard(void)
-{
- current_selection.Truncate(0);
- while (current_selection_textruns.ItemAt(0)) {
- text_run *run = (text_run *)current_selection_textruns.RemoveItem(0L);
- delete run;
- }
- return true;
-}
-
-bool gui_add_to_clipboard(const char *text, size_t length, bool space,
- const plot_font_style_t *fstyle)
-{
- BString s;
- BFont font;
- text_run *run = new text_run;
-
- nsbeos_style_to_font(font, fstyle);
- run->offset = current_selection.Length();
- run->font = font;
- run->color = nsbeos_rgb_colour(fstyle->foreground);
- current_selection_textruns.AddItem(run);
-
- s.SetTo(text, length);
- current_selection << s;
- if (space)
- current_selection << " ";
- return true;
-}
-
-bool gui_commit_clipboard(void)
+void gui_set_clipboard(const char *buffer, size_t length,
+ nsclipboard_styles styles[], int n_styles)
{
BMessage *clip;
- if (current_selection.Length() == 0)
- return true;
-
if (be_clipboard->Lock()) {
be_clipboard->Clear();
clip = be_clipboard->Data();
if (clip) {
- clip->AddData("text/plain", B_MIME_TYPE,
- current_selection.String(),
- current_selection.Length());
+ clip->AddData("text/plain", B_MIME_TYPE, buffer, length);
+
int arraySize = sizeof(text_run_array) +
- current_selection_textruns.CountItems() * sizeof(text_run);
+ n_styles * sizeof(text_run);
text_run_array *array = (text_run_array *)malloc(arraySize);
- array->count = current_selection_textruns.CountItems();
- for (int i = 0; i < array->count; i++)
- memcpy(&array->runs[i], current_selection_textruns.ItemAt(i),
- sizeof(text_run));
+ array->count = n_styles;
+ for (int i = 0; i < n_styles; i++) {
+ BFont font;
+ nsbeos_style_to_font(font, &styles[i].style);
+ array->runs[i].offset = styles[i].start;
+ array->runs[i].font = font;
+ array->runs[i].color =
+ nsbeos_rgb_colour(styles[i].style.foreground);
+ }
clip->AddData("application/x-vnd.Be-text_run_array", B_MIME_TYPE,
array, arraySize);
free(array);
-
- gui_empty_clipboard();
be_clipboard->Commit();
}
be_clipboard->Unlock();
}
- return true;
}
-bool gui_copy_to_clipboard(struct selection *s)
-{
- if (s->defined && selection_copy_to_clipboard(s))
- gui_commit_clipboard();
- return true;
-}
-
-
void gui_window_get_dimensions(struct gui_window *g, int *width, int *height,
bool scaled)
{
diff --git a/desktop/mouse.h b/desktop/mouse.h
index 42603a6..042db23 100644
--- a/desktop/mouse.h
+++ b/desktop/mouse.h
@@ -28,8 +28,12 @@
/* Mouse state. 1 is primary mouse button (e.g. Select on RISC OS).
* 2 is secondary mouse button (e.g. Adjust on RISC OS). */
typedef enum {
- BROWSER_MOUSE_PRESS_1 = 1, /* button 1 pressed */
- BROWSER_MOUSE_PRESS_2 = 2, /* button 2 pressed */
+ BROWSER_MOUSE_HOVER = 0, /* No mouse buttons pressed,
+ * May be used to indicate
+ * hover or end of drag. */
+
+ BROWSER_MOUSE_PRESS_1 = (1 << 0), /* button 1 pressed */
+ BROWSER_MOUSE_PRESS_2 = (1 << 1), /* button 2 pressed */
/* note: click meaning is different for
* different front ends. On RISC OS, it
@@ -40,27 +44,29 @@ typedef enum {
* click is fired when the mouse button
* is released, if the operation wasn't
* a drag. */
- BROWSER_MOUSE_CLICK_1 = 4, /* button 1 clicked. */
- BROWSER_MOUSE_CLICK_2 = 8, /* button 2 clicked. */
- BROWSER_MOUSE_DOUBLE_CLICK = 16, /* button 1 double clicked */
+ BROWSER_MOUSE_CLICK_1 = (1 << 2), /* button 1 clicked. */
+ BROWSER_MOUSE_CLICK_2 = (1 << 3), /* button 2 clicked. */
+
+ BROWSER_MOUSE_DOUBLE_CLICK = (1 << 4), /* button 1 double clicked */
- BROWSER_MOUSE_DRAG_1 = 32, /* start of button 1 drag operation */
- BROWSER_MOUSE_DRAG_2 = 64, /* start of button 2 drag operation */
+ BROWSER_MOUSE_DRAG_1 = (1 << 5), /* start of button 1 drag */
+ BROWSER_MOUSE_DRAG_2 = (1 << 6), /* start of button 2 drag */
- BROWSER_MOUSE_DRAG_ON = 128, /* a drag operation was started and
- * a mouse button is still pressed */
+ BROWSER_MOUSE_DRAG_ON = (1 << 7), /* a drag operation was started
+ * and a mouse button is still
+ * pressed */
- BROWSER_MOUSE_HOLDING_1 = 256, /* while button 1 drag is in progress */
- BROWSER_MOUSE_HOLDING_2 = 512, /* while button 2 drag is in progress */
+ BROWSER_MOUSE_HOLDING_1 = (1 << 8), /* during button 1 drag */
+ BROWSER_MOUSE_HOLDING_2 = (1 << 9), /* during button 2 drag */
- BROWSER_MOUSE_MOD_1 = 1024, /* primary modifier key pressed
- * (eg. Shift) */
- BROWSER_MOUSE_MOD_2 = 2048, /* secondary modifier key pressed
- * (eg. Ctrl) */
- BROWSER_MOUSE_MOD_3 = 4096 /* secondary modifier key pressed
- * (eg. Alt) */
+ BROWSER_MOUSE_MOD_1 = (1 << 10), /* 1st modifier key pressed
+ * (eg. Shift) */
+ BROWSER_MOUSE_MOD_2 = (1 << 11), /* 2nd modifier key pressed
+ * (eg. Ctrl) */
+ BROWSER_MOUSE_MOD_3 = (1 << 12) /* 3rd modifier key pressed
+ * (eg. Alt) */
} browser_mouse_state;
diff --git a/desktop/textarea.c b/desktop/textarea.c
index 31effdc..2c7b748 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -29,30 +29,13 @@
#include "desktop/textarea.h"
#include "desktop/textinput.h"
#include "desktop/plotters.h"
+#include "desktop/scrollbar.h"
#include "render/font.h"
#include "utils/log.h"
#include "utils/utf8.h"
#include "utils/utils.h"
-#define MARGIN_LEFT 4
-#define MARGIN_RIGHT 4
#define CARET_COLOR 0x0000FF
-/* background color for readonly textarea */
-#define READONLY_BG 0xD9D9D9
-#define BACKGROUND_COL 0xFFFFFF
-#define BORDER_COLOR 0x000000
-#define SELECTION_COL 0xFFDDDD
-
-static plot_style_t pstyle_fill_selection = {
- .fill_type = PLOT_OP_TYPE_SOLID,
- .fill_colour = SELECTION_COL,
-};
-
-static plot_style_t pstyle_stroke_border = {
- .stroke_type = PLOT_OP_TYPE_SOLID,
- .stroke_colour = BORDER_COLOR,
- .stroke_width = 1,
-};
static plot_style_t pstyle_stroke_caret = {
.stroke_type = PLOT_OP_TYPE_SOLID,
@@ -64,47 +47,65 @@ struct line_info {
unsigned int b_start; /**< Byte offset of line start */
unsigned int b_length; /**< Byte length of line */
};
+struct textarea_drag {
+ textarea_drag_type type;
+ union {
+ struct scrollbar* scrollbar;
+ } data;
+};
struct textarea {
- int scroll_x, scroll_y; /**< scroll offsets of the textarea
- * content
- */
+ int scroll_x, scroll_y; /**< scroll offsets for the textarea */
+
+ struct scrollbar *bar_x; /**< Horizontal scroll. */
+ struct scrollbar *bar_y; /**< Vertical scroll. */
unsigned int flags; /**< Textarea flags */
int vis_width; /**< Visible width, in pixels */
int vis_height; /**< Visible height, in pixels */
+ int pad_top; /**< Top padding, inside border, in pixels */
+ int pad_right; /**< Right padding, inside border, in pixels */
+ int pad_bottom; /**< Bottom padding, inside border, in pixels */
+ int pad_left; /**< Left padding, inside border, in pixels */
+
+ int border_width; /**< Border width, in pixels */
+ colour border_col; /**< Border colour */
+
+ plot_font_style_t fstyle; /**< Text style, inc. textarea bg col */
+ plot_font_style_t sel_fstyle; /**< Selected text style */
+
char *text; /**< UTF-8 text */
unsigned int text_alloc; /**< Size of allocated text */
unsigned int text_len; /**< Length of text, in bytes */
unsigned int text_utf8_len; /**< Length of text, in characters
- * without the trailing NUL */
+ * without the trailing NULL */
struct {
int line; /**< Line caret is on */
- int char_off; /**< Character index of caret within the
- * specified line */
+ int char_off; /**< Character index of caret on line */
} caret_pos;
int caret_x; /**< cached X coordinate of the caret */
int caret_y; /**< cached Y coordinate of the caret */
- int sel_start; /**< Character index of sel start(inclusive) */
- int sel_end; /**< Character index of sel end(exclusive) */
-
- plot_font_style_t fstyle; /**< Text style */
+ int sel_start; /**< Character index of sel start (inclusive) */
+ int sel_end; /**< Character index of sel end (exclusive) */
+ int h_extent; /**< Width of content in px */
+ int v_extent; /**< Height of content in px */
int line_count; /**< Count of lines */
#define LINE_CHUNK_SIZE 16
struct line_info *lines; /**< Line info array */
int line_height; /**< Line height obtained from style */
/** Callback function for a redraw request */
- textarea_redraw_request_callback redraw_request;
+ textarea_client_callback callback;
- void *data; /** < Callback data for both callback functions */
+ void *data; /**< Client data for callback */
- int drag_start_char; /**< Character index of drag start */
+ int drag_start_char; /**< Character index of drag start */
+ struct textarea_drag drag_info; /**< Drag information */
};
@@ -161,6 +162,7 @@ static void textarea_normalise_text(struct textarea *ta,
static bool textarea_select(struct textarea *ta, int c_start, int c_end)
{
int swap;
+ struct textarea_msg msg;
/* Ensure start is the beginning of the selection */
if (c_start > c_end) {
@@ -169,10 +171,20 @@ static bool textarea_select(struct textarea *ta, int c_start, int c_end)
c_end = swap;
}
+ if (ta->sel_start == c_start && ta->sel_end == c_end)
+ return true;
+
ta->sel_start = c_start;
ta->sel_end = c_end;
- ta->redraw_request(ta->data, 0, 0, ta->vis_width, ta->vis_height);
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
+ msg.data.redraw.x0 = 0;
+ msg.data.redraw.y0 = 0;
+ msg.data.redraw.x1 = ta->vis_width;
+ msg.data.redraw.y1 = ta->vis_height;
+
+ ta->callback(ta->data, &msg);
return true;
}
@@ -237,51 +249,79 @@ static bool textarea_select_fragment(struct textarea * ta)
*/
static bool textarea_scroll_visible(struct textarea *ta)
{
- int x0, x1, y0, y1, x, y;
- int index, b_off;
+ int x0, x1, y0, y1; /* area we want caret inside */
+ int xc, yc; /* area centre */
+ int x, y; /* caret pos */
+ int xs = ta->scroll_x;
+ int ys = ta->scroll_y;
bool scrolled = false;
if (ta->caret_pos.char_off == -1)
return false;
- x0 = MARGIN_LEFT;
- x1 = ta->vis_width - MARGIN_RIGHT;
+ x0 = ta->border_width + ta->pad_left;
+ x1 = ta->vis_width - (ta->border_width + ta->pad_right);
y0 = 0;
- y1 = ta->vis_height;
-
- index = textarea_get_caret(ta);
-
- /* find byte offset of caret position */
- for (b_off = 0; index-- > 0;
- b_off = utf8_next(ta->text, ta->text_len, b_off))
- ; /* do nothing */
-
- nsfont.font_width(&ta->fstyle,
- ta->text + ta->lines[ta->caret_pos.line].b_start,
- b_off - ta->lines[ta->caret_pos.line].b_start,
- &x);
-
- /* top-left of caret */
- x += MARGIN_LEFT - ta->scroll_x;
- y = ta->line_height * ta->caret_pos.line - ta->scroll_y;
+ y1 = ta->vis_height - 2 * ta->border_width -
+ ta->pad_top - ta->pad_bottom;
+ xc = (x1 - x0) / 2 + x0;
+ yc = (y1 - y0) / 2 + y0;
+
+ x = ta->caret_x - xs;
+ y = ta->caret_y + ta->line_height / 2 - ys;
+
+ /* horizontal scroll; centre caret */
+ xs += x - xc;
+
+ /* force back into range */
+ if (xs < 0)
+ xs = 0;
+ else if (xs > ta->h_extent - (x1 - x0))
+ xs = ta->h_extent - (x1 - x0);
+
+ /* If scrolled, set new pos. */
+ if (xs != ta->scroll_x && ta->bar_x != NULL) {
+ scrollbar_set(ta->bar_x, xs, false);
+ xs = scrollbar_get_offset(ta->bar_x);
+ if (xs != ta->scroll_x) {
+ ta->scroll_x = xs;
+ scrolled = true;
+ }
- /* check and change vertical scroll */
- if (y < y0) {
- ta->scroll_y -= y0 - y;
+ } else if (ta->flags & TEXTAREA_MULTILINE && ta->bar_x == NULL &&
+ ta->scroll_x != 0) {
+ ta->scroll_x = 0;
scrolled = true;
- } else if (y + ta->line_height > y1) {
- ta->scroll_y += y + ta->line_height - y1;
+
+ } else if (xs != ta->scroll_x && !(ta->flags & TEXTAREA_MULTILINE)) {
+ ta->scroll_x = xs;
scrolled = true;
}
+ /* check and change vertical scroll */
+ if (ta->flags & TEXTAREA_MULTILINE) {
+ /* vertical scroll; centre caret */
+ ys += y - yc;
+
+ /* force back into range */
+ if (ys < 0)
+ ys = 0;
+ else if (ys > ta->v_extent - (y1 - y0))
+ ys = ta->v_extent - (y1 - y0);
+
+ /* If scrolled, set new pos. */
+ if (ys != ta->scroll_y && ta->bar_y != NULL) {
+ scrollbar_set(ta->bar_y, ys, false);
+ ys = scrollbar_get_offset(ta->bar_y);
+ if (ys != ta->scroll_y) {
+ ta->scroll_y = ys;
+ scrolled = true;
+ }
- /* check and change horizontal scroll */
- if (x < x0) {
- ta->scroll_x -= x0 - x ;
- scrolled = true;
- } else if (x > x1 - 1) {
- ta->scroll_x += x - (x1 - 1);
- scrolled = true;
+ } else if (ta->bar_y == NULL && ta->scroll_y != 0) {
+ ta->scroll_y = 0;
+ scrolled = true;
+ }
}
return scrolled;
@@ -289,25 +329,80 @@ static bool textarea_scroll_visible(struct textarea *ta)
/**
+ * Callback for scrollbar widget.
+ */
+static void textarea_scrollbar_callback(void *client_data,
+ struct scrollbar_msg_data *scrollbar_data)
+{
+ struct textarea *ta = client_data;
+ struct textarea_msg msg;
+
+ switch(scrollbar_data->msg) {
+ case SCROLLBAR_MSG_MOVED:
+ /* Scrolled; redraw everything */
+ ta->scroll_x = scrollbar_get_offset(ta->bar_x);
+ ta->scroll_y = scrollbar_get_offset(ta->bar_y);
+
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
+ msg.data.redraw.x0 = 0;
+ msg.data.redraw.y0 = 0;
+ msg.data.redraw.x1 = ta->vis_width;
+ msg.data.redraw.y1 = ta->vis_height;
+
+ ta->callback(ta->data, &msg);
+ break;
+
+ case SCROLLBAR_MSG_SCROLL_START:
+ ta->drag_info.type = TEXTAREA_DRAG_SCROLLBAR;
+ ta->drag_info.data.scrollbar = scrollbar_data->scrollbar;
+
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_DRAG_REPORT;
+ msg.data.drag = ta->drag_info.type;
+
+ /* Tell client we're handling a drag */
+ ta->callback(ta->data, &msg);
+ break;
+
+ case SCROLLBAR_MSG_SCROLL_FINISHED:
+ ta->drag_info.type = TEXTAREA_DRAG_NONE;
+
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_DRAG_REPORT;
+ msg.data.drag = ta->drag_info.type;
+
+ /* Tell client we finished handling the drag */
+ ta->callback(ta->data, &msg);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
+/**
* Reflow a text area from the given line onwards
*
* \param ta Text area to reflow
- * \param line Line number to begin reflow on
+ * \param start Line number to begin reflow on
* \return true on success false otherwise
*/
-static bool textarea_reflow(struct textarea *ta, unsigned int line)
+static bool textarea_reflow(struct textarea *ta, unsigned int start)
{
char *text;
unsigned int len;
size_t b_off;
int x;
- char *space;
- unsigned int line_count = 0;
-
- /** \todo pay attention to line parameter */
- /** \todo create horizontal scrollbar if needed */
-
- ta->line_count = 0;
+ char *space, *para_end;
+ unsigned int line; /* line count */
+ unsigned int scroll_lines;
+ int avail_width;
+ int h_extent; /* horizontal extent */
+ int v_extent; /* vertical extent */
+ bool restart;
if (ta->lines == NULL) {
ta->lines =
@@ -320,71 +415,190 @@ static bool textarea_reflow(struct textarea *ta, unsigned int line)
if (!(ta->flags & TEXTAREA_MULTILINE)) {
/* Single line */
- ta->lines[line_count].b_start = 0;
- ta->lines[line_count++].b_length = ta->text_len - 1;
+ int w = ta->vis_width - 2 * ta->border_width -
+ ta->pad_left - ta->pad_right;
+ ta->lines[0].b_start = 0;
+ ta->lines[0].b_length = ta->text_len - 1;
- ta->line_count = line_count;
+ nsfont.font_width(&ta->fstyle, ta->text, ta->text_len, &x);
+ if (x > w)
+ w = x;
+ ta->h_extent = w + ta->pad_left - ta->pad_right;
+ ta->line_count = 1;
return true;
}
- for (len = ta->text_len - 1, text = ta->text; len > 0;
- len -= b_off, text += b_off) {
+ /* Find max number of lines before vertical scrollbar is required */
+ scroll_lines = (ta->vis_height - 2 * ta->border_width -
+ ta->pad_top - ta->pad_bottom) /
+ ta->line_height;
+
+ if ((signed)start > ta->line_count)
+ start = 0;
+ /** \todo pay attention to start param, for now force start at zero */
+ start = 0;
+
+ do {
+ /* Set line count to start point */
+ line = start;
+
+ /* Find available width */
+ avail_width = ta->vis_width - 2 * ta->border_width -
+ ta->pad_left - ta->pad_right;
+ if (avail_width < 0)
+ avail_width = 0;
+ h_extent = avail_width;
+
+ restart = false;
+ for (len = ta->text_len - 1, text = ta->text; len > 0;
+ len -= b_off, text += b_off) {
+
+ /* Find end of paragraph */
+ for (para_end = text; para_end < text + len;
+ para_end++) {
+ if (*para_end == '\n')
+ break;
+ }
- nsfont.font_split(&ta->fstyle, text, len,
- ta->vis_width - MARGIN_LEFT - MARGIN_RIGHT,
- &b_off, &x);
+ /* Wrap current line in paragraph */
+ nsfont.font_split(&ta->fstyle, text, para_end - text,
+ avail_width, &b_off, &x);
+ /* b_off now marks space, or end of paragraph */
- if (line_count > 0 && line_count % LINE_CHUNK_SIZE == 0) {
- struct line_info *temp = realloc(ta->lines,
- (line_count + LINE_CHUNK_SIZE) *
- sizeof(struct line_info));
- if (temp == NULL) {
- LOG(("realloc failed"));
- return false;
+ if (x > h_extent) {
+ h_extent = x;
+ }
+ if (x > avail_width && ta->bar_x == NULL) {
+ /* We need to insert a horizontal scrollbar */
+ int w = ta->vis_width - 2 * ta->border_width;
+ if (!scrollbar_create(true, w, w, w,
+ ta, textarea_scrollbar_callback,
+ &(ta->bar_x)))
+ return false;
+ if (ta->bar_y != NULL)
+ scrollbar_make_pair(ta->bar_x,
+ ta->bar_y);
+ ta->pad_bottom += SCROLLBAR_WIDTH;
+
+ /* Find new max visible lines */
+ scroll_lines = (ta->vis_height -
+ 2 * ta->border_width -
+ ta->pad_top - ta->pad_bottom) /
+ ta->line_height;
}
- ta->lines = temp;
- }
+ if (line > 0 && line % LINE_CHUNK_SIZE == 0) {
+ struct line_info *temp = realloc(ta->lines,
+ (line + LINE_CHUNK_SIZE) *
+ sizeof(struct line_info));
+ if (temp == NULL) {
+ LOG(("realloc failed"));
+ return false;
+ }
- /* handle LF */
- for (space = text; space <= text + b_off; space++) {
- if (*space == '\n')
- break;
- }
+ ta->lines = temp;
+ }
+
+ if (para_end == text + b_off && *para_end == '\n') {
+ /* Not found any spaces to wrap at, and we
+ * have a newline char */
+ ta->lines[line].b_start = text - ta->text;
+ ta->lines[line++].b_length = para_end - text;
+
+ /* Jump newline */
+ b_off++;
+
+ if (len - b_off == 0) {
+ /* reached end of input;
+ * add last line */
+ ta->lines[line].b_start =
+ text + b_off - ta->text;
+ ta->lines[line++].b_length = 0;
+ }
- if (space <= text + b_off) {
- /* Found newline; use it */
- ta->lines[line_count].b_start = text - ta->text;
- ta->lines[line_count++].b_length = space - text;
+ if (line > scroll_lines && ta->bar_y == NULL)
+ break;
- b_off = space + 1 - text;
+ continue;
- if (len - b_off == 0) {
- /* reached end of input => add last line */
- ta->lines[line_count].b_start =
- text + b_off - ta->text;
- ta->lines[line_count++].b_length = 0;
+ } else if (len - b_off > 0) {
+ /* soft wraped, find last space (if any) */
+ for (space = text + b_off; space > text;
+ space--) {
+ if (*space == ' ')
+ break;
+ }
+
+ if (space != text)
+ b_off = space + 1 - text;
}
- continue;
+ ta->lines[line].b_start = text - ta->text;
+ ta->lines[line++].b_length = b_off;
+
+ if (line > scroll_lines && ta->bar_y == NULL)
+ break;
}
- if (len - b_off > 0) {
- /* find last space (if any) */
- for (space = text + b_off; space > text; space--)
- if (*space == ' ')
- break;
+ if (h_extent <= avail_width && ta->bar_x != NULL) {
+ /* We need to remove a horizontal scrollbar */
+ scrollbar_destroy(ta->bar_x);
+ ta->bar_x = NULL;
+ ta->pad_bottom -= SCROLLBAR_WIDTH;
- if (space != text)
- b_off = space + 1 - text;
+ /* Find new max visible lines */
+ scroll_lines = (ta->vis_height - 2 * ta->border_width -
+ ta->pad_top - ta->pad_bottom) /
+ ta->line_height;
}
- ta->lines[line_count].b_start = text - ta->text;
- ta->lines[line_count++].b_length = b_off;
+ if (line > scroll_lines && ta->bar_y == NULL) {
+ /* Add vertical scrollbar */
+ int h = ta->vis_height - 2 * ta->border_width;
+ if (!scrollbar_create(false, h, h, h,
+ ta, textarea_scrollbar_callback,
+ &(ta->bar_y)))
+ return false;
+ if (ta->bar_x != NULL)
+ scrollbar_make_pair(ta->bar_x,
+ ta->bar_y);
+ ta->pad_right += SCROLLBAR_WIDTH;
+ restart = true;
+
+ } else if (line <= scroll_lines && ta->bar_y != NULL) {
+ /* Remove vertical scrollbar */
+ scrollbar_destroy(ta->bar_y);
+ ta->bar_y = NULL;
+ ta->pad_right -= SCROLLBAR_WIDTH;
+ restart = true;
+ }
+ } while (restart);
+
+ h_extent += ta->pad_left + ta->pad_right -
+ (ta->bar_y != NULL ? SCROLLBAR_WIDTH : 0);
+ v_extent = line * ta->line_height + ta->pad_top +
+ ta->pad_bottom -
+ (ta->bar_x != NULL ? SCROLLBAR_WIDTH : 0);
+
+ if (ta->bar_x != NULL) {
+ /* Set horizontal scrollbar extents */
+ int w = ta->vis_width - 2 * ta->border_width -
+ (ta->bar_y != NULL ? SCROLLBAR_WIDTH : 0);
+ scrollbar_set_extents(ta->bar_x, w, w, h_extent);
}
- ta->line_count = line_count;
+ if (ta->bar_y != NULL) {
+ /* Set vertical scrollbar extents */
+ int h = ta->vis_height - 2 * ta->border_width;
+ scrollbar_set_extents(ta->bar_y, h,
+ h - (ta->bar_x != NULL ? SCROLLBAR_WIDTH : 0),
+ v_extent);
+ }
+
+ ta->h_extent = h_extent;
+ ta->v_extent = v_extent;
+ ta->line_count = line;
return true;
}
@@ -411,8 +625,8 @@ static void textarea_get_xy_offset(struct textarea *ta, int x, int y,
return;
}
- x = x - MARGIN_LEFT + ta->scroll_x;
- y = y + ta->scroll_y;
+ x = x - ta->border_width - ta->pad_left + ta->scroll_x;
+ y = y - ta->border_width - ta->pad_top + ta->scroll_y;
if (x < 0)
x = 0;
@@ -602,7 +816,7 @@ static bool textarea_replace_text(struct textarea *ta, unsigned int start,
/* Insert new text */
memcpy(ta->text + b_start, rep, rep_len);
- ta->text_len += rep_len - (b_end - b_start);
+ ta->text_len += (int)rep_len - (b_end - b_start);
ta->text_utf8_len = utf8_length(ta->text);
textarea_normalise_text(ta, b_start, rep_len);
@@ -611,16 +825,80 @@ static bool textarea_replace_text(struct textarea *ta, unsigned int start,
}
+/**
+ * Handles the end of a drag operation
+ *
+ * \param ta Text area
+ * \param mouse the mouse state at drag end moment
+ * \param x X coordinate
+ * \param y Y coordinate
+ * \return true if drag end was handled false otherwise
+ */
+static bool textarea_drag_end(struct textarea *ta, browser_mouse_state mouse,
+ int x, int y)
+{
+ int c_end;
+ size_t b_off;
+ unsigned int c_off;
+ struct textarea_msg msg;
+
+ assert(ta->drag_info.type != TEXTAREA_DRAG_NONE);
+
+ switch (ta->drag_info.type) {
+ case TEXTAREA_DRAG_SCROLLBAR:
+ if (ta->drag_info.data.scrollbar == ta->bar_x) {
+ x -= ta->border_width;
+ y -= ta->vis_height - ta->border_width -
+ SCROLLBAR_WIDTH;
+ } else {
+ x -= ta->vis_width - ta->border_width -
+ SCROLLBAR_WIDTH;
+ y -= ta->border_width;
+ }
+ scrollbar_mouse_drag_end(ta->drag_info.data.scrollbar,
+ mouse, x, y);
+ assert(ta->drag_info.type == TEXTAREA_DRAG_NONE);
+
+ /* Return, since drag end already reported to textarea client */
+ return true;
+
+ case TEXTAREA_DRAG_SELECTION:
+ ta->drag_info.type = TEXTAREA_DRAG_NONE;
+
+ textarea_get_xy_offset(ta, x, y, &b_off, &c_off);
+ c_end = c_off;
+
+ if (!textarea_select(ta, ta->drag_start_char, c_end))
+ return false;
+
+ break;
+
+ default:
+ return false;
+ }
+
+ /* Report drag end to client, if not already reported */
+ assert(ta->drag_info.type == TEXTAREA_DRAG_NONE);
+
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_DRAG_REPORT;
+ msg.data.drag = ta->drag_info.type;
+
+ ta->callback(ta->data, &msg);
+
+ return true;
+}
+
+
/* exported interface, documented in textarea.h */
-struct textarea *textarea_create(int width, int height,
- textarea_flags flags, const plot_font_style_t *style,
- textarea_redraw_request_callback redraw_request, void *data)
+struct textarea *textarea_create(const textarea_setup *setup,
+ textarea_client_callback callback, void *data)
{
struct textarea *ret;
- if (redraw_request == NULL) {
+ if (callback == NULL) {
LOG(("no callback provided"));
return NULL;
}
@@ -631,16 +909,35 @@ struct textarea *textarea_create(int width, int height,
return NULL;
}
- ret->redraw_request = redraw_request;
+ ret->callback = callback;
ret->data = data;
- ret->vis_width = width;
- ret->vis_height = height;
+
+ ret->flags = setup->flags;
+ ret->vis_width = setup->width;
+ ret->vis_height = setup->height;
+
+ ret->pad_top = setup->pad_top;
+ ret->pad_right = setup->pad_right;
+ ret->pad_bottom = setup->pad_bottom;
+ ret->pad_left = setup->pad_left;
+
+ ret->border_width = setup->border_width;
+ ret->border_col = setup->border_col;
+
+ ret->fstyle = setup->text;
+
+ ret->sel_fstyle = setup->text;
+ ret->sel_fstyle.foreground = setup->selected_text;
+ ret->sel_fstyle.background = setup->selected_bg;
+
ret->scroll_x = 0;
ret->scroll_y = 0;
+ ret->bar_x = NULL;
+ ret->bar_y = NULL;
ret->drag_start_char = 0;
+ ret->drag_info.type = TEXTAREA_DRAG_NONE;
- ret->flags = flags;
ret->text = malloc(64);
if (ret->text == NULL) {
LOG(("malloc failed"));
@@ -652,14 +949,13 @@ struct textarea *textarea_create(int width, int height,
ret->text_len = 1;
ret->text_utf8_len = 0;
- ret->fstyle = *style;
-
ret->line_height = FIXTOINT(FDIV((FMUL(FLTTOFIX(1.2),
FMUL(nscss_screen_dpi,
- INTTOFIX((style->size / FONT_SIZE_SCALE))))), F_72));
+ INTTOFIX((setup->text.size /
+ FONT_SIZE_SCALE))))), F_72));
- ret->caret_pos.line = ret->caret_pos.char_off = 0;
- ret->caret_x = MARGIN_LEFT;
+ ret->caret_pos.line = ret->caret_pos.char_off = -1;
+ ret->caret_x = 0;
ret->caret_y = 0;
ret->sel_start = -1;
ret->sel_end = -1;
@@ -674,6 +970,10 @@ struct textarea *textarea_create(int width, int height,
/* exported interface, documented in textarea.h */
void textarea_destroy(struct textarea *ta)
{
+ if (ta->bar_x)
+ scrollbar_destroy(ta->bar_x);
+ if (ta->bar_y)
+ scrollbar_destroy(ta->bar_y);
free(ta->text);
free(ta->lines);
free(ta);
@@ -738,6 +1038,7 @@ bool textarea_set_caret(struct textarea *ta, int caret)
int x0, y0, x1, y1;
int text_y_offset;
int width, height;
+ struct textarea_msg msg;
if (ta->flags & TEXTAREA_READONLY)
return true;
@@ -749,48 +1050,28 @@ bool textarea_set_caret(struct textarea *ta, int caret)
if (ta->flags & TEXTAREA_MULTILINE) {
/* Multiline textarea */
- text_y_offset = 0;
+ text_y_offset = ta->border_width + ta->pad_top;
} else {
/* Single line text area; text is vertically centered */
- text_y_offset = (ta->vis_height - ta->line_height + 1) / 2;
+ text_y_offset = ta->border_width;
+ text_y_offset += (ta->vis_height - ta->line_height + 1) / 2;
}
/* Delete the old caret */
if (ta->caret_pos.char_off != -1) {
- index = textarea_get_caret(ta);
- if (index == -1)
- return false;
-
- /* the redraw might happen in response to a text-change and
- the caret position might be beyond the current text */
- if ((unsigned)index > c_len)
- index = c_len;
-
- /* find byte offset of caret position */
- for (b_off = 0; index-- > 0;
- b_off = utf8_next(ta->text,
- ta->text_len, b_off))
- ; /* do nothing */
-
- nsfont.font_width(&ta->fstyle,
- ta->text +
- ta->lines[ta->caret_pos.line].b_start,
- b_off - ta->lines[ta->caret_pos.line].b_start,
- &x);
-
- x += MARGIN_LEFT - ta->scroll_x;
-
- y = ta->line_height * ta->caret_pos.line - ta->scroll_y;
-
- /* set the caret coordinate beyond the redraw rectangle */
- ta->caret_x = x - 2;
-
- x0 = x - 1;
- y0 = y + text_y_offset;
+ x0 = ta->caret_x - ta->scroll_x;
+ y0 = ta->caret_y + text_y_offset - ta->scroll_y;
width = 2;
height = ta->line_height;
- ta->redraw_request(ta->data, x0, y0, width, height);
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
+ msg.data.redraw.x0 = x0;
+ msg.data.redraw.y0 = y0;
+ msg.data.redraw.x1 = x0 + width;
+ msg.data.redraw.y1 = y0 + height;
+
+ ta->callback(ta->data, &msg);
}
/* check if the caret has to be drawn at all */
@@ -831,19 +1112,18 @@ bool textarea_set_caret(struct textarea *ta, int caret)
b_off - ta->lines[ta->caret_pos.line].b_start,
&x);
- x += MARGIN_LEFT - ta->scroll_x;
+ x += ta->border_width + ta->pad_left;
ta->caret_x = x;
- y = ta->line_height * ta->caret_pos.line - ta->scroll_y;
+ y = ta->line_height * ta->caret_pos.line;
ta->caret_y = y;
- if (textarea_scroll_visible(ta)) {
- ta->redraw_request(ta->data, 0, 0,
- ta->vis_width,
- ta->vis_height);
- } else {
- x0 = max(x - 1, MARGIN_LEFT);
+ if (!textarea_scroll_visible(ta)) {
+ /* No scroll, just caret moved, redraw it */
+ x -= ta->scroll_x;
+ y -= ta->scroll_y;
+ x0 = max(x - 1, ta->border_width);
y0 = max(y + text_y_offset, 0);
- x1 = min(x + 1, ta->vis_width - MARGIN_RIGHT);
+ x1 = min(x + 1, ta->vis_width - ta->border_width);
y1 = min(y + ta->line_height + text_y_offset,
ta->vis_height);
@@ -851,8 +1131,14 @@ bool textarea_set_caret(struct textarea *ta, int caret)
height = y1 - y0;
if (width > 0 && height > 0) {
- ta->redraw_request(ta->data, x0, y0,
- width, height);
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
+ msg.data.redraw.x0 = x0;
+ msg.data.redraw.y0 = y0;
+ msg.data.redraw.x1 = x0 + width;
+ msg.data.redraw.y1 = y0 + height;
+
+ ta->callback(ta->data, &msg);
}
}
}
@@ -866,6 +1152,9 @@ int textarea_get_caret(struct textarea *ta)
{
unsigned int c_off = 0, b_off;
+ /* Ensure caret isn't hidden */
+ if (ta->caret_pos.char_off < 0)
+ textarea_set_caret(ta, 0);
/* if the text is a trailing NUL only */
if (ta->text_utf8_len == 0)
@@ -881,19 +1170,26 @@ int textarea_get_caret(struct textarea *ta)
/* exported interface, documented in textarea.h */
-void textarea_redraw(struct textarea *ta, int x, int y,
+void textarea_redraw(struct textarea *ta, int x, int y, colour bg,
const struct rect *clip, const struct redraw_context *ctx)
{
+ struct textarea_msg msg;
const struct plotter_table *plot = ctx->plot;
- int line0, line1, line;
- int chars, offset, text_y_offset, text_y_offset_baseline;
- unsigned int c_pos, c_len, b_start, b_end, line_len;
+ int line0, line1, line, left, right;
+ int chars, text_y_offset, text_y_offset_baseline;
+ unsigned int c_pos, c_len, c_len_part, b_start, b_end, line_len;
+ unsigned int sel_start, sel_end;
char *line_text;
- struct rect r;
- plot_style_t plot_style_fill_bg = {
- .fill_type = PLOT_OP_TYPE_SOLID,
- .fill_colour = BACKGROUND_COL,
- };
+ struct rect r, s;
+ bool selected = false;
+ plot_font_style_t *fstyle;
+ plot_style_t plot_style_fill_bg = {
+ .stroke_type = PLOT_OP_TYPE_NONE,
+ .stroke_width = 0,
+ .stroke_colour = NS_TRANSPARENT,
+ .fill_type = PLOT_OP_TYPE_SOLID,
+ .fill_colour = ta->border_col
+ };
r = *clip;
@@ -906,9 +1202,6 @@ void textarea_redraw(struct textarea *ta, int x, int y,
/* Nothing to redraw */
return;
- if (ta->flags & TEXTAREA_READONLY)
- plot_style_fill_bg.fill_colour = READONLY_BG;
-
line0 = (r.y0 - y + ta->scroll_y) / ta->line_height - 1;
line1 = (r.y1 - y + ta->scroll_y) / ta->line_height + 1;
@@ -933,145 +1226,213 @@ void textarea_redraw(struct textarea *ta, int x, int y,
r.y1 = y + ta->vis_height;
plot->clip(&r);
- plot->rectangle(r.x0, r.y0, r.x1, r.y1, &plot_style_fill_bg);
- plot->rectangle(x, y,
- x + ta->vis_width - 1, y + ta->vis_height - 1,
- &pstyle_stroke_border);
-
- if (r.x0 < x + MARGIN_LEFT)
- r.x0 = x + MARGIN_LEFT;
- if (r.x1 > x + ta->vis_width - MARGIN_RIGHT)
- r.x1 = x + ta->vis_width - MARGIN_RIGHT;
- plot->clip(&r);
+ if (ta->border_col != NS_TRANSPARENT &&
+ ta->border_width > 0) {
+ /* Plot border */
+ plot->rectangle(x, y, x + ta->vis_width, y + ta->vis_height,
+ &plot_style_fill_bg);
+ }
+ if (ta->fstyle.background != NS_TRANSPARENT) {
+ /* Plot background */
+ plot_style_fill_bg.fill_colour = ta->fstyle.background;
+ plot->rectangle(x + ta->border_width, y + ta->border_width,
+ x + ta->vis_width - ta->border_width,
+ y + ta->vis_height - ta->border_width,
+ &plot_style_fill_bg);
+ }
+
+ if (r.x0 < x + ta->border_width)
+ r.x0 = x + ta->border_width;
+ if (r.x1 > x + ta->vis_width - ta->border_width)
+ r.x1 = x + ta->vis_width - ta->border_width;
+ if (r.y0 < y + ta->border_width)
+ r.y0 = y + ta->border_width;
+ if (r.y1 > y + ta->vis_height - ta->border_width -
+ (ta->bar_x != NULL ? SCROLLBAR_WIDTH : 0))
+ r.y1 = y + ta->vis_height - ta->border_width -
+ (ta->bar_x != NULL ? SCROLLBAR_WIDTH : 0);
if (line0 > 0)
- c_pos = utf8_bounded_length(ta->text,
- ta->lines[line0].b_start - 1);
+ c_pos = utf8_bounded_length(ta->text, ta->lines[line0].b_start);
else
c_pos = 0;
+ text_y_offset = text_y_offset_baseline = ta->border_width;
if (ta->flags & TEXTAREA_MULTILINE) {
/* Multiline textarea */
- text_y_offset = 0;
- text_y_offset_baseline = (ta->line_height * 3 + 2) / 4;
+ text_y_offset += ta->pad_top;
+ text_y_offset_baseline += (ta->line_height * 3 + 2) / 4 +
+ ta->pad_top;
} else {
/* Single line text area; text is vertically centered */
- text_y_offset = (ta->vis_height - ta->line_height + 1) / 2;
- text_y_offset_baseline = (ta->vis_height * 3 + 2) / 4;
+ int vis_height = ta->vis_height - 2 * ta->border_width;
+ text_y_offset += (vis_height - ta->line_height + 1) / 2;
+ text_y_offset_baseline += (vis_height * 3 + 2) / 4;
}
+ plot_style_fill_bg.fill_colour = ta->sel_fstyle.background;
+
for (line = line0; (line <= line1) &&
(y + line * ta->line_height <= r.y1 + ta->scroll_y);
line++) {
if (ta->lines[line].b_length == 0)
continue;
+ /* reset clip rectangle */
+ plot->clip(&r);
+
c_len = utf8_bounded_length(
&(ta->text[ta->lines[line].b_start]),
ta->lines[line].b_length);
- /* if there is a newline between the lines count it too */
- if (line < ta->line_count - 1 && ta->lines[line + 1].b_start !=
- ta->lines[line].b_start +
- ta->lines[line].b_length)
- c_len++;
-
- /* check if a part of the line is selected, won't happen if no
- selection (ta->sel_end = -1) */
- if (ta->sel_end != -1 &&
- c_pos < (unsigned)ta->sel_end &&
- c_pos + c_len > (unsigned)ta->sel_start) {
+ b_end = 0;
+ right = x + ta->border_width + ta->pad_left - ta->scroll_x;
+
+ do {
+ sel_start = ta->sel_start;
+ sel_end = ta->sel_end;
+ /* get length of part of line */
+ if (ta->sel_end == -1 || ta->sel_end == ta->sel_start ||
+ sel_end <= c_pos ||
+ sel_start > c_pos + c_len) {
+ /* rest of line unselected */
+ selected = false;
+ c_len_part = c_len;
+ fstyle = &ta->fstyle;
+
+ } else if (sel_start <= c_pos &&
+ sel_end > c_pos + c_len) {
+ /* rest of line selected */
+ selected = true;
+ c_len_part = c_len;
+ fstyle = &ta->sel_fstyle;
+
+ } else if (sel_start > c_pos) {
+ /* next part of line unselected */
+ selected = false;
+ c_len_part = sel_start - c_pos;
+ fstyle = &ta->fstyle;
+
+ } else if (sel_end > c_pos) {
+ /* next part of line selected */
+ selected = true;
+ c_len_part = sel_end - c_pos;
+ fstyle = &ta->sel_fstyle;
- /* offset from the beginning of the line */
- offset = ta->sel_start - c_pos;
- chars = ta->sel_end - c_pos -
- (offset > 0 ? offset:0);
+ } else {
+ assert(0);
+ }
line_text = &(ta->text[ta->lines[line].b_start]);
line_len = ta->lines[line].b_length;
- if (offset > 0) {
-
- /* find byte start of the selected part */
- for (b_start = 0; offset > 0; offset--)
- b_start = utf8_next(line_text,
- line_len,
- b_start);
- nsfont.font_width(&ta->fstyle, line_text,
- b_start, &r.x0);
- r.x0 += x + MARGIN_LEFT;
- }
- else {
- r.x0 = x + MARGIN_LEFT;
- b_start = 0;
+ /* find b_start and b_end for this part of the line */
+ b_start = b_end;
+
+ chars = c_len_part;
+ for (b_end = b_start; chars > 0; chars--)
+ b_end = utf8_next(line_text, line_len, b_end);
+
+ /* find clip left/right for this part of line */
+ left = right;
+ nsfont.font_width(&ta->fstyle, line_text,
+ b_end, &right);
+ right += x + ta->border_width + ta->pad_left -
+ ta->scroll_x;
+
+ /* set clip rectangle for line part */
+ s = r;
+ if (s.x0 < left)
+ s.x0 = left;
+ if (s.x1 > right)
+ s.x1 = right;
+ plot->clip(&s);
+
+ if (selected) {
+ /* draw selection fill */
+ plot->rectangle(s.x0,
+ y + line * ta->line_height + 1 -
+ ta->scroll_y + text_y_offset,
+ s.x1,
+ y + (line + 1) * ta->line_height + 1 -
+ ta->scroll_y + text_y_offset,
+ &plot_style_fill_bg);
}
+ /* draw text */
+ plot->text(x + ta->border_width + ta->pad_left -
+ ta->scroll_x,
+ y + line * ta->line_height +
+ text_y_offset_baseline - ta->scroll_y,
+ ta->text + ta->lines[line].b_start,
+ ta->lines[line].b_length, fstyle);
+
+ c_pos += c_len_part;
+ c_len -= c_len_part;
+
+ } while (c_pos < c_pos + c_len);
+
+ /* if there is a newline between the lines, skip it */
+ if (line < ta->line_count - 1 &&
+ ta->lines[line + 1].b_start !=
+ ta->lines[line].b_start +
+ ta->lines[line].b_length)
+ c_pos++;
+ }
- if (chars >= 0) {
+ plot->clip(clip);
- /* find byte end of the selected part */
- for (b_end = b_start; chars > 0 &&
- b_end < line_len;
- chars--) {
- b_end = utf8_next(line_text, line_len,
- b_end);
- }
- }
- else
- b_end = ta->lines[line].b_length;
-
- b_end -= b_start;
- nsfont.font_width(&ta->fstyle,
- &(ta->text[ta->lines[line].b_start +
- b_start]),
- b_end, &r.x1);
- r.x1 += r.x0;
- plot->rectangle(r.x0 - ta->scroll_x, y +
- line * ta->line_height +
- 1 - ta->scroll_y + text_y_offset,
- r.x1 - ta->scroll_x,
- y + (line + 1) * ta->line_height -
- 1 - ta->scroll_y + text_y_offset,
- &pstyle_fill_selection);
+ if ((ta->sel_end == -1 || ta->sel_start == ta->sel_end) &&
+ ta->caret_pos.char_off >= 0) {
+ /* There is no selection, and caret visible: show caret */
+ int caret_y = y - ta->scroll_y + ta->caret_y + text_y_offset;
+ if (ta->flags & TEXTAREA_INTERNAL_CARET) {
+ /* Render our own caret */
+ plot->line(x - ta->scroll_x + ta->caret_x, caret_y,
+ x - ta->scroll_x + ta->caret_x,
+ caret_y + ta->line_height,
+ &pstyle_stroke_caret);
+ } else {
+ /* Tell client where caret should be placed */
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_MOVED_CARET;
+ msg.data.caret.hidden = false;
+ msg.data.caret.x = x - ta->scroll_x + ta->caret_x;
+ msg.data.caret.y = caret_y;
+ msg.data.caret.height = ta->line_height;
+
+ ta->callback(ta->data, &msg);
}
+ } else if (!(ta->flags & TEXTAREA_INTERNAL_CARET)) {
+ /* Caret hidden, and client is responsible: tell client */
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_MOVED_CARET;
+ msg.data.caret.hidden = true;
- c_pos += c_len;
-
- r.y0 = y + line * ta->line_height + text_y_offset_baseline;
-
- ta->fstyle.background =
- (ta->flags & TEXTAREA_READONLY) ?
- READONLY_BG : BACKGROUND_COL,
-
- plot->text(x + MARGIN_LEFT - ta->scroll_x,
- r.y0 - ta->scroll_y,
- ta->text + ta->lines[line].b_start,
- ta->lines[line].b_length,
- &ta->fstyle);
+ ta->callback(ta->data, &msg);
}
- if ((ta->sel_end == -1 ||
- ta->sel_start == ta->sel_end) &&
- x + ta->caret_x >= clip->x0 &&
- x + ta->caret_x <= clip->x1) {
- /* There is no selection and caret is in horizontal
- * clip range. */
- int caret_height = ta->line_height - 1;
- y += ta->caret_y + text_y_offset;
- if (y + caret_height >= clip->y0 && y <= clip->y1)
- /* Caret in vertical clip range; plot */
- plot->line(x + ta->caret_x, y + ta->caret_y,
- x + ta->caret_x,
- y + ta->caret_y + caret_height,
- &pstyle_stroke_caret);
- }
+ if (ta->bar_x != NULL)
+ scrollbar_redraw(ta->bar_x,
+ x + ta->border_width,
+ y + ta->vis_height - ta->border_width -
+ SCROLLBAR_WIDTH,
+ clip, 1.0, ctx);
+
+ if (ta->bar_y != NULL)
+ scrollbar_redraw(ta->bar_y,
+ x + ta->vis_width - ta->border_width -
+ SCROLLBAR_WIDTH,
+ y + ta->border_width,
+ clip, 1.0, ctx);
}
/* exported interface, documented in textarea.h */
bool textarea_keypress(struct textarea *ta, uint32_t key)
{
+ struct textarea_msg msg;
char utf8[6];
unsigned int caret, caret_init, length, l_len, b_off, b_len;
int c_line, c_chars, line;
@@ -1082,7 +1443,6 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
line = ta->caret_pos.line;
readonly = (ta->flags & TEXTAREA_READONLY ? true:false);
-
if (!(key <= 0x001F || (0x007F <= key && key <= 0x009F))) {
/* normal character insertion */
length = utf8_from_ucs4(key, utf8);
@@ -1110,10 +1470,10 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
case KEY_SELECT_ALL:
caret = ta->text_utf8_len;
- ta->sel_start = 0;
+ ta->sel_start = 0;
ta->sel_end = ta->text_utf8_len;
- redraw = true;
- break;
+ redraw = true;
+ break;
case KEY_COPY_SELECTION:
if (ta->sel_start != -1) {
if (!textarea_replace_text(ta,
@@ -1157,13 +1517,16 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
break;
case KEY_PASTE:
{
- if (readonly)
- break;
char *clipboard;
size_t clipboard_length;
size_t clipboard_chars;
+ if (readonly)
+ break;
+
gui_get_clipboard(&clipboard, &clipboard_length);
+ if (clipboard == NULL)
+ return false;
clipboard_chars = utf8_bounded_length(clipboard,
clipboard_length);
@@ -1336,7 +1699,7 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
break;
if (ta->sel_start != -1) {
if (!textarea_replace_text(ta,
- ta->sel_start,
+ ta->sel_start,
ta->sel_end, "", 0, false))
return false;
@@ -1404,7 +1767,7 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
break;
if (ta->sel_start != -1) {
if (!textarea_replace_text(ta,
- ta->sel_start,
+ ta->sel_start,
ta->sel_end, "", 0, false))
return false;
ta->sel_start = ta->sel_end = -1;
@@ -1424,7 +1787,7 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
break;
if (ta->sel_start != -1) {
if (!textarea_replace_text(ta,
- ta->sel_start,
+ ta->sel_start,
ta->sel_end, "", 0, false))
return false;
ta->sel_start = ta->sel_end = -1;
@@ -1446,8 +1809,14 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
textarea_set_caret(ta, caret);
//TODO:redraw only the important part
if (redraw) {
- ta->redraw_request(ta->data, 0, 0,
- ta->vis_width, ta->vis_height);
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
+ msg.data.redraw.x0 = 0;
+ msg.data.redraw.y0 = 0;
+ msg.data.redraw.x1 = ta->vis_width;
+ msg.data.redraw.y1 = ta->vis_height;
+
+ ta->callback(ta->data, &msg);
}
return true;
@@ -1459,23 +1828,83 @@ bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
int x, int y)
{
int c_start, c_end;
+ int sx, sy; /* xy coord offset for scrollbar */
+ int sl; /* scrollbar length */
size_t b_off;
unsigned int c_off;
+ struct textarea_msg msg;
+
+ if (ta->drag_info.type != TEXTAREA_DRAG_NONE &&
+ mouse == BROWSER_MOUSE_HOVER) {
+ /* There is a drag that we must end */
+ textarea_drag_end(ta, mouse, x, y);
+ }
+
+ if (ta->drag_info.type == TEXTAREA_DRAG_SCROLLBAR) {
+ /* Scrollbar drag in progress; pass input to scrollbar */
+ if (ta->drag_info.data.scrollbar == ta->bar_x) {
+ x -= ta->border_width;
+ y -= ta->vis_height - ta->border_width -
+ SCROLLBAR_WIDTH;
+ } else {
+ x -= ta->vis_width - ta->border_width -
+ SCROLLBAR_WIDTH;
+ y -= ta->border_width;
+ }
+ scrollbar_mouse_action(ta->drag_info.data.scrollbar,
+ mouse, x, y);
+ return true;
+ }
+
+ /* Horizontal scrollbar */
+ if (ta->bar_x != NULL && ta->drag_info.type == TEXTAREA_DRAG_NONE) {
+ /* No drag happening, but mouse input is over scrollbar;
+ * pass input to scrollbar */
+ sx = x - ta->border_width;
+ sy = y - (ta->vis_height - ta->border_width - SCROLLBAR_WIDTH);
+ sl = ta->vis_width - 2 * ta->border_width -
+ (ta->bar_y != NULL ? SCROLLBAR_WIDTH : 0);
+
+ if (sx >= 0 && sy >= 0 && sx < sl && sy < SCROLLBAR_WIDTH) {
+ scrollbar_mouse_action(ta->bar_x, mouse, sx, sy);
+ return true;
+ }
+ }
+
+ /* Vertical scrollbar */
+ if (ta->bar_y != NULL && ta->drag_info.type == TEXTAREA_DRAG_NONE) {
+ /* No drag happening, but mouse input is over scrollbar;
+ * pass input to scrollbar */
+ sx = x - (ta->vis_width - ta->border_width - SCROLLBAR_WIDTH);
+ sy = y - ta->border_width;
+ sl = ta->vis_height - 2 * ta->border_width;
+
+ if (sx >= 0 && sy >= 0 && sx < SCROLLBAR_WIDTH && sy < sl) {
+ scrollbar_mouse_action(ta->bar_y, mouse, sx, sy);
+ return true;
+ }
+ }
/* mouse button pressed above the text area, move caret */
if (mouse & BROWSER_MOUSE_PRESS_1) {
if (!(ta->flags & TEXTAREA_READONLY)) {
- textarea_set_caret_xy(ta, x, y);
-
textarea_get_xy_offset(ta, x, y, &b_off, &c_off);
ta->drag_start_char = c_off;
+
+ textarea_set_caret(ta, c_off);
}
if (ta->sel_start != -1) {
/* remove selection */
ta->sel_start = ta->sel_end = -1;
- ta->redraw_request(ta->data, 0, 0,
- ta->vis_width,
- ta->vis_height);
+
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
+ msg.data.redraw.x0 = 0;
+ msg.data.redraw.y0 = 0;
+ msg.data.redraw.x1 = ta->vis_width;
+ msg.data.redraw.y1 = ta->vis_height;
+
+ ta->callback(ta->data, &msg);
}
} else if (mouse & BROWSER_MOUSE_DOUBLE_CLICK) {
@@ -1488,24 +1917,18 @@ bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
textarea_get_xy_offset(ta, x, y, &b_off, &c_off);
c_start = ta->drag_start_char;
c_end = c_off;
- return textarea_select(ta, c_start, c_end);
- }
+ ta->drag_info.type = TEXTAREA_DRAG_SELECTION;
- return true;
-}
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_DRAG_REPORT;
+ msg.data.drag = ta->drag_info.type;
+ ta->callback(ta->data, &msg);
-/* exported interface, documented in textarea.h */
-bool textarea_drag_end(struct textarea *ta, browser_mouse_state mouse,
- int x, int y)
-{
- int c_end;
- size_t b_off;
- unsigned int c_off;
+ return textarea_select(ta, c_start, c_end);
+ }
- textarea_get_xy_offset(ta, x, y, &b_off, &c_off);
- c_end = c_off;
- return textarea_select(ta, ta->drag_start_char, c_end);
+ return true;
}
@@ -1522,8 +1945,18 @@ void textarea_get_dimensions(struct textarea *ta, int *width, int *height)
/* exported interface, documented in textarea.h */
void textarea_set_dimensions(struct textarea *ta, int width, int height)
{
+ struct textarea_msg msg;
+
ta->vis_width = width;
ta->vis_height = height;
textarea_reflow(ta, 0);
- ta->redraw_request(ta->data, 0, 0, ta->vis_width, ta->vis_height);
+
+ msg.ta = ta;
+ msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
+ msg.data.redraw.x0 = 0;
+ msg.data.redraw.y0 = 0;
+ msg.data.redraw.x1 = ta->vis_width;
+ msg.data.redraw.y1 = ta->vis_height;
+
+ ta->callback(ta->data, &msg);
}
diff --git a/desktop/textarea.h b/desktop/textarea.h
index e4fa2c7..6a1a471 100644
--- a/desktop/textarea.h
+++ b/desktop/textarea.h
@@ -29,34 +29,83 @@
#include "desktop/browser.h"
#include "desktop/plot_style.h"
+
+struct textarea;
+
/* Text area flags */
-typedef enum textarea_flags {
- TEXTAREA_DEFAULT = (1 << 0),
- TEXTAREA_MULTILINE = (1 << 1),
- TEXTAREA_READONLY = (1 << 2)
+typedef enum {
+ TEXTAREA_DEFAULT = (1 << 0), /**< Standard input */
+ TEXTAREA_MULTILINE = (1 << 1), /**< Multiline area */
+ TEXTAREA_READONLY = (1 << 2), /**< Non-editable */
+ TEXTAREA_INTERNAL_CARET = (1 << 3) /**< Render own caret */
} textarea_flags;
+typedef enum {
+ TEXTAREA_DRAG_NONE,
+ TEXTAREA_DRAG_SCROLLBAR,
+ TEXTAREA_DRAG_SELECTION
+} textarea_drag_type;
+
+typedef enum {
+ TEXTAREA_MSG_DRAG_REPORT, /**< Textarea drag start/end report */
+ TEXTAREA_MSG_REDRAW_REQUEST, /**< Textarea redraw request */
+ TEXTAREA_MSG_MOVED_CARET /**< Textarea caret moved */
+} textarea_msg_type;
+
+struct textarea_msg {
+ struct textarea *ta;
+
+ textarea_msg_type type;
+ union {
+ textarea_drag_type drag;
+ struct rect redraw;
+ struct {
+ bool hidden;
+ int x;
+ int y;
+ int height;
+ } caret;
+ } data;
+};
+
+typedef struct textarea_setup {
+ textarea_flags flags; /**< Setup flags */
+
+ int width; /**< Textarea width */
+ int height; /**< Textarea height */
+
+ int pad_top; /**< Textarea top padding */
+ int pad_right; /**< Textarea right padding */
+ int pad_bottom; /**< Textarea bottom padding */
+ int pad_left; /**< Textarea left padding */
+
+ int border_width; /**< Textarea border width */
+ colour border_col; /**< Textarea border colour */
+
+ colour selected_text; /**< Textarea selected text colour */
+ colour selected_bg; /**< Textarea selection background colour */
+ plot_font_style_t text; /**< Textarea background colour and font */
+
+} textarea_setup;
-struct textarea;
-
-typedef void(*textarea_redraw_request_callback)(void *data, int x, int y,
- int width, int height);
+/**
+ * Client callback for the textarea
+ *
+ * \param data user data passed at textarea creation
+ * \param textarea_msg textarea message data
+ */
+typedef void(*textarea_client_callback)(void *data, struct textarea_msg *msg);
/**
* Create a text area
*
- * \param width width of the text area
- * \param height width of the text area
- * \param flags text area flags
- * \param style font style
- * \param redraw_start_callback will be called when textarea wants to redraw
- * \param redraw_end_callback will be called when textarea finisjes redrawing
- * \param data user specified data which will be passed to redraw callbacks
+ * \param setup textarea settings and style
+ * \param redraw_callback will be called when textarea wants to redraw
+ * \param data user specified data which will be passed to callbacks
* \return Opaque handle for textarea or 0 on error
*/
-struct textarea *textarea_create(int width, int height,
- textarea_flags flags, const plot_font_style_t *style,
- textarea_redraw_request_callback redraw_request, void *data);
+struct textarea *textarea_create(const textarea_setup *setup,
+ textarea_client_callback callback, void *data);
/**
* Destroy a text area
@@ -106,14 +155,14 @@ int textarea_get_caret(struct textarea *ta);
/**
* Handle redraw requests for text areas
*
- * \param redraw Redraw request block
- * \param x0 left X coordinate of redraw area
- * \param y0 top Y coordinate of redraw area
- * \param x1 right X coordinate of redraw area
- * \param y1 bottom Y coordinate of redraw area
+ * \param ta textarea to render
+ * \param x x coordinate of textarea top
+ * \param y y coordinate of textarea left
+ * \param bg background colour under textarea
+ * \param clip clip rectangle
* \param ctx current redraw context
*/
-void textarea_redraw(struct textarea *ta, int x, int y,
+void textarea_redraw(struct textarea *ta, int x, int y, colour bg,
const struct rect *clip, const struct redraw_context *ctx);
/**
@@ -138,18 +187,6 @@ bool textarea_mouse_action(struct textarea *ta, browser_mouse_state mouse,
int x, int y);
/**
- * Handles the end of a drag operation
- *
- * \param ta Text area
- * \param mouse the mouse state at drag end moment
- * \param x X coordinate
- * \param y Y coordinate
- * \return true if drag end was handled false otherwise
- */
-bool textarea_drag_end(struct textarea *ta, browser_mouse_state mouse,
- int x, int y);
-
-/**
* Gets the dimensions of a textarea
*
* \param width if not NULL, gets updated to the width of the textarea
diff --git a/desktop/tree.c b/desktop/tree.c
index 250bdd8..959b987 100644
--- a/desktop/tree.c
+++ b/desktop/tree.c
@@ -160,8 +160,7 @@ struct tree {
int height; /* Tree height */
unsigned int flags; /* Tree flags */
struct textarea *textarea; /* Handle for UTF-8 textarea */
- bool textarea_drag_start; /* whether the start of a mouse drag
- was in the textarea */
+ int ta_height; /* Textarea height */
struct node_element *editing; /* Node element being edited */
bool redraw; /* Flag indicating whether the tree
@@ -263,7 +262,6 @@ struct tree *tree_create(unsigned int flags,
tree->height = 0;
tree->flags = flags;
tree->textarea = NULL;
- tree->textarea_drag_start = false;
tree->editing = NULL;
tree->redraw = false;
tree->drag = TREE_NO_DRAG;
@@ -2078,7 +2076,10 @@ void tree_draw(struct tree *tree, int x, int y,
y = y + tree->editing->box.y;
if (tree->editing->type == NODE_ELEMENT_TEXT_PLUS_ICON)
x += NODE_INSTEP;
- textarea_redraw(tree->textarea, x, y, &clip, &new_ctx);
+ textarea_redraw(tree->textarea, x, y,
+ plot_style_fill_tree_background.
+ fill_colour,
+ &clip, &new_ctx);
}
}
@@ -2427,9 +2428,9 @@ bool tree_mouse_action(struct tree *tree, browser_mouse_state mouse, int x,
x0 += NODE_INSTEP;
x1 = tree->editing->box.x + tree->editing->box.width;
y0 = tree->editing->box.y;
- y1 = tree->editing->box.y + tree->editing->box.height;
+ y1 = tree->editing->box.y + tree->ta_height;
- if (tree->textarea_drag_start &&
+ if (tree->drag == TREE_TEXTAREA_DRAG &&
(mouse & (BROWSER_MOUSE_HOLDING_1 |
BROWSER_MOUSE_HOLDING_2))) {
/* Track the drag path */
@@ -2438,19 +2439,7 @@ bool tree_mouse_action(struct tree *tree, browser_mouse_state mouse, int x,
return true;
}
-
-
if ((x >= x0) && (x < x1) && (y >= y0) && (y < y1)) {
- /* Inside the textarea */
- if (mouse & (BROWSER_MOUSE_DRAG_1 |
- BROWSER_MOUSE_DRAG_2)) {
- /* Drag starting */
- tree->textarea_drag_start = true;
- tree->drag = TREE_TEXTAREA_DRAG;
- } else {
- /* Other action */
- tree->textarea_drag_start = false;
- }
textarea_mouse_action(tree->textarea, mouse,
x - x0, y - y0);
return true;
@@ -2458,8 +2447,6 @@ bool tree_mouse_action(struct tree *tree, browser_mouse_state mouse, int x,
}
}
- tree->textarea_drag_start = false;
-
/* we are not interested in the drag path, return */
if (mouse & (BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_HOLDING_2))
return true;
@@ -2832,25 +2819,25 @@ void tree_drag_end(struct tree *tree, browser_mouse_state mouse, int x0, int y0,
struct node *node;
int x, y;
- if (tree->textarea_drag_start) {
+ switch (tree->drag) {
+ case TREE_NO_DRAG:
+ case TREE_UNKNOWN_DRAG:
+ break;
+
+ case TREE_TEXTAREA_DRAG:
x = tree->editing->box.x;
y = tree->editing->box.y;
if (tree->editing->type == NODE_ELEMENT_TEXT_PLUS_ICON)
x += NODE_INSTEP;
- textarea_drag_end(tree->textarea, mouse, x1 - x, y1 - y);
- }
-
- tree->textarea_drag_start = false;
-
- switch (tree->drag) {
- case TREE_NO_DRAG:
- case TREE_TEXTAREA_DRAG:
- case TREE_UNKNOWN_DRAG:
+ textarea_mouse_action(tree->textarea, BROWSER_MOUSE_HOVER,
+ x1 - x, y1 - y);
break;
+
case TREE_SELECT_DRAG:
tree_handle_selection_area(tree, y0, y1 - y0,
(mouse | BROWSER_MOUSE_HOLDING_2));
break;
+
case TREE_MOVE_DRAG:
if (!(tree->flags & TREE_MOVABLE))
return;
@@ -2872,7 +2859,6 @@ void tree_drag_end(struct tree *tree, browser_mouse_state mouse, int x0, int y0,
*/
bool tree_keypress(struct tree *tree, uint32_t key)
{
-
if (tree->editing != NULL)
switch (key) {
case KEY_ESCAPE:
@@ -2909,19 +2895,43 @@ int tree_alphabetical_sort(struct node *n1, struct node *n2)
* check the redraw flag of the tree before requesting a redraw and change the
* position to tree origin relative.
*/
-static void tree_textarea_redraw_request(void *data, int x, int y,
- int width, int height)
+
+static void tree_textarea_callback(void *data, struct textarea_msg *msg)
{
struct tree *tree = data;
- x = x + tree->editing->box.x;
- y = y + tree->editing->box.y;
- if (tree->editing->type == NODE_ELEMENT_TEXT_PLUS_ICON)
- x += NODE_INSTEP;
+ int x, y;
- if (tree->redraw)
- tree->callbacks->redraw_request(x, y,
- width, height,
- tree->client_data);
+ switch (msg->type) {
+ case TEXTAREA_MSG_DRAG_REPORT:
+ if (msg->data.drag == TEXTAREA_DRAG_NONE) {
+ /* Textarea drag finished */
+ tree->drag = TREE_NO_DRAG;
+ } else {
+ /* Textarea drag started */
+ tree->drag = TREE_TEXTAREA_DRAG;
+ }
+ break;
+
+ case TEXTAREA_MSG_REDRAW_REQUEST:
+ x = msg->data.redraw.x0 + tree->editing->box.x;
+ y = msg->data.redraw.y0 + tree->editing->box.y;
+
+ if (tree->editing->type == NODE_ELEMENT_TEXT_PLUS_ICON)
+ x += NODE_INSTEP;
+
+ /* Redraw the textarea */
+ if (tree->redraw)
+ tree->callbacks->redraw_request(x, y,
+ msg->data.redraw.x1 -
+ msg->data.redraw.x0,
+ msg->data.redraw.y1 -
+ msg->data.redraw.y0,
+ tree->client_data);
+ break;
+
+ default:
+ break;
+ }
}
@@ -2935,6 +2945,7 @@ void tree_start_edit(struct tree *tree, struct node_element *element)
{
struct node *parent;
int width, height;
+ textarea_setup ta_setup;
assert(tree != NULL);
assert(element != NULL);
@@ -2959,8 +2970,25 @@ void tree_start_edit(struct tree *tree, struct node_element *element)
if (element->type == NODE_ELEMENT_TEXT_PLUS_ICON)
width -= NODE_INSTEP;
- tree->textarea = textarea_create(width, height, TEXTAREA_DEFAULT,
- &plot_fstyle, tree_textarea_redraw_request, tree);
+ tree->ta_height = height;
+
+ ta_setup.flags = TEXTAREA_INTERNAL_CARET;
+ ta_setup.width = width;
+ ta_setup.height = tree->ta_height;
+ ta_setup.pad_top = 0;
+ ta_setup.pad_right = 4;
+ ta_setup.pad_bottom = 0;
+ ta_setup.pad_left = 4;
+ ta_setup.border_width = 1;
+ ta_setup.border_col = 0x000000;
+ ta_setup.selected_text = 0xffffff;
+ ta_setup.selected_bg = 0x000000;
+ ta_setup.text = plot_fstyle;
+ ta_setup.text.foreground = 0x000000;
+ ta_setup.text.background = 0xffffff;
+
+ tree->textarea = textarea_create(&ta_setup,
+ tree_textarea_callback, tree);
if (tree->textarea == NULL) {
tree_stop_edit(tree, false);
return;
diff --git a/gtk/treeview.c b/gtk/treeview.c
index efba9c4..1a98798 100644
--- a/gtk/treeview.c
+++ b/gtk/treeview.c
@@ -254,7 +254,7 @@ gboolean nsgtk_tree_window_button_press_event(GtkWidget *widget,
switch (event->button) {
case 1: tw->mouse_state |= BROWSER_MOUSE_PRESS_1; break;
- case 3: tw->mouse_state |= BROWSER_MOUSE_PRESS_2; break;
+ case 2: tw->mouse_state |= BROWSER_MOUSE_PRESS_2; break;
}
/* Handle the modifiers too */
if (event->state & GDK_SHIFT_MASK)
diff --git a/image/png.c b/image/png.c
index 23c7558..2a83346 100644
--- a/image/png.c
+++ b/image/png.c
@@ -502,7 +502,8 @@ png_cache_convert_error:
free((png_bytep *) row_pointers);
- bitmap_modified((struct bitmap *)bitmap);
+ if (bitmap != NULL)
+ bitmap_modified((struct bitmap *)bitmap);
return (struct bitmap *)bitmap;
}
diff --git a/javascript/jsapi.h b/javascript/jsapi.h
index e3295fe..e38188a 100644
--- a/javascript/jsapi.h
+++ b/javascript/jsapi.h
@@ -75,10 +75,9 @@
/* native proprty definition */
-#define JSAPI_PROP_GETTER(name, cx, obj, vp) \
- jsapi_property_##name##_get(cx, obj, jsval jsapi_id, vp)
-#define JSAPI_PROP_SETTER(name, cx, obj, vp) \
- jsapi_property_##name##_set(cx, obj, jsval jsapi_id, vp)
+#define JSAPI_PROP(name, cx, obj, vp) \
+ jsapi_property_##name(cx, obj, jsval jsapi_id, vp)
+#define JSAPI_STRICTPROP JSAPI_PROP
/* native property return value */
#define JSAPI_PROP_RVAL(cx, vp) (*(vp))
@@ -193,12 +192,10 @@ JS_NewCompartmentAndGlobalObject(JSContext *cx,
-
/* proprty native calls */
-#define JSAPI_PROP_GETTER(name, cx, obj, vp) \
- jsapi_property_##name##_get(cx, obj, jsval jsapi_id, vp)
-#define JSAPI_PROP_SETTER(name, cx, obj, vp) \
- jsapi_property_##name##_set(cx, obj, jsval jsapi_id, vp)
+#define JSAPI_PROP(name, cx, obj, vp) \
+ jsapi_property_##name(cx, obj, jsval jsapi_id, vp)
+#define JSAPI_STRICTPROP JSAPI_PROP
/* native property return value */
#define JSAPI_PROP_RVAL JS_RVAL
@@ -307,10 +304,10 @@ JS_NewCompartmentAndGlobalObject(JSContext *cx,
#define JSAPI_THIS_OBJECT(cx,vp) JS_THIS_OBJECT(cx,vp)
/* proprty native calls */
-#define JSAPI_PROP_GETTER(name, cx, obj, vp) \
- jsapi_property_##name##_get(cx, obj, jsid jsapi_id, vp)
-#define JSAPI_PROP_SETTER(name, cx, obj, vp) \
- jsapi_property_##name##_set(cx, obj, jsid jsapi_id, JSBool strict, vp)
+#define JSAPI_PROP(name, cx, obj, vp) \
+ jsapi_property_##name(cx, obj, jsid jsapi_id, vp)
+#define JSAPI_STRICTPROP(name, cx, obj, vp) \
+ jsapi_property_##name(cx, obj, jsid jsapi_id, JSBool strict, vp)
/* native property return value */
#define JSAPI_PROP_RVAL JS_RVAL
@@ -379,5 +376,10 @@ JS_NewCompartmentAndGlobalObject(JSContext *cx,
#endif
#define JSLOG(args...) LOG((args))
+#ifdef ENABLE_VERBOSE_JS_DEBUG
+#define JSDBG(args...) LOG((args))
+#else
+#define JSDBG(args...)
+#endif
#endif
diff --git a/javascript/jsapi/htmldocument.bnd b/javascript/jsapi/htmldocument.bnd
index 8d5c69e..4aacccf 100644
--- a/javascript/jsapi/htmldocument.bnd
+++ b/javascript/jsapi/htmldocument.bnd
@@ -52,6 +52,9 @@ binding document {
/** location instantiated on first use */
property unshared location;
+ /* compatability mode instantiated on first use */
+ property unshared compatMode;
+
/* events through a single interface */
property unshared type EventHandler;
}
@@ -66,7 +69,7 @@ api finalise %{
getter location %{
- if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx,vp))) {
+ if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
/* already created - return it */
return JS_TRUE;
}
@@ -95,6 +98,32 @@ getter documentURI %{
jsret = JSVAL_TO_STRING(jsstr);
%}
+
+getter compatMode %{
+ /* Returns the string "CSS1Compat" if document is in no-quirks
+ * mode or limited-quirks mode, and "BackCompat", if document
+ * is in quirks mode.
+ */
+ if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
+ /* already created, just use it */
+ return JS_TRUE;
+ }
+ if (private->htmlc->quirks == DOM_DOCUMENT_QUIRKS_MODE_FULL) {
+ jsret = JS_NewStringCopyN(cx, "BackCompat", SLEN("BackCompat"));
+ } else {
+ jsret = JS_NewStringCopyN(cx, "CSS1Compat", SLEN("CSS1Compat"));
+ }
+
+%}
+
+/*
+getter characterSet %{
+%}
+
+getter contentType %{
+%}
+*/
+
getter cookie %{
char *cookie_str;
cookie_str = urldb_get_cookie(llcache_handle_get_url(private->htmlc->base.llcache), false);
@@ -144,7 +173,7 @@ getter body %{
dom_node *body;
dom_exception exc;
- JSLOG("Getting your body");
+ JSDBG("Getting your body");
/* document (html) element */
exc = dom_document_get_document_element(private->node, &element);
@@ -160,7 +189,7 @@ getter body %{
dom_node_unref(element);
}
- JSLOG("returning jsobject %p",jsret);
+ JSDBG("returning jsobject %p",jsret);
%}
@@ -190,6 +219,7 @@ operation getElementById %{
* Dom 4 says this should return a htmlcollection, libdom currently
* returns DOM 3 spec of a nodelist
*/
+/* HTMLCollection Document::getElementsByTagName(DOMString localName); */
operation getElementsByTagName %{
dom_string *localName_dom;
/* dom_html_collection *collection;*/
@@ -236,7 +266,7 @@ operation createTextNode %{
if (data != NULL) {
- JSLOG("Creating text node for string \"%s\"", data);
+ JSDBG("Creating text node for string \"%s\"", data);
exc = dom_string_create((unsigned char*)data, data_len, &data_dom);
if (exc != DOM_NO_ERR) {
return JS_FALSE;
@@ -251,7 +281,7 @@ operation createTextNode %{
jsret = jsapi_new_Text(cx, NULL, NULL, text, private->htmlc);
}
- JSLOG("returning jsobject %p",jsret);
+ JSDBG("returning jsobject %p",jsret);
%}
@@ -263,7 +293,7 @@ operation createComment %{
if (data != NULL) {
- JSLOG("Creating string \"%s\"", data);
+ JSDBG("Creating string \"%s\"", data);
exc = dom_string_create((unsigned char*)data,
data_len,
&data_dom);
@@ -271,7 +301,7 @@ operation createComment %{
return JS_FALSE;
}
- JSLOG("Creating comment object for dom string \"%s\"",
+ JSDBG("Creating comment object for dom string \"%s\"",
dom_string_data(data_dom));
exc = dom_document_create_comment(private->node,
data_dom,
@@ -284,7 +314,7 @@ operation createComment %{
jsret = jsapi_new_Comment(cx, NULL, NULL, comment, private->htmlc);
}
- JSLOG("returning jsobject %p", jsret);
+ JSDBG("returning jsobject %p", jsret);
%}
@@ -295,7 +325,7 @@ operation createElement %{
dom_element *element;
if (localName != NULL) {
- JSLOG("Creating text node for string \"%s\"", localName);
+ JSDBG("Creating text node for string \"%s\"", localName);
exc = dom_string_create((unsigned char*)localName, localName_len, &localName_dom);
if (exc != DOM_NO_ERR) {
return JS_FALSE;
@@ -310,7 +340,7 @@ operation createElement %{
jsret = jsapi_new_HTMLElement(cx, NULL, NULL, element, private->htmlc);
}
- JSLOG("returning jsobject %p",jsret);
+ JSDBG("returning jsobject %p",jsret);
%}
diff --git a/javascript/jsapi/htmlelement.bnd b/javascript/jsapi/htmlelement.bnd
index 5e22f7e..33b4951 100644
--- a/javascript/jsapi/htmlelement.bnd
+++ b/javascript/jsapi/htmlelement.bnd
@@ -29,6 +29,7 @@ preamble %{
#include "htmlelement.h"
#include "text.h"
#include "location.h"
+#include "nodelist.h"
%}
@@ -114,6 +115,9 @@ binding htmlelement {
private "dom_element *" node;
private "struct html_content *" htmlc;
+ /* tag name retrieved first time its fetched and doesnt change */
+ property unshared tagName;
+
/* events through a single interface */
property unshared type EventHandler;
}
@@ -126,6 +130,180 @@ api finalise %{
/* interface Element in dom idl */
+/* readonly attribute DOMString Element::tagName; */
+getter tagName %{
+ if (!JSVAL_IS_VOID(JSAPI_PROP_RVAL(cx, vp))) {
+ /* already created - return it */
+ return JS_TRUE;
+ }
+
+ dom_exception exc;
+ dom_string *name;
+
+ exc = dom_element_get_tag_name(private->node, &name);
+ if (name != NULL) {
+ jsret = JS_NewStringCopyN(cx, dom_string_data(name), dom_string_length(name));
+ dom_string_unref(name);
+ }
+%}
+
+/* attribute DOMString Element::id; */
+getter id %{
+ dom_string *value;
+ dom_exception exc;
+
+ exc = dom_element_get_attribute(private->node, corestring_dom_id, &value);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ if (value != NULL) {
+ jsret = JS_NewStringCopyN(cx, dom_string_data(value), dom_string_length(value));
+ dom_string_unref(value);
+ }
+%}
+
+/* attribute DOMString Element::className; */
+getter className %{
+ dom_string *value;
+ dom_exception exc;
+
+ exc = dom_element_get_attribute(private->node, corestring_dom_class, &value);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ if (value != NULL) {
+ jsret = JS_NewStringCopyN(cx, dom_string_data(value), dom_string_length(value));
+ dom_string_unref(value);
+ }
+%}
+
+/* DOMString? Element::getAttribute(DOMString name); */
+operation getAttribute %{
+ dom_string *value;
+ dom_string *name_dom;
+ dom_exception exc;
+
+ exc = dom_string_create((unsigned char*)name, name_len, &name_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ exc = dom_element_get_attribute(private->node, name_dom, &value);
+ dom_string_unref(name_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ if (value != NULL) {
+ jsret = JS_NewStringCopyN(cx, dom_string_data(value), dom_string_length(value));
+ dom_string_unref(value);
+ }
+%}
+
+/* void Element::setAttribute(DOMString name, DOMString value); */
+operation setAttribute %{
+ dom_string *value_dom;
+ dom_string *name_dom;
+ dom_exception exc;
+
+ exc = dom_string_create((unsigned char*)name, name_len, &name_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ exc = dom_string_create((unsigned char*)name, name_len, &value_dom);
+ if (exc != DOM_NO_ERR) {
+ dom_string_unref(name_dom);
+ return JS_FALSE;
+ }
+
+ exc = dom_element_set_attribute(private->node, name_dom, value_dom);
+ dom_string_unref(name_dom);
+ dom_string_unref(value_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+%}
+
+/* void Element::removeAttribute(DOMString name); */
+operation removeAttribute %{
+ dom_string *name_dom;
+ dom_exception exc;
+
+ exc = dom_string_create((unsigned char*)name, name_len, &name_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ exc = dom_element_remove_attribute(private->node, name_dom);
+ dom_string_unref(name_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+%}
+
+/* boolean Element::hasAttribute(DOMString name); */
+operation hasAttribute %{
+ bool result;
+ dom_string *name_dom;
+ dom_exception exc;
+
+ exc = dom_string_create((unsigned char*)name, name_len, &name_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ exc = dom_element_has_attribute(private->node, name_dom, &result);
+ dom_string_unref(name_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ if (result) {
+ jsret = JS_TRUE;
+ }
+%}
+
+/*
+ *
+ * Dom 4 says this should return a htmlcollection, libdom currently
+ * returns DOM 3 spec of a nodelist
+ */
+/* HTMLCollection Element::getElementsByTagName(DOMString localName); */
+operation getElementsByTagName %{
+ dom_string *localName_dom;
+ /* dom_html_collection *collection;*/
+ dom_nodelist *nodelist;
+ dom_exception exc;
+
+ exc = dom_string_create((uint8_t *)localName, localName_len, &localName_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ exc = dom_element_get_elements_by_tag_name(private->node, localName_dom, /*&collection*/&nodelist);
+ dom_string_unref(localName_dom);
+ if (exc != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ if (/*collection*/nodelist != NULL) {
+ /*jsret = jsapi_new_HTMLCollection(cx,
+ NULL,
+ NULL,
+ collection,
+ private->htmlc);*/
+ jsret = jsapi_new_NodeList(cx,
+ NULL,
+ NULL,
+ nodelist,
+ private->htmlc);
+ }
+
+%}
+
/*
* DOM 3 has these as the element traversal extension
*
diff --git a/javascript/jsapi/nodelist.bnd b/javascript/jsapi/nodelist.bnd
index 4aa8c47..3798096 100644
--- a/javascript/jsapi/nodelist.bnd
+++ b/javascript/jsapi/nodelist.bnd
@@ -39,6 +39,41 @@ binding nodelist {
private "struct html_content *" htmlc;
}
+api finalise %{
+ if (private != NULL) {
+ dom_nodelist_unref(private->nodelist);
+ }
+%}
+
+/* default handler for numericaly indexed property values */
+api getproperty %{
+ jsval queryprop;
+ int idx;
+ JSObject *jsret = NULL; /* Node */
+ dom_exception err;
+ dom_node *domnode;
+
+ JSAPI_PROP_IDVAL(cx, &queryprop);
+ if (JSVAL_IS_INT(queryprop)) {
+ idx = JSVAL_TO_INT(queryprop);
+ JSDBG("Index was %d", idx);
+
+
+ err = dom_nodelist_item(private->nodelist, idx, &domnode);
+ if (err != DOM_NO_ERR) {
+ return JS_FALSE;
+ }
+
+ if (domnode != NULL) {
+ jsret = jsapi_new_HTMLElement(cx, NULL, NULL, (dom_element *)domnode, private->htmlc);
+
+ JSDBG("return object:%p", jsret);
+
+ JSAPI_PROP_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(jsret));
+ }
+ }
+%}
+
getter length %{
dom_exception err;
@@ -62,9 +97,3 @@ operation item %{
}
%}
-api finalise %{
- if (private != NULL) {
- dom_nodelist_unref(private->nodelist);
- }
-%}
-
diff --git a/render/textinput.c b/render/textinput.c
index 71b4e53..e9c6df7 100644
--- a/render/textinput.c
+++ b/render/textinput.c
@@ -1380,12 +1380,12 @@ bool textinput_textarea_callback(struct browser_window *bw, uint32_t key,
case KEY_PASTE:
{
- char *buff;
+ char *buff = NULL;
size_t buff_len;
bool success;
gui_get_clipboard(&buff, &buff_len);
- if (utf8 == NULL)
+ if (buff == NULL)
return false;
success = browser_window_paste_text(bw, buff, buff_len, true);
@@ -2027,12 +2027,12 @@ bool textinput_input_callback(struct browser_window *bw, uint32_t key,
case KEY_PASTE:
{
- char *buff;
+ char *buff = NULL;
size_t buff_len;
bool success;
gui_get_clipboard(&buff, &buff_len);
- if (utf8 == NULL)
+ if (buff == NULL)
return false;
success = browser_window_paste_text(bw, buff, buff_len, true);
diff --git a/riscos/distribution/!System/310/Modules/Iconv,ffa b/riscos/distribution/!System/310/Modules/Iconv,ffa
index b3eb47e..8a9cc3a 100644
--- a/riscos/distribution/!System/310/Modules/Iconv,ffa
+++ b/riscos/distribution/!System/310/Modules/Iconv,ffa
Binary files differ
diff --git a/riscos/distribution/3rdParty/Iconv/ReadMe b/riscos/distribution/3rdParty/Iconv/ReadMe
index fda952a..907c2c7 100644
--- a/riscos/distribution/3rdParty/Iconv/ReadMe
+++ b/riscos/distribution/3rdParty/Iconv/ReadMe
@@ -24,7 +24,7 @@ See the ReadMe file in that directory for further information.
Licence
=======
-Iconv is Copyright © 2004-11 J-M Bell
+Iconv is Copyright © 2004-13 J-M Bell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/riscos/distribution/3rdParty/Iconv/doc/ChangeLog b/riscos/distribution/3rdParty/Iconv/doc/ChangeLog
index 4c17511..3a22a45 100644
--- a/riscos/distribution/3rdParty/Iconv/doc/ChangeLog
+++ b/riscos/distribution/3rdParty/Iconv/doc/ChangeLog
@@ -105,3 +105,10 @@ Iconv Changelog
- Toolchain used to build 0.10 turns out to have produced broken code.
- Minor additions to the charset alias mapping file.
+0.12 20-Jan-2013
+---------------
+
+ - Master alias mapping file now lives in ROOL repository.
+ - Correct handling of trailing valid shift sequences. Previously would
+ erroneously report EINVAL, instead of silently accepting them.
+ - Add proper transliteration behaviour when requested using //TRANSLIT.
diff --git a/riscos/filetype.c b/riscos/filetype.c
index ec15b36..529f867 100644
--- a/riscos/filetype.c
+++ b/riscos/filetype.c
@@ -305,9 +305,21 @@ int ro_content_native_type(hlcache_handle *c)
*/
int ro_content_filetype_from_mime_type(lwc_string *mime_type)
{
- int file_type;
+ int file_type, index;
os_error *error;
+ /* Search internal type map */
+ for (index = TYPE_MAP_COUNT; index > 0; index--) {
+ const struct type_entry *e = &type_map[index - 1];
+
+ if (strlen(e->mime_type) == lwc_string_length(mime_type) &&
+ strncasecmp(e->mime_type,
+ lwc_string_data(mime_type),
+ lwc_string_length(mime_type)) == 0)
+ return e->file_type;
+ }
+
+ /* Ask MimeMap module */
error = xmimemaptranslate_mime_type_to_filetype(
lwc_string_data(mime_type), (bits *) &file_type);
if (error)
diff --git a/riscos/font.c b/riscos/font.c
index 717b960..8d4c6d3 100644
--- a/riscos/font.c
+++ b/riscos/font.c
@@ -255,6 +255,7 @@ bool nsfont_width(const plot_font_style_t *fstyle,
else
LOG(("rufl_width: 0x%x", code));
/* warn_user("MiscError", "font error"); */
+ *width = 0;
return false;
}
@@ -303,6 +304,8 @@ bool nsfont_position_in_string(const plot_font_style_t *fstyle,
else
LOG(("rufl_x_to_offset: 0x%x", code));
/* warn_user("MiscError", "font error"); */
+ *char_offset = 0;
+ *actual_x = 0;
return false;
}
@@ -355,11 +358,27 @@ bool nsfont_split(const plot_font_style_t *fstyle,
else
LOG(("rufl_split: 0x%x", code));
/* warn_user("MiscError", "font error"); */
+ *char_offset = 0;
+ *actual_x = 0;
return false;
}
- while (*char_offset && string[*char_offset] != ' ')
- (*char_offset)--;
+ if (*char_offset != length) {
+ /* we found something to split at */
+ size_t orig = *char_offset;
+
+ /* ensure a space at <= the split point we found */
+ while (*char_offset && string[*char_offset] != ' ')
+ (*char_offset)--;
+
+ /* nothing valid found <= split point, advance to next space */
+ if (*char_offset == 0) {
+ *char_offset = orig;
+ while (*char_offset != length &&
+ string[*char_offset] != ' ')
+ (*char_offset)++;
+ }
+ }
code = rufl_width(font_family, font_style, font_size,
string, *char_offset,
@@ -372,6 +391,8 @@ bool nsfont_split(const plot_font_style_t *fstyle,
else
LOG(("rufl_width: 0x%x", code));
/* warn_user("MiscError", "font error"); */
+ *char_offset = 0;
+ *actual_x = 0;
return false;
}
diff --git a/riscos/gui.c b/riscos/gui.c
index 8eac42d..e786f67 100644
--- a/riscos/gui.c
+++ b/riscos/gui.c
@@ -944,6 +944,8 @@ void ro_gui_cleanup(void)
{
ro_gui_buffer_close();
xhourglass_off();
+ /* Uninstall NetSurf-specific fonts */
+ xos_cli("FontRemove NetSurf:Resources.Fonts.");
}
@@ -1280,6 +1282,22 @@ void ro_gui_drag_end(wimp_dragged *drag)
* Handle Key_Pressed events.
*/
+static void ro_gui_keypress_cb(void *pw)
+{
+ wimp_key *key = (wimp_key *) pw;
+
+ if (ro_gui_wimp_event_keypress(key) == false) {
+ os_error *error = xwimp_process_key(key->c);
+ if (error) {
+ LOG(("xwimp_process_key: 0x%x: %s",
+ error->errnum, error->errmess));
+ warn_user("WimpError", error->errmess);
+ }
+ }
+
+ free(key);
+}
+
void ro_gui_keypress(wimp_key *key)
{
if (key->c == wimp_KEY_ESCAPE &&
@@ -1290,8 +1308,17 @@ void ro_gui_keypress(wimp_key *key)
(easier than finding somewhere safe to abort the drag) */
ro_gui_drag_box_cancel();
gui_current_drag_type = GUI_DRAG_NONE;
- }
- else if (!ro_gui_wimp_event_keypress(key)) {
+ } else if (key->c == 22 /* Ctrl-V */) {
+ wimp_key *copy;
+
+ /* Must copy the keypress as it's on the stack */
+ copy = malloc(sizeof(wimp_key));
+ if (copy == NULL)
+ return;
+ memcpy(copy, key, sizeof(wimp_key));
+
+ ro_gui_selection_prepare_paste(key->w, ro_gui_keypress_cb, copy);
+ } else if (ro_gui_wimp_event_keypress(key) == false) {
os_error *error = xwimp_process_key(key->c);
if (error) {
LOG(("xwimp_process_key: 0x%x: %s",
@@ -1318,9 +1345,10 @@ void ro_gui_user_message(wimp_event_no event, wimp_message *message)
if (event == wimp_USER_MESSAGE_ACKNOWLEDGE) {
if (ro_print_current_window)
ro_print_dataload_bounce(message);
- }
- else
+ } else if (ro_gui_selection_prepare_paste_dataload(
+ (wimp_full_message_data_xfer *) message) == false) {
ro_msg_dataload(message);
+ }
break;
case message_DATA_LOAD_ACK:
@@ -1770,6 +1798,9 @@ void ro_msg_datasave(wimp_message *message)
ro_msg_terminate_filename(dataxfer);
+ if (ro_gui_selection_prepare_paste_datasave(dataxfer))
+ return;
+
switch (dataxfer->file_type) {
case FILETYPE_ACORN_URI:
case FILETYPE_ANT_URL:
diff --git a/riscos/save.c b/riscos/save.c
index f61fd01..12af6ab 100644
--- a/riscos/save.c
+++ b/riscos/save.c
@@ -1239,6 +1239,11 @@ void ro_gui_save_set_state(hlcache_handle *h, gui_save_type save_type,
}
/* filename is utf8 */
+ if (save_type == GUI_SAVE_COMPLETE && leaf_len > 0) {
+ leaf_buf[0] = '!';
+ leaf_buf++;
+ leaf_len--;
+ }
strncpy(leaf_buf, name, leaf_len);
leaf_buf[leaf_len - 1] = 0;
diff --git a/riscos/scripts/Run b/riscos/scripts/Run
index d3b9988..8f3b873 100644
--- a/riscos/scripts/Run
+++ b/riscos/scripts/Run
@@ -88,12 +88,12 @@ RMEnsure Tinct 0.13 Error NetSurf requires Tinct 0.13 or later. This can be down
| Ensure Iconv
| http://www.netsurf-browser.org/iconv/
-RMEnsure Iconv 0.11 NetSurfRMLoad System:Modules.Iconv
-RMEnsure Iconv 0.11 Error NetSurf requires Iconv 0.11 or later. This can be downloaded from http://www.netsurf-browser.org/iconv/
+RMEnsure Iconv 0.12 NetSurfRMLoad System:Modules.Iconv
+RMEnsure Iconv 0.12 Error NetSurf requires Iconv 0.12 or later. This can be downloaded from http://www.netsurf-browser.org/iconv/
| Ensure CryptRandom
-RMEnsure CryptRandom 0.12 NetSurfRMLoad System:Modules.CryptRand
-RMEnsure CryptRandom 0.12 Error NetSurf requires CryptRandom 0.12 or later. This can be downloaded from http://www.riscos.info/index.php/CryptRandom
+RMEnsure CryptRandom 0.13 NetSurfRMLoad System:Modules.CryptRand
+RMEnsure CryptRandom 0.13 Error NetSurf requires CryptRandom 0.13 or later. This can be downloaded from http://www.markettos.org.uk/riscos/crypto/
| Disable SpecialFX, if present
Set NetSurf$SpecialFX 1
@@ -114,6 +114,3 @@ FontInstall NetSurf:Resources.Fonts.
WIMPSLOT
Run <NetSurf$Dir>.!RunImage %*0 2><Wimp$ScrapDir>.WWW.NetSurf.Log
-
-| Uninstall NetSurf-specific fonts
-FontRemove NetSurf:Resources.Fonts.
diff --git a/riscos/textselection.c b/riscos/textselection.c
index d1d4340..0cb8eb2 100644
--- a/riscos/textselection.c
+++ b/riscos/textselection.c
@@ -56,11 +56,17 @@ static bool drag_claimed = false;
static bool owns_clipboard = false;
static bool owns_caret_and_selection = false;
-/* current clipboard contents if we own the clipboard */
+/* Current clipboard contents if we own the clipboard
+ * Current paste buffer if we don't
+ */
static char *clipboard = NULL;
-static size_t clip_alloc = 0;
static size_t clip_length = 0;
+/* Paste context */
+static ro_gui_selection_prepare_paste_cb paste_cb = NULL;
+static void *paste_cb_pw = NULL;
+static int paste_prev_message = 0;
+
static void ro_gui_discard_clipboard_contents(void);
static void ro_gui_dragging_bounced(wimp_message *message);
@@ -207,22 +213,21 @@ void gui_clear_selection(struct gui_window *g)
void gui_set_clipboard(const char *buffer, size_t length,
nsclipboard_styles styles[], int n_styles)
{
- utf8_convert_ret res;
char *new_cb;
if (length == 0)
return;
- /* Convert to local encoding */
- res = utf8_to_local_encoding(buffer, length, &new_cb);
-
- if (res != UTF8_CONVERT_OK || new_cb == NULL)
+ new_cb = malloc(length);
+ if (new_cb == NULL)
return;
- /* Replace existing clipboard contents with converted text */
+ memcpy(new_cb, buffer, length);
+
+ /* Replace existing clipboard contents */
free(clipboard);
clipboard = new_cb;
- clip_alloc = clip_length = strlen(new_cb);
+ clip_length = length;
if (!owns_clipboard) {
/* Tell RO we now own clipboard */
@@ -253,7 +258,7 @@ void gui_set_clipboard(const char *buffer, size_t length,
/**
* Core asks front end for clipboard contents.
*
- * \param buffer UTF-8 text, allocated by front end, ownership yeilded to core
+ * \param buffer UTF-8 text, allocated by front end, ownership yielded to core
* \param length Byte length of UTF-8 text in buffer
*/
void gui_get_clipboard(char **buffer, size_t *length)
@@ -261,64 +266,180 @@ void gui_get_clipboard(char **buffer, size_t *length)
*buffer = NULL;
*length = 0;
- if (owns_clipboard) {
- if (clip_length > 0) {
- char *utf8;
- utf8_convert_ret ret;
- /* Clipboard is in local encoding so
- * convert to UTF8 */
- ret = utf8_from_local_encoding(clipboard,
- clip_length, &utf8);
- if (ret == UTF8_CONVERT_OK) {
- *buffer = utf8;
- *length = strlen(utf8);
- }
+ if (clip_length > 0) {
+ char *cb = malloc(clip_length);
+ if (cb != NULL) {
+ memcpy(cb, clipboard, clip_length);
+ *buffer = cb;
+ *length = clip_length;
}
- } else {
- /** TODO: Handle case when we don't own the clipboard */
+ }
+}
+
-/* http://www.starfighter.acornarcade.com/mysite/articles/SelectionModel.html
+/**
+ * Discard the current contents of the clipboard, if any, releasing the
+ * memory it uses.
*/
-/* wimp_full_message_data_request msg;
- os_error *error;
- os_coord pos;
+void ro_gui_discard_clipboard_contents(void)
+{
+ free(clipboard);
+ clip_length = 0;
+}
+
- if (!ro_gui_window_to_screen_pos(g, x, y, &pos))
- return;
+static void ro_gui_selection_prepare_paste_complete(void)
+{
+ ro_gui_selection_prepare_paste_cb cb = paste_cb;
+ void *pw = paste_cb_pw;
+
+ paste_cb = NULL;
+ paste_cb_pw = NULL;
+ paste_prev_message = 0;
+
+ cb(pw);
+}
+
+static void ro_gui_selection_prepare_paste_bounced(wimp_message *message)
+{
+ ro_gui_selection_prepare_paste_complete();
+}
+
+/**
+ * Prepare to paste data from another application
+ *
+ * \param w Window being pasted into
+ * \param cb Callback to call once preparation is complete
+ * \param pw Private data for callback
+ */
+
+void ro_gui_selection_prepare_paste(wimp_w w,
+ ro_gui_selection_prepare_paste_cb cb, void *pw)
+{
+ if (owns_clipboard) {
+ /* We own the clipboard: we're already prepared */
+ cb(pw);
+ } else {
+ /* Someone else owns the clipboard: request its contents */
+ wimp_full_message_data_request msg;
+ bool success;
+
+ ro_gui_discard_clipboard_contents();
msg.size = sizeof(msg);
msg.your_ref = 0;
msg.action = message_DATA_REQUEST;
- msg.w = g->window;
+ msg.w = w;
msg.i = -1;
- msg.pos.x = pos.x;
- msg.pos.y = pos.y;
+ msg.pos.x = 0;
+ msg.pos.y = 0;
msg.flags = wimp_DATA_REQUEST_CLIPBOARD;
msg.file_types[0] = osfile_TYPE_TEXT;
msg.file_types[1] = ~0;
- error = xwimp_send_message(wimp_USER_MESSAGE,
- (wimp_message*)&msg, wimp_BROADCAST);
- if (error) {
- LOG(("xwimp_send_message: 0x%x : %s",
- error->errnum, error->errmess));
- warn_user("WimpError", error->errmess);
+ success = ro_message_send_message(wimp_USER_MESSAGE_RECORDED,
+ (wimp_message *) &msg, wimp_BROADCAST,
+ ro_gui_selection_prepare_paste_bounced);
+ if (success == false) {
+ /* Ensure key is handled, anyway */
+ cb(pw);
+ } else {
+ /* Set up paste context */
+ paste_cb = cb;
+ paste_cb_pw = pw;
+ paste_prev_message = msg.my_ref;
}
-*/ }
+ }
}
-
/**
- * Discard the current contents of the clipboard, if any, releasing the
- * memory it uses.
+ * Prepare to paste data from another application (step 2)
+ *
+ * \param dataxfer DataSave message
+ * \return True if message was handled, false otherwise
*/
+bool ro_gui_selection_prepare_paste_datasave(
+ wimp_full_message_data_xfer *dataxfer)
+{
+ bool success;
-void ro_gui_discard_clipboard_contents(void)
+ /* Ignore messages that aren't for us */
+ if (dataxfer->your_ref == 0 || dataxfer->your_ref != paste_prev_message)
+ return false;
+
+ /* We're done if the paste data isn't text */
+ if (dataxfer->file_type != osfile_TYPE_TEXT) {
+ ro_gui_selection_prepare_paste_complete();
+ return true;
+ }
+
+ /* Generate and send DataSaveAck */
+ dataxfer->your_ref = dataxfer->my_ref;
+ dataxfer->size = offsetof(wimp_full_message_data_xfer, file_name) + 16;
+ dataxfer->action = message_DATA_SAVE_ACK;
+ dataxfer->est_size = -1;
+ memcpy(dataxfer->file_name, "<Wimp$Scrap>", SLEN("<Wimp$Scrap>") + 1);
+
+ success = ro_message_send_message(wimp_USER_MESSAGE_RECORDED,
+ (wimp_message *) dataxfer, dataxfer->sender,
+ ro_gui_selection_prepare_paste_bounced);
+ if (success == false) {
+ ro_gui_selection_prepare_paste_complete();
+ } else {
+ paste_prev_message = dataxfer->my_ref;
+ }
+
+ return true;
+}
+
+
+/**
+ * Prepare to paste data from another application (step 3)
+ *
+ * \param dataxfer DataLoad message
+ * \return True if message was handled, false otherwise
+ */
+bool ro_gui_selection_prepare_paste_dataload(
+ wimp_full_message_data_xfer *dataxfer)
{
- if (clip_alloc) free(clipboard);
- clip_alloc = 0;
- clip_length = 0;
+ FILE *fp;
+ long size;
+ char *local_cb;
+ utf8_convert_ret ret;
+
+ /* Ignore messages that aren't for us */
+ if (dataxfer->your_ref == 0 || dataxfer->your_ref != paste_prev_message)
+ return false;
+
+ fp = fopen(dataxfer->file_name, "r");
+ if (fp != NULL) {
+ fseek(fp, 0, SEEK_END);
+ size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ local_cb = malloc(size);
+ if (local_cb != NULL) {
+ fread(local_cb, 1, size, fp);
+
+ fclose(fp);
+
+ ret = utf8_from_local_encoding(local_cb, size,
+ &clipboard);
+ if (ret == UTF8_CONVERT_OK) {
+ clip_length = strlen(clipboard);
+ }
+ }
+ }
+
+ /* Send DataLoadAck */
+ dataxfer->action = message_DATA_LOAD_ACK;
+ dataxfer->your_ref = dataxfer->my_ref;
+ ro_message_send_message(wimp_USER_MESSAGE,
+ (wimp_message *) dataxfer, dataxfer->sender, NULL);
+
+ ro_gui_selection_prepare_paste_complete();
+ return true;
}
@@ -398,18 +519,31 @@ void ro_gui_selection_data_request(wimp_full_message_data_request *req)
bool ro_gui_save_clipboard(const char *path)
{
+ char *local_cb;
+ utf8_convert_ret ret;
os_error *error;
assert(clip_length > 0 && clipboard);
+
+ ret = utf8_to_local_encoding(clipboard, clip_length, &local_cb);
+ if (ret != UTF8_CONVERT_OK) {
+ warn_user("SaveError", "Could not convert");
+ return false;
+ }
+
error = xosfile_save_stamped(path, osfile_TYPE_TEXT,
- (byte*)clipboard,
- (byte*)clipboard + clip_length);
+ (byte*) local_cb,
+ (byte*) local_cb + strlen(local_cb));
+
+ free(local_cb);
+
if (error) {
LOG(("xosfile_save_stamped: 0x%x: %s",
error->errnum, error->errmess));
warn_user("SaveError", error->errmess);
return false;
}
+
return true;
}
diff --git a/riscos/textselection.h b/riscos/textselection.h
index 544636e..a3763b4 100644
--- a/riscos/textselection.h
+++ b/riscos/textselection.h
@@ -26,6 +26,14 @@
#include "oslib/wimp.h"
#include "desktop/gui.h"
+typedef void (*ro_gui_selection_prepare_paste_cb)(void *pw);
+
+void ro_gui_selection_prepare_paste(wimp_w w,
+ ro_gui_selection_prepare_paste_cb cb, void *pw);
+bool ro_gui_selection_prepare_paste_datasave(
+ wimp_full_message_data_xfer *dataxfer);
+bool ro_gui_selection_prepare_paste_dataload(
+ wimp_full_message_data_xfer *dataxfer);
void ro_gui_selection_drag_end(struct gui_window *g, wimp_dragged *drag);
void ro_gui_selection_claim_entity(wimp_full_message_claim_entity *claim);
diff --git a/riscos/window.c b/riscos/window.c
index 5351054..2f8bec6 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -74,6 +74,7 @@
#include "riscos/oslib_pre7.h"
#include "riscos/save.h"
#include "riscos/content-handlers/sprite.h"
+#include "riscos/textselection.h"
#include "riscos/toolbar.h"
#include "riscos/thumbnail.h"
#include "riscos/url_complete.h"
@@ -2600,6 +2601,14 @@ void ro_gui_window_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu,
}
+static void ro_gui_window_paste_cb(void *pw)
+{
+ struct browser_window *bw = pw;
+
+ browser_window_key_press(bw, KEY_PASTE);
+}
+
+
/**
* Handle selections from a browser window menu
*
@@ -2833,7 +2842,7 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu,
browser_window_key_press(bw, KEY_CUT_SELECTION);
break;
case BROWSER_SELECTION_PASTE:
- browser_window_key_press(bw, KEY_PASTE);
+ ro_gui_selection_prepare_paste(w, ro_gui_window_paste_cb, bw);
break;
case BROWSER_SELECTION_ALL:
browser_window_key_press(bw, KEY_SELECT_ALL);
diff --git a/test/js/dom-getElementsByTagName.html b/test/js/dom-getElementsByTagName.html
index 02cdffc..2f03e7b 100644
--- a/test/js/dom-getElementsByTagName.html
+++ b/test/js/dom-getElementsByTagName.html
@@ -15,6 +15,16 @@
for (var i=0;i<pcol.length;i++)
{
document.write(pcol.item(i).textContent);
+document.write("|");
+}
+</script>
+<br>
+<p>
+<script>
+for (var i=0;i<pcol.length;i++)
+{
+document.write(pcol[i].textContent);
+document.write("|");
}
</script>
</body>
diff --git a/utils/corestrings.c b/utils/corestrings.c
index 65666df..f39a59c 100644
--- a/utils/corestrings.c
+++ b/utils/corestrings.c
@@ -134,6 +134,7 @@ dom_string *corestring_dom_cellpadding;
dom_string *corestring_dom_cellspacing;
dom_string *corestring_dom_change;
dom_string *corestring_dom_charset;
+dom_string *corestring_dom_class;
dom_string *corestring_dom_click;
dom_string *corestring_dom_close;
dom_string *corestring_dom_color;
@@ -357,6 +358,7 @@ void corestrings_fini(void)
CSS_DOM_STRING_UNREF(cellspacing);
CSS_DOM_STRING_UNREF(change);
CSS_DOM_STRING_UNREF(charset);
+ CSS_DOM_STRING_UNREF(class);
CSS_DOM_STRING_UNREF(click);
CSS_DOM_STRING_UNREF(close);
CSS_DOM_STRING_UNREF(color);
@@ -611,6 +613,7 @@ nserror corestrings_init(void)
CSS_DOM_STRING_INTERN(cellspacing);
CSS_DOM_STRING_INTERN(change);
CSS_DOM_STRING_INTERN(charset);
+ CSS_DOM_STRING_INTERN(class);
CSS_DOM_STRING_INTERN(click);
CSS_DOM_STRING_INTERN(close);
CSS_DOM_STRING_INTERN(color);
diff --git a/utils/corestrings.h b/utils/corestrings.h
index 08d2545..e28b713 100644
--- a/utils/corestrings.h
+++ b/utils/corestrings.h
@@ -140,6 +140,7 @@ extern struct dom_string *corestring_dom_cellpadding;
extern struct dom_string *corestring_dom_cellspacing;
extern struct dom_string *corestring_dom_change;
extern struct dom_string *corestring_dom_charset;
+extern struct dom_string *corestring_dom_class;
extern struct dom_string *corestring_dom_click;
extern struct dom_string *corestring_dom_close;
extern struct dom_string *corestring_dom_color;
diff --git a/utils/nsurl.c b/utils/nsurl.c
index 18577b6..23e177e 100644
--- a/utils/nsurl.c
+++ b/utils/nsurl.c
@@ -720,6 +720,9 @@ static nserror nsurl__create_from_section(const char * const url_s,
break;
}
+ if (end < start)
+ end = start;
+
length = end - start;
/* Stage 1: Normalise the required section */
diff --git a/utils/transtab b/utils/transtab
deleted file mode 100644
index ccb0017..0000000
--- a/utils/transtab
+++ b/dev/null
@@ -1,1688 +0,0 @@
-% Source: http://www.cl.cam.ac.uk/~mgk25/unicode.html#libs
-%
-% "This package contains a table for transliterating ISO 10646 texts into
-% best-effort representations using smaller coded character sets (ASCII,
-% ISO 8859, etc.). It is primarily intended for inclusion into the GNU C
-% library, but might be of use for other applications as well. The table
-% is freely available to anyone."
-
-% APOSTROPHE
-<U0027> <U2019>
-% GRAVE ACCENT
-<U0060> <U201B>;<U2018>
-% NO-BREAK SPACE
-<U00A0> <U0020>
-% INVERTED EXCLAMATION MARK
-<U00A1> <U0021>
-% CENT SIGN
-<U00A2> <U0063>
-% POUND SIGN
-<U00A3> "<U0047><U0042><U0050>"
-% YEN SIGN
-<U00A5> <U0059>
-% BROKEN BAR
-<U00A6> <U007C>
-% SECTION SIGN
-<U00A7> <U0053>
-% DIAERESIS
-<U00A8> <U0022>
-% COPYRIGHT SIGN
-<U00A9> "<U0028><U0063><U0029>";<U0063>
-% FEMININE ORDINAL INDICATOR
-<U00AA> <U0061>
-% LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
-<U00AB> "<U003C><U003C>"
-% NOT SIGN
-<U00AC> <U002D>
-% SOFT HYPHEN
-<U00AD> <U002D>
-% REGISTERED SIGN
-<U00AE> "<U0028><U0052><U0029>"
-% MACRON
-<U00AF> <U002D>
-% DEGREE SIGN
-<U00B0> <U0020>
-% PLUS-MINUS SIGN
-<U00B1> "<U002B><U002F><U002D>"
-% SUPERSCRIPT TWO
-<U00B2> "<U005E><U0032>";<U0032>
-% SUPERSCRIPT THREE
-<U00B3> "<U005E><U0033>";<U0033>
-% ACUTE ACCENT
-<U00B4> <U0027>
-% MICRO SIGN
-<U00B5> <U03BC>;<U0075>
-% PILCROW SIGN
-<U00B6> <U0050>
-% MIDDLE DOT
-<U00B7> <U002E>
-% CEDILLA
-<U00B8> <U002C>
-% SUPERSCRIPT ONE
-<U00B9> "<U005E><U0031>";<U0031>
-% MASCULINE ORDINAL INDICATOR
-<U00BA> <U006F>
-% RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
-<U00BB> "<U003E><U003E>"
-% VULGAR FRACTION ONE QUARTER
-<U00BC> "<U0020><U0031><U002F><U0034>"
-% VULGAR FRACTION ONE HALF
-<U00BD> "<U0020><U0031><U002F><U0032>"
-% VULGAR FRACTION THREE QUARTERS
-<U00BE> "<U0020><U0033><U002F><U0034>"
-% INVERTED QUESTION MARK
-<U00BF> <U003F>
-% LATIN CAPITAL LETTER A WITH GRAVE
-<U00C0> <U0041>
-% LATIN CAPITAL LETTER A WITH ACUTE
-<U00C1> <U0041>
-% LATIN CAPITAL LETTER A WITH CIRCUMFLEX
-<U00C2> <U0041>
-% LATIN CAPITAL LETTER A WITH TILDE
-<U00C3> <U0041>
-% LATIN CAPITAL LETTER A WITH DIAERESIS
-<U00C4> "<U0041><U0065>";<U0041>
-% LATIN CAPITAL LETTER A WITH RING ABOVE
-<U00C5> "<U0041><U0061>";<U0041>
-% LATIN CAPITAL LETTER AE
-<U00C6> "<U0041><U0045>";<U0041>
-% LATIN CAPITAL LETTER C WITH CEDILLA
-<U00C7> <U0043>
-% LATIN CAPITAL LETTER E WITH GRAVE
-<U00C8> <U0045>
-% LATIN CAPITAL LETTER E WITH ACUTE
-<U00C9> <U0045>
-% LATIN CAPITAL LETTER E WITH CIRCUMFLEX
-<U00CA> <U0045>
-% LATIN CAPITAL LETTER E WITH DIAERESIS
-<U00CB> <U0045>
-% LATIN CAPITAL LETTER I WITH GRAVE
-<U00CC> <U0049>
-% LATIN CAPITAL LETTER I WITH ACUTE
-<U00CD> <U0049>
-% LATIN CAPITAL LETTER I WITH CIRCUMFLEX
-<U00CE> <U0049>
-% LATIN CAPITAL LETTER I WITH DIAERESIS
-<U00CF> <U0049>
-% LATIN CAPITAL LETTER ETH
-<U00D0> <U0044>
-% LATIN CAPITAL LETTER N WITH TILDE
-<U00D1> <U004E>
-% LATIN CAPITAL LETTER O WITH GRAVE
-<U00D2> <U004F>
-% LATIN CAPITAL LETTER O WITH ACUTE
-<U00D3> <U004F>
-% LATIN CAPITAL LETTER O WITH CIRCUMFLEX
-<U00D4> <U004F>
-% LATIN CAPITAL LETTER O WITH TILDE
-<U00D5> <U004F>
-% LATIN CAPITAL LETTER O WITH DIAERESIS
-<U00D6> "<U004F><U0065>";<U004F>
-% MULTIPLICATION SIGN
-<U00D7> <U0078>
-% LATIN CAPITAL LETTER O WITH STROKE
-<U00D8> <U004F>
-% LATIN CAPITAL LETTER U WITH GRAVE
-<U00D9> <U0055>
-% LATIN CAPITAL LETTER U WITH ACUTE
-<U00DA> <U0055>
-% LATIN CAPITAL LETTER U WITH CIRCUMFLEX
-<U00DB> <U0055>
-% LATIN CAPITAL LETTER U WITH DIAERESIS
-<U00DC> "<U0055><U0065>";<U0055>
-% LATIN CAPITAL LETTER Y WITH ACUTE
-<U00DD> <U0059>
-% LATIN CAPITAL LETTER THORN
-<U00DE> "<U0054><U0068>"
-% LATIN SMALL LETTER SHARP S
-<U00DF> "<U0073><U0073>";<U03B2>
-% LATIN SMALL LETTER A WITH GRAVE
-<U00E0> <U0061>
-% LATIN SMALL LETTER A WITH ACUTE
-<U00E1> <U0061>
-% LATIN SMALL LETTER A WITH CIRCUMFLEX
-<U00E2> <U0061>
-% LATIN SMALL LETTER A WITH TILDE
-<U00E3> <U0061>
-% LATIN SMALL LETTER A WITH DIAERESIS
-<U00E4> "<U0061><U0065>";<U0061>
-% LATIN SMALL LETTER A WITH RING ABOVE
-<U00E5> "<U0061><U0061>";<U0061>
-% LATIN SMALL LETTER AE
-<U00E6> "<U0061><U0065>";<U0061>
-% LATIN SMALL LETTER C WITH CEDILLA
-<U00E7> <U0063>
-% LATIN SMALL LETTER E WITH GRAVE
-<U00E8> <U0065>
-% LATIN SMALL LETTER E WITH ACUTE
-<U00E9> <U0065>
-% LATIN SMALL LETTER E WITH CIRCUMFLEX
-<U00EA> <U0065>
-% LATIN SMALL LETTER E WITH DIAERESIS
-<U00EB> <U0065>
-% LATIN SMALL LETTER I WITH GRAVE
-<U00EC> <U0069>
-% LATIN SMALL LETTER I WITH ACUTE
-<U00ED> <U0069>
-% LATIN SMALL LETTER I WITH CIRCUMFLEX
-<U00EE> <U0069>
-% LATIN SMALL LETTER I WITH DIAERESIS
-<U00EF> <U0069>
-% LATIN SMALL LETTER ETH
-<U00F0> <U0064>
-% LATIN SMALL LETTER N WITH TILDE
-<U00F1> <U006E>
-% LATIN SMALL LETTER O WITH GRAVE
-<U00F2> <U006F>
-% LATIN SMALL LETTER O WITH ACUTE
-<U00F3> <U006F>
-% LATIN SMALL LETTER O WITH CIRCUMFLEX
-<U00F4> <U006F>
-% LATIN SMALL LETTER O WITH TILDE
-<U00F5> <U006F>
-% LATIN SMALL LETTER O WITH DIAERESIS
-<U00F6> "<U006F><U0065>";<U006F>
-% DIVISION SIGN
-<U00F7> <U003A>
-% LATIN SMALL LETTER O WITH STROKE
-<U00F8> <U006F>
-% LATIN SMALL LETTER U WITH GRAVE
-<U00F9> <U0075>
-% LATIN SMALL LETTER U WITH ACUTE
-<U00FA> <U0075>
-% LATIN SMALL LETTER U WITH CIRCUMFLEX
-<U00FB> <U0075>
-% LATIN SMALL LETTER U WITH DIAERESIS
-<U00FC> "<U0075><U0065>";<U0075>
-% LATIN SMALL LETTER Y WITH ACUTE
-<U00FD> <U0079>
-% LATIN SMALL LETTER THORN
-<U00FE> "<U0074><U0068>"
-% LATIN SMALL LETTER Y WITH DIAERESIS
-<U00FF> <U0079>
-% LATIN CAPITAL LETTER A WITH MACRON
-<U0100> <U0041>
-% LATIN SMALL LETTER A WITH MACRON
-<U0101> <U0061>
-% LATIN CAPITAL LETTER A WITH BREVE
-<U0102> <U0041>
-% LATIN SMALL LETTER A WITH BREVE
-<U0103> <U0061>
-% LATIN CAPITAL LETTER A WITH OGONEK
-<U0104> <U0041>
-% LATIN SMALL LETTER A WITH OGONEK
-<U0105> <U0061>
-% LATIN CAPITAL LETTER C WITH ACUTE
-<U0106> <U0043>
-% LATIN SMALL LETTER C WITH ACUTE
-<U0107> <U0063>
-% LATIN CAPITAL LETTER C WITH CIRCUMFLEX
-<U0108> "<U0043><U0068>";<U0043>
-% LATIN SMALL LETTER C WITH CIRCUMFLEX
-<U0109> "<U0063><U0068>";<U0063>
-% LATIN CAPITAL LETTER C WITH DOT ABOVE
-<U010A> <U0043>
-% LATIN SMALL LETTER C WITH DOT ABOVE
-<U010B> <U0063>
-% LATIN CAPITAL LETTER C WITH CARON
-<U010C> <U0043>
-% LATIN SMALL LETTER C WITH CARON
-<U010D> <U0063>
-% LATIN CAPITAL LETTER D WITH CARON
-<U010E> <U0044>
-% LATIN SMALL LETTER D WITH CARON
-<U010F> <U0064>
-% LATIN CAPITAL LETTER D WITH STROKE
-<U0110> <U0044>
-% LATIN SMALL LETTER D WITH STROKE
-<U0111> <U0064>
-% LATIN CAPITAL LETTER E WITH MACRON
-<U0112> <U0045>
-% LATIN SMALL LETTER E WITH MACRON
-<U0113> <U0065>
-% LATIN CAPITAL LETTER E WITH BREVE
-<U0114> <U0045>
-% LATIN SMALL LETTER E WITH BREVE
-<U0115> <U0065>
-% LATIN CAPITAL LETTER E WITH DOT ABOVE
-<U0116> <U0045>
-% LATIN SMALL LETTER E WITH DOT ABOVE
-<U0117> <U0065>
-% LATIN CAPITAL LETTER E WITH OGONEK
-<U0118> <U0045>
-% LATIN SMALL LETTER E WITH OGONEK
-<U0119> <U0065>
-% LATIN CAPITAL LETTER E WITH CARON
-<U011A> <U0045>
-% LATIN SMALL LETTER E WITH CARON
-<U011B> <U0065>
-% LATIN CAPITAL LETTER G WITH CIRCUMFLEX
-<U011C> "<U0047><U0068>";<U0047>
-% LATIN SMALL LETTER G WITH CIRCUMFLEX
-<U011D> "<U0067><U0068>";<U0067>
-% LATIN CAPITAL LETTER G WITH BREVE
-<U011E> <U0047>
-% LATIN SMALL LETTER G WITH BREVE
-<U011F> <U0067>
-% LATIN CAPITAL LETTER G WITH DOT ABOVE
-<U0120> <U0047>
-% LATIN SMALL LETTER G WITH DOT ABOVE
-<U0121> <U0067>
-% LATIN CAPITAL LETTER G WITH CEDILLA
-<U0122> <U0047>
-% LATIN SMALL LETTER G WITH CEDILLA
-<U0123> <U0067>
-% LATIN CAPITAL LETTER H WITH CIRCUMFLEX
-<U0124> "<U0048><U0068>";<U0048>
-% LATIN SMALL LETTER H WITH CIRCUMFLEX
-<U0125> "<U0068><U0068>";<U0068>
-% LATIN CAPITAL LETTER H WITH STROKE
-<U0126> <U0048>
-% LATIN SMALL LETTER H WITH STROKE
-<U0127> <U0068>
-% LATIN CAPITAL LETTER I WITH TILDE
-<U0128> <U0049>
-% LATIN SMALL LETTER I WITH TILDE
-<U0129> <U0069>
-% LATIN CAPITAL LETTER I WITH MACRON
-<U012A> <U0049>
-% LATIN SMALL LETTER I WITH MACRON
-<U012B> <U0069>
-% LATIN CAPITAL LETTER I WITH BREVE
-<U012C> <U0049>
-% LATIN SMALL LETTER I WITH BREVE
-<U012D> <U0069>
-% LATIN CAPITAL LETTER I WITH OGONEK
-<U012E> <U0049>
-% LATIN SMALL LETTER I WITH OGONEK
-<U012F> <U0069>
-% LATIN CAPITAL LETTER I WITH DOT ABOVE
-<U0130> <U0049>
-% LATIN SMALL LETTER DOTLESS I
-<U0131> <U0069>
-% LATIN CAPITAL LIGATURE IJ
-<U0132> "<U0049><U004A>"
-% LATIN SMALL LIGATURE IJ
-<U0133> "<U0069><U006A>"
-% LATIN CAPITAL LETTER J WITH CIRCUMFLEX
-<U0134> "<U004A><U0068>";<U004A>
-% LATIN SMALL LETTER J WITH CIRCUMFLEX
-<U0135> "<U006A><U0068>";<U006A>
-% LATIN CAPITAL LETTER K WITH CEDILLA
-<U0136> <U004B>
-% LATIN SMALL LETTER K WITH CEDILLA
-<U0137> <U006B>
-% LATIN SMALL LETTER KRA
-<U0138> <U006B>
-% LATIN CAPITAL LETTER L WITH ACUTE
-<U0139> <U004C>
-% LATIN SMALL LETTER L WITH ACUTE
-<U013A> <U006C>
-% LATIN CAPITAL LETTER L WITH CEDILLA
-<U013B> <U004C>
-% LATIN SMALL LETTER L WITH CEDILLA
-<U013C> <U006C>
-% LATIN CAPITAL LETTER L WITH CARON
-<U013D> <U004C>
-% LATIN SMALL LETTER L WITH CARON
-<U013E> <U006C>
-% LATIN CAPITAL LETTER L WITH MIDDLE DOT
-<U013F> "<U004C><U00B7>";"<U004C><U002E>";<U004C>
-% LATIN SMALL LETTER L WITH MIDDLE DOT
-<U0140> "<U006C><U00B7>";"<U006C><U002E>";<U006C>
-% LATIN CAPITAL LETTER L WITH STROKE
-<U0141> <U004C>
-% LATIN SMALL LETTER L WITH STROKE
-<U0142> <U006C>
-% LATIN CAPITAL LETTER N WITH ACUTE
-<U0143> <U004E>
-% LATIN SMALL LETTER N WITH ACUTE
-<U0144> <U006E>
-% LATIN CAPITAL LETTER N WITH CEDILLA
-<U0145> <U004E>
-% LATIN SMALL LETTER N WITH CEDILLA
-<U0146> <U006E>
-% LATIN CAPITAL LETTER N WITH CARON
-<U0147> <U004E>
-% LATIN SMALL LETTER N WITH CARON
-<U0148> <U006E>
-% LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
-<U0149> "<U0027><U006E>"
-% LATIN CAPITAL LETTER ENG
-<U014A> "<U004E><U0047>";<U004E>
-% LATIN SMALL LETTER ENG
-<U014B> "<U006E><U0067>";<U006E>
-% LATIN CAPITAL LETTER O WITH MACRON
-<U014C> <U004F>
-% LATIN SMALL LETTER O WITH MACRON
-<U014D> <U006F>
-% LATIN CAPITAL LETTER O WITH BREVE
-<U014E> <U004F>
-% LATIN SMALL LETTER O WITH BREVE
-<U014F> <U006F>
-% LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
-<U0150> <U004F>
-% LATIN SMALL LETTER O WITH DOUBLE ACUTE
-<U0151> <U006F>
-% LATIN CAPITAL LIGATURE OE
-<U0152> <U009A>;"<U004F><U0045>"
-% LATIN SMALL LIGATURE OE
-<U0153> <U009B>;"<U006F><U0065>"
-% LATIN CAPITAL LETTER R WITH ACUTE
-<U0154> <U0052>
-% LATIN SMALL LETTER R WITH ACUTE
-<U0155> <U0072>
-% LATIN CAPITAL LETTER R WITH CEDILLA
-<U0156> <U0052>
-% LATIN SMALL LETTER R WITH CEDILLA
-<U0157> <U0072>
-% LATIN CAPITAL LETTER R WITH CARON
-<U0158> <U0052>
-% LATIN SMALL LETTER R WITH CARON
-<U0159> <U0072>
-% LATIN CAPITAL LETTER S WITH ACUTE
-<U015A> <U0053>
-% LATIN SMALL LETTER S WITH ACUTE
-<U015B> <U0073>
-% LATIN CAPITAL LETTER S WITH CIRCUMFLEX
-<U015C> "<U0053><U0068>";<U0053>
-% LATIN SMALL LETTER S WITH CIRCUMFLEX
-<U015D> "<U0073><U0068>";<U0073>
-% LATIN CAPITAL LETTER S WITH CEDILLA
-<U015E> <U0053>
-% LATIN SMALL LETTER S WITH CEDILLA
-<U015F> <U0073>
-% LATIN CAPITAL LETTER S WITH CARON
-<U0160> <U0053>
-% LATIN SMALL LETTER S WITH CARON
-<U0161> <U0073>
-% LATIN CAPITAL LETTER T WITH CEDILLA
-<U0162> <U0054>
-% LATIN SMALL LETTER T WITH CEDILLA
-<U0163> <U0074>
-% LATIN CAPITAL LETTER T WITH CARON
-<U0164> <U0054>
-% LATIN SMALL LETTER T WITH CARON
-<U0165> <U0074>
-% LATIN CAPITAL LETTER T WITH STROKE
-<U0166> <U0054>
-% LATIN SMALL LETTER T WITH STROKE
-<U0167> <U0074>
-% LATIN CAPITAL LETTER U WITH TILDE
-<U0168> <U0055>
-% LATIN SMALL LETTER U WITH TILDE
-<U0169> <U0075>
-% LATIN CAPITAL LETTER U WITH MACRON
-<U016A> <U0055>
-% LATIN SMALL LETTER U WITH MACRON
-<U016B> <U0075>
-% LATIN CAPITAL LETTER U WITH BREVE
-<U016C> <U0055>
-% LATIN SMALL LETTER U WITH BREVE
-<U016D> <U0075>
-% LATIN CAPITAL LETTER U WITH RING ABOVE
-<U016E> <U0055>
-% LATIN SMALL LETTER U WITH RING ABOVE
-<U016F> <U0075>
-% LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
-<U0170> <U0055>
-% LATIN SMALL LETTER U WITH DOUBLE ACUTE
-<U0171> <U0075>
-% LATIN CAPITAL LETTER U WITH OGONEK
-<U0172> <U0055>
-% LATIN SMALL LETTER U WITH OGONEK
-<U0173> <U0075>
-% LATIN CAPITAL LETTER W WITH CIRCUMFLEX
-<U0174> <U0081>;<U0057>
-% LATIN SMALL LETTER W WITH CIRCUMFLEX
-<U0175> <U0082>;<U0077>
-% LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
-<U0176> <U0085>;<U0059>
-% LATIN SMALL LETTER Y WITH CIRCUMFLEX
-<U0177> <U0086>;<U0079>
-% LATIN CAPITAL LETTER Y WITH DIAERESIS
-<U0178> <U0059>
-% LATIN CAPITAL LETTER Z WITH ACUTE
-<U0179> <U005A>
-% LATIN SMALL LETTER Z WITH ACUTE
-<U017A> <U007A>
-% LATIN CAPITAL LETTER Z WITH DOT ABOVE
-<U017B> <U005A>
-% LATIN SMALL LETTER Z WITH DOT ABOVE
-<U017C> <U007A>
-% LATIN CAPITAL LETTER Z WITH CARON
-<U017D> <U005A>
-% LATIN SMALL LETTER Z WITH CARON
-<U017E> <U007A>
-% LATIN SMALL LETTER LONG S
-<U017F> <U0073>
-% LATIN SMALL LETTER F WITH HOOK
-<U0192> <U0066>
-% LATIN CAPITAL LETTER S WITH COMMA BELOW
-<U0218> <U015E>;<U0053>
-% LATIN SMALL LETTER S WITH COMMA BELOW
-<U0219> <U015F>;<U0073>
-% LATIN CAPITAL LETTER T WITH COMMA BELOW
-<U021A> <U0162>;<U0054>
-% LATIN SMALL LETTER T WITH COMMA BELOW
-<U021B> <U0163>;<U0074>
-% MODIFIER LETTER PRIME
-<U02B9> <U2032>;<U0027>
-% MODIFIER LETTER TURNED COMMA
-<U02BB> <U2018>
-% MODIFIER LETTER APOSTROPHE
-<U02BC> <U2019>;<U0027>
-% MODIFIER LETTER REVERSED COMMA
-<U02BD> <U201B>
-% MODIFIER LETTER CIRCUMFLEX ACCENT
-<U02C6> <U005E>
-% MODIFIER LETTER VERTICAL LINE
-<U02C8> <U0027>
-% MODIFIER LETTER MACRON
-<U02C9> <U00AF>
-% MODIFIER LETTER LOW VERTICAL LINE
-<U02CC> <U002C>
-% MODIFIER LETTER TRIANGULAR COLON
-<U02D0> <U003A>
-% RING ABOVE
-<U02DA> <U00B0>
-% SMALL TILDE
-<U02DC> <U007E>
-% DOUBLE ACUTE ACCENT
-<U02DD> <U0022>
-% GREEK NUMERAL SIGN
-<U0374> <U0027>
-% GREEK LOWER NUMERAL SIGN
-<U0375> <U002C>
-% GREEK QUESTION MARK
-<U037E> <U003B>
-% LATIN CAPITAL LETTER B WITH DOT ABOVE
-<U1E02> <U0042>
-% LATIN SMALL LETTER B WITH DOT ABOVE
-<U1E03> <U0062>
-% LATIN CAPITAL LETTER D WITH DOT ABOVE
-<U1E0A> <U0044>
-% LATIN SMALL LETTER D WITH DOT ABOVE
-<U1E0B> <U0064>
-% LATIN CAPITAL LETTER F WITH DOT ABOVE
-<U1E1E> <U0046>
-% LATIN SMALL LETTER F WITH DOT ABOVE
-<U1E1F> <U0066>
-% LATIN CAPITAL LETTER M WITH DOT ABOVE
-<U1E40> <U004D>
-% LATIN SMALL LETTER M WITH DOT ABOVE
-<U1E41> <U006D>
-% LATIN CAPITAL LETTER P WITH DOT ABOVE
-<U1E56> <U0050>
-% LATIN SMALL LETTER P WITH DOT ABOVE
-<U1E57> <U0070>
-% LATIN CAPITAL LETTER S WITH DOT ABOVE
-<U1E60> <U0053>
-% LATIN SMALL LETTER S WITH DOT ABOVE
-<U1E61> <U0073>
-% LATIN CAPITAL LETTER T WITH DOT ABOVE
-<U1E6A> <U0054>
-% LATIN SMALL LETTER T WITH DOT ABOVE
-<U1E6B> <U0074>
-% LATIN CAPITAL LETTER W WITH GRAVE
-<U1E80> <U0057>
-% LATIN SMALL LETTER W WITH GRAVE
-<U1E81> <U0077>
-% LATIN CAPITAL LETTER W WITH ACUTE
-<U1E82> <U0057>
-% LATIN SMALL LETTER W WITH ACUTE
-<U1E83> <U0077>
-% LATIN CAPITAL LETTER W WITH DIAERESIS
-<U1E84> <U0057>
-% LATIN SMALL LETTER W WITH DIAERESIS
-<U1E85> <U0077>
-% LATIN CAPITAL LETTER Y WITH GRAVE
-<U1EF2> <U0059>
-% LATIN SMALL LETTER Y WITH GRAVE
-<U1EF3> <U0079>
-% EN QUAD
-<U2000> <U0020>
-% EM QUAD
-<U2001> "<U0020><U0020>"
-% EN SPACE
-<U2002> <U0020>
-% EM SPACE
-<U2003> "<U0020><U0020>"
-% THREE-PER-EM SPACE
-<U2004> <U0020>
-% FOUR-PER-EM SPACE
-<U2005> <U0020>
-% SIX-PER-EM SPACE
-<U2006> <U0020>
-% FIGURE SPACE
-<U2007> <U0020>
-% PUNCTUATION SPACE
-<U2008> <U0020>
-% THIN SPACE
-<U2009> <U0020>
-% HAIR SPACE
-<U200A> ""
-% ZERO WIDTH SPACE
-<U200B> ""
-% ZERO WIDTH NON-JOINER
-<U200C> ""
-% ZERO WIDTH JOINER
-<U200D> ""
-% LEFT-TO-RIGHT MARK
-<U200E> ""
-% RIGHT-TO-LEFT MARK
-<U200F> ""
-% HYPHEN
-<U2010> <U002D>
-% NON-BREAKING HYPHEN
-<U2011> <U002D>
-% FIGURE DASH
-<U2012> <U002D>
-% EN DASH
-<U2013> <U0097>;<U002D>
-% EM DASH
-<U2014> <U0098>;"<U002D><U002D>"
-% HORIZONTAL BAR
-<U2015> "<U002D><U002D>"
-% DOUBLE VERTICAL LINE
-<U2016> "<U007C><U007C>"
-% DOUBLE LOW LINE
-<U2017> <U005F>
-% LEFT SINGLE QUOTATION MARK
-<U2018> <U0090>;<U0027>
-% RIGHT SINGLE QUOTATION MARK
-<U2019> <U0091>;<U0027>
-% SINGLE LOW-9 QUOTATION MARK
-<U201A> <U0027>
-% SINGLE HIGH-REVERSED-9 QUOTATION MARK
-<U201B> <U0027>
-% LEFT DOUBLE QUOTATION MARK
-<U201C> <U0094>;<U0022>
-% RIGHT DOUBLE QUOTATION MARK
-<U201D> <U0095>;<U0022>
-% DOUBLE LOW-9 QUOTATION MARK
-<U201E> <U0096>;<U0022>
-% DOUBLE HIGH-REVERSED-9 QUOTATION MARK
-<U201F> <U0022>
-% DAGGER
-<U2020> <U009C>;<U002B>
-% DOUBLE DAGGER
-<U2021> <U009D>;"<U002B><U002B>"
-% BULLET
-<U2022> <U008F>;<U006F>
-% TRIANGULAR BULLET
-<U2023> <U003E>
-% ONE DOT LEADER
-<U2024> <U002E>
-% TWO DOT LEADER
-<U2025> "<U002E><U002E>"
-% HORIZONTAL ELLIPSIS
-<U2026> <U008C>;"<U002E><U002E><U002E>"
-% HYPHENATION POINT
-<U2027> <U002D>
-% LEFT-TO-RIGHT EMBEDDING
-<U202A> ""
-% RIGHT-TO-LEFT EMBEDDING
-<U202B> ""
-% POP DIRECTIONAL FORMATTING
-<U202C> ""
-% LEFT-TO-RIGHT OVERRIDE
-<U202D> ""
-% RIGHT-TO-LEFT OVERRIDE
-<U202E> ""
-% NARROW NO-BREAK SPACE
-<U202F> <U0020>
-% PER MILLE SIGN
-<U2030> <U008E>;"<U0020><U0030><U002F><U0030><U0030>"
-% PRIME
-<U2032> <U0027>
-% DOUBLE PRIME
-<U2033> <U0022>
-% TRIPLE PRIME
-<U2034> "<U0027><U0027><U0027>"
-% REVERSED PRIME
-<U2035> <U0060>
-% REVERSED DOUBLE PRIME
-<U2036> "<U0060><U0060>"
-% REVERSED TRIPLE PRIME
-<U2037> "<U0060><U0060><U0060>"
-% SINGLE LEFT-POINTING ANGLE QUOTATION MARK
-<U2039> <U0092>;<U003C>
-% SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
-<U203A> <U0093>;<U003E>
-% DOUBLE EXCLAMATION MARK
-<U203C> "<U0021><U0021>"
-% OVERLINE
-<U203E> <U002D>
-% HYPHEN BULLET
-<U2043> <U002D>
-% FRACTION SLASH
-<U2044> <U002F>
-% QUESTION EXCLAMATION MARK
-<U2048> "<U003F><U0021>"
-% EXCLAMATION QUESTION MARK
-<U2049> "<U0021><U003F>"
-% TIRONIAN SIGN ET
-<U204A> <U0037>
-% SUPERSCRIPT ZERO
-<U2070> "<U005E><U0030>";<U0030>
-% SUPERSCRIPT FOUR
-<U2074> "<U005E><U0034>";<U0034>
-% SUPERSCRIPT FIVE
-<U2075> "<U005E><U0035>";<U0035>
-% SUPERSCRIPT SIX
-<U2076> "<U005E><U0036>";<U0036>
-% SUPERSCRIPT SEVEN
-<U2077> "<U005E><U0037>";<U0037>
-% SUPERSCRIPT EIGHT
-<U2078> "<U005E><U0038>";<U0038>
-% SUPERSCRIPT NINE
-<U2079> "<U005E><U0039>";<U0039>
-% SUPERSCRIPT PLUS SIGN
-<U207A> "<U005E><U002B>";<U002B>
-% SUPERSCRIPT MINUS
-<U207B> "<U005E><U002D>";<U002D>
-% SUPERSCRIPT EQUALS SIGN
-<U207C> "<U005E><U003D>";<U003D>
-% SUPERSCRIPT LEFT PARENTHESIS
-<U207D> "<U005E><U0028>";<U0028>
-% SUPERSCRIPT RIGHT PARENTHESIS
-<U207E> "<U005E><U0029>";<U0029>
-% SUPERSCRIPT LATIN SMALL LETTER N
-<U207F> "<U005E><U006E>";<U006E>
-% SUBSCRIPT ZERO
-<U2080> "<U005F><U0030>";<U0030>
-% SUBSCRIPT ONE
-<U2081> "<U005F><U0031>";<U0031>
-% SUBSCRIPT TWO
-<U2082> "<U005F><U0032>";<U0032>
-% SUBSCRIPT THREE
-<U2083> "<U005F><U0033>";<U0033>
-% SUBSCRIPT FOUR
-<U2084> "<U005F><U0034>";<U0034>
-% SUBSCRIPT FIVE
-<U2085> "<U005F><U0035>";<U0035>
-% SUBSCRIPT SIX
-<U2086> "<U005F><U0036>";<U0036>
-% SUBSCRIPT SEVEN
-<U2087> "<U005F><U0037>";<U0037>
-% SUBSCRIPT EIGHT
-<U2088> "<U005F><U0038>";<U0038>
-% SUBSCRIPT NINE
-<U2089> "<U005F><U0039>";<U0039>
-% SUBSCRIPT PLUS SIGN
-<U208A> "<U005F><U002B>";<U002B>
-% SUBSCRIPT MINUS
-<U208B> "<U005F><U002D>";<U002D>
-% SUBSCRIPT EQUALS SIGN
-<U208C> "<U005F><U003D>";<U003D>
-% SUBSCRIPT LEFT PARENTHESIS
-<U208D> "<U005F><U0028>";<U0028>
-% SUBSCRIPT RIGHT PARENTHESIS
-<U208E> "<U005F><U0029>";<U0029>
-% EURO SIGN
-<U20AC> <U0080>;"<U0045><U0055><U0052>";<U0045>
-% ACCOUNT OF
-<U2100> "<U0061><U002F><U0063>"
-% ADDRESSED TO THE SUBJECT
-<U2101> "<U0061><U002F><U0073>"
-% DEGREE CELSIUS
-<U2103> "<U00B0><U0043>";<U0043>
-% CARE OF
-<U2105> "<U0063><U002F><U006F>"
-% CADA UNA
-<U2106> "<U0063><U002F><U0075>"
-% DEGREE FAHRENHEIT
-<U2109> "<U00B0><U0046>";<U0046>
-% SCRIPT SMALL L
-<U2113> <U006C>
-% NUMERO SIGN
-<U2116> "<U004E><U00BA>";"<U004E><U006F>"
-% SOUND RECORDING COPYRIGHT
-<U2117> "<U0028><U0050><U0029>"
-% SERVICE MARK
-<U2120> "<U005B><U0053><U004D><U005D>"
-% TELEPHONE SIGN
-<U2121> "<U0054><U0045><U004C>"
-% TRADE MARK SIGN
-<U2122> <U008D>;"<U005B><U0054><U004D><U005D>"
-% OHM SIGN
-<U2126> <U03A9>;"<U006F><U0068><U006D>";<U004F>
-% KELVIN SIGN
-<U212A> <U004B>
-% ANGSTROM SIGN
-<U212B> <U00C5>
-% ESTIMATED SYMBOL
-<U212E> <U0065>
-% VULGAR FRACTION ONE THIRD
-<U2153> "<U0020><U0031><U002F><U0033>"
-% VULGAR FRACTION TWO THIRDS
-<U2154> "<U0020><U0032><U002F><U0033>"
-% VULGAR FRACTION ONE FIFTH
-<U2155> "<U0020><U0031><U002F><U0035>"
-% VULGAR FRACTION TWO FIFTHS
-<U2156> "<U0020><U0032><U002F><U0035>"
-% VULGAR FRACTION THREE FIFTHS
-<U2157> "<U0020><U0033><U002F><U0035>"
-% VULGAR FRACTION FOUR FIFTHS
-<U2158> "<U0020><U0034><U002F><U0035>"
-% VULGAR FRACTION ONE SIXTH
-<U2159> "<U0020><U0031><U002F><U0036>"
-% VULGAR FRACTION FIVE SIXTHS
-<U215A> "<U0020><U0035><U002F><U0036>"
-% VULGAR FRACTION ONE EIGHTH
-<U215B> "<U0020><U0031><U002F><U0038>"
-% VULGAR FRACTION THREE EIGHTHS
-<U215C> "<U0020><U0033><U002F><U0038>"
-% VULGAR FRACTION FIVE EIGHTHS
-<U215D> "<U0020><U0035><U002F><U0038>"
-% VULGAR FRACTION SEVEN EIGHTHS
-<U215E> "<U0020><U0037><U002F><U0038>"
-% FRACTION NUMERATOR ONE
-<U215F> "<U0020><U0031><U002F>"
-% ROMAN NUMERAL ONE
-<U2160> <U0049>
-% ROMAN NUMERAL TWO
-<U2161> "<U0049><U0049>"
-% ROMAN NUMERAL THREE
-<U2162> "<U0049><U0049><U0049>"
-% ROMAN NUMERAL FOUR
-<U2163> "<U0049><U0056>"
-% ROMAN NUMERAL FIVE
-<U2164> <U0056>
-% ROMAN NUMERAL SIX
-<U2165> "<U0056><U0049>"
-% ROMAN NUMERAL SEVEN
-<U2166> "<U0056><U0049><U0049>"
-% ROMAN NUMERAL EIGHT
-<U2167> "<U0056><U0049><U0049><U0049>"
-% ROMAN NUMERAL NINE
-<U2168> "<U0049><U0058>"
-% ROMAN NUMERAL TEN
-<U2169> <U0058>
-% ROMAN NUMERAL ELEVEN
-<U216A> "<U0058><U0049>"
-% ROMAN NUMERAL TWELVE
-<U216B> "<U0058><U0049><U0049>"
-% ROMAN NUMERAL FIFTY
-<U216C> <U004C>
-% ROMAN NUMERAL ONE HUNDRED
-<U216D> <U0043>
-% ROMAN NUMERAL FIVE HUNDRED
-<U216E> <U0044>
-% ROMAN NUMERAL ONE THOUSAND
-<U216F> <U004D>
-% SMALL ROMAN NUMERAL ONE
-<U2170> <U0069>
-% SMALL ROMAN NUMERAL TWO
-<U2171> "<U0069><U0069>"
-% SMALL ROMAN NUMERAL THREE
-<U2172> "<U0069><U0069><U0069>"
-% SMALL ROMAN NUMERAL FOUR
-<U2173> "<U0069><U0076>"
-% SMALL ROMAN NUMERAL FIVE
-<U2174> <U0076>
-% SMALL ROMAN NUMERAL SIX
-<U2175> "<U0076><U0069>"
-% SMALL ROMAN NUMERAL SEVEN
-<U2176> "<U0076><U0069><U0069>"
-% SMALL ROMAN NUMERAL EIGHT
-<U2177> "<U0076><U0069><U0069><U0069>"
-% SMALL ROMAN NUMERAL NINE
-<U2178> "<U0069><U0078>"
-% SMALL ROMAN NUMERAL TEN
-<U2179> <U0078>
-% SMALL ROMAN NUMERAL ELEVEN
-<U217A> "<U0078><U0069>"
-% SMALL ROMAN NUMERAL TWELVE
-<U217B> "<U0078><U0069><U0069>"
-% SMALL ROMAN NUMERAL FIFTY
-<U217C> <U006C>
-% SMALL ROMAN NUMERAL ONE HUNDRED
-<U217D> <U0063>
-% SMALL ROMAN NUMERAL FIVE HUNDRED
-<U217E> <U0064>
-% SMALL ROMAN NUMERAL ONE THOUSAND
-<U217F> <U006D>
-% LEFTWARDS ARROW
-<U2190> "<U003C><U002D>"
-% UPWARDS ARROW
-<U2191> <U005E>
-% RIGHTWARDS ARROW
-<U2192> "<U002D><U003E>"
-% DOWNWARDS ARROW
-<U2193> <U0076>
-% LEFT RIGHT ARROW
-<U2194> "<U003C><U002D><U003E>"
-% LEFTWARDS DOUBLE ARROW
-<U21D0> "<U003C><U003D>"
-% RIGHTWARDS DOUBLE ARROW
-<U21D2> "<U003D><U003E>"
-% LEFT RIGHT DOUBLE ARROW
-<U21D4> "<U003C><U003D><U003E>"
-% MINUS SIGN
-<U2212> <U0099>;<U2013>;<U002D>
-% DIVISION SLASH
-<U2215> <U002F>
-% SET MINUS
-<U2216> <U005C>
-% ASTERISK OPERATOR
-<U2217> <U002A>
-% RING OPERATOR
-<U2218> <U006F>
-% BULLET OPERATOR
-<U2219> <U00B7>
-% INFINITY
-<U221E> "<U0069><U006E><U0066>"
-% DIVIDES
-<U2223> <U007C>
-% PARALLEL TO
-<U2225> "<U007C><U007C>"
-% RATIO
-<U2236> <U003A>
-% TILDE OPERATOR
-<U223C> <U007E>
-% NOT EQUAL TO
-<U2260> "<U002F><U003D>"
-% IDENTICAL TO
-<U2261> <U003D>
-% LESS-THAN OR EQUAL TO
-<U2264> "<U003C><U003D>"
-% GREATER-THAN OR EQUAL TO
-<U2265> "<U003E><U003D>"
-% MUCH LESS-THAN
-<U226A> "<U003C><U003C>"
-% MUCH GREATER-THAN
-<U226B> "<U003E><U003E>"
-% CIRCLED PLUS
-<U2295> "<U0028><U002B><U0029>"
-% CIRCLED MINUS
-<U2296> "<U0028><U002D><U0029>"
-% CIRCLED TIMES
-<U2297> "<U0028><U0078><U0029>"
-% CIRCLED DIVISION SLASH
-<U2298> "<U0028><U002F><U0029>"
-% RIGHT TACK
-<U22A2> "<U007C><U002D>"
-% LEFT TACK
-<U22A3> "<U002D><U007C>"
-% ASSERTION
-<U22A6> "<U007C><U002D>"
-% MODELS
-<U22A7> "<U007C><U003D>"
-% TRUE
-<U22A8> "<U007C><U003D>"
-% FORCES
-<U22A9> "<U007C><U007C><U002D>"
-% DOT OPERATOR
-<U22C5> <U00B7>
-% STAR OPERATOR
-<U22C6> <U002A>
-% EQUAL AND PARALLEL TO
-<U22D5> <U0023>
-% VERY MUCH LESS-THAN
-<U22D8> "<U003C><U003C><U003C>"
-% VERY MUCH GREATER-THAN
-<U22D9> "<U003E><U003E><U003E>"
-% MIDLINE HORIZONTAL ELLIPSIS
-<U22EF> "<U002E><U002E><U002E>"
-% LEFT-POINTING ANGLE BRACKET
-<U2329> <U003C>
-% RIGHT-POINTING ANGLE BRACKET
-<U232A> <U003E>
-% SYMBOL FOR NULL
-<U2400> "<U004E><U0055><U004C>"
-% SYMBOL FOR START OF HEADING
-<U2401> "<U0053><U004F><U0048>"
-% SYMBOL FOR START OF TEXT
-<U2402> "<U0053><U0054><U0058>"
-% SYMBOL FOR END OF TEXT
-<U2403> "<U0045><U0054><U0058>"
-% SYMBOL FOR END OF TRANSMISSION
-<U2404> "<U0045><U004F><U0054>"
-% SYMBOL FOR ENQUIRY
-<U2405> "<U0045><U004E><U0051>"
-% SYMBOL FOR ACKNOWLEDGE
-<U2406> "<U0041><U0043><U004B>"
-% SYMBOL FOR BELL
-<U2407> "<U0042><U0045><U004C>"
-% SYMBOL FOR BACKSPACE
-<U2408> "<U0042><U0053>"
-% SYMBOL FOR HORIZONTAL TABULATION
-<U2409> "<U0048><U0054>"
-% SYMBOL FOR LINE FEED
-<U240A> "<U004C><U0046>"
-% SYMBOL FOR VERTICAL TABULATION
-<U240B> "<U0056><U0054>"
-% SYMBOL FOR FORM FEED
-<U240C> "<U0046><U0046>"
-% SYMBOL FOR CARRIAGE RETURN
-<U240D> "<U0043><U0052>"
-% SYMBOL FOR SHIFT OUT
-<U240E> "<U0053><U004F>"
-% SYMBOL FOR SHIFT IN
-<U240F> "<U0053><U0049>"
-% SYMBOL FOR DATA LINK ESCAPE
-<U2410> "<U0044><U004C><U0045>"
-% SYMBOL FOR DEVICE CONTROL ONE
-<U2411> "<U0044><U0043><U0031>"
-% SYMBOL FOR DEVICE CONTROL TWO
-<U2412> "<U0044><U0043><U0032>"
-% SYMBOL FOR DEVICE CONTROL THREE
-<U2413> "<U0044><U0043><U0033>"
-% SYMBOL FOR DEVICE CONTROL FOUR
-<U2414> "<U0044><U0043><U0034>"
-% SYMBOL FOR NEGATIVE ACKNOWLEDGE
-<U2415> "<U004E><U0041><U004B>"
-% SYMBOL FOR SYNCHRONOUS IDLE
-<U2416> "<U0053><U0059><U004E>"
-% SYMBOL FOR END OF TRANSMISSION BLOCK
-<U2417> "<U0045><U0054><U0042>"
-% SYMBOL FOR CANCEL
-<U2418> "<U0043><U0041><U004E>"
-% SYMBOL FOR END OF MEDIUM
-<U2419> "<U0045><U004D>"
-% SYMBOL FOR SUBSTITUTE
-<U241A> "<U0053><U0055><U0042>"
-% SYMBOL FOR ESCAPE
-<U241B> "<U0045><U0053><U0043>"
-% SYMBOL FOR FILE SEPARATOR
-<U241C> "<U0046><U0053>"
-% SYMBOL FOR GROUP SEPARATOR
-<U241D> "<U0047><U0053>"
-% SYMBOL FOR RECORD SEPARATOR
-<U241E> "<U0052><U0053>"
-% SYMBOL FOR UNIT SEPARATOR
-<U241F> "<U0055><U0053>"
-% SYMBOL FOR SPACE
-<U2420> "<U0053><U0050>"
-% SYMBOL FOR DELETE
-<U2421> "<U0044><U0045><U004C>"
-% OPEN BOX
-<U2423> <U005F>
-% SYMBOL FOR NEWLINE
-<U2424> "<U004E><U004C>"
-% SYMBOL FOR DELETE FORM TWO
-<U2425> "<U002F><U002F><U002F>"
-% SYMBOL FOR SUBSTITUTE FORM TWO
-<U2426> <U003F>
-% CIRCLED DIGIT ONE
-<U2460> "<U0028><U0031><U0029>";<U0031>
-% CIRCLED DIGIT TWO
-<U2461> "<U0028><U0032><U0029>";<U0032>
-% CIRCLED DIGIT THREE
-<U2462> "<U0028><U0033><U0029>";<U0033>
-% CIRCLED DIGIT FOUR
-<U2463> "<U0028><U0034><U0029>";<U0034>
-% CIRCLED DIGIT FIVE
-<U2464> "<U0028><U0035><U0029>";<U0035>
-% CIRCLED DIGIT SIX
-<U2465> "<U0028><U0036><U0029>";<U0036>
-% CIRCLED DIGIT SEVEN
-<U2466> "<U0028><U0037><U0029>";<U0037>
-% CIRCLED DIGIT EIGHT
-<U2467> "<U0028><U0038><U0029>";<U0038>
-% CIRCLED DIGIT NINE
-<U2468> "<U0028><U0039><U0029>";<U0039>
-% CIRCLED NUMBER TEN
-<U2469> "<U0028><U0031><U0030><U0029>"
-% CIRCLED NUMBER ELEVEN
-<U246A> "<U0028><U0031><U0031><U0029>"
-% CIRCLED NUMBER TWELVE
-<U246B> "<U0028><U0031><U0032><U0029>"
-% CIRCLED NUMBER THIRTEEN
-<U246C> "<U0028><U0031><U0033><U0029>"
-% CIRCLED NUMBER FOURTEEN
-<U246D> "<U0028><U0031><U0034><U0029>"
-% CIRCLED NUMBER FIFTEEN
-<U246E> "<U0028><U0031><U0035><U0029>"
-% CIRCLED NUMBER SIXTEEN
-<U246F> "<U0028><U0031><U0036><U0029>"
-% CIRCLED NUMBER SEVENTEEN
-<U2470> "<U0028><U0031><U0037><U0029>"
-% CIRCLED NUMBER EIGHTEEN
-<U2471> "<U0028><U0031><U0038><U0029>"
-% CIRCLED NUMBER NINETEEN
-<U2472> "<U0028><U0031><U0039><U0029>"
-% CIRCLED NUMBER TWENTY
-<U2473> "<U0028><U0032><U0030><U0029>"
-% PARENTHESIZED DIGIT ONE
-<U2474> "<U0028><U0031><U0029>";<U0031>
-% PARENTHESIZED DIGIT TWO
-<U2475> "<U0028><U0032><U0029>";<U0032>
-% PARENTHESIZED DIGIT THREE
-<U2476> "<U0028><U0033><U0029>";<U0033>
-% PARENTHESIZED DIGIT FOUR
-<U2477> "<U0028><U0034><U0029>";<U0034>
-% PARENTHESIZED DIGIT FIVE
-<U2478> "<U0028><U0035><U0029>";<U0035>
-% PARENTHESIZED DIGIT SIX
-<U2479> "<U0028><U0036><U0029>";<U0036>
-% PARENTHESIZED DIGIT SEVEN
-<U247A> "<U0028><U0037><U0029>";<U0037>
-% PARENTHESIZED DIGIT EIGHT
-<U247B> "<U0028><U0038><U0029>";<U0038>
-% PARENTHESIZED DIGIT NINE
-<U247C> "<U0028><U0039><U0029>";<U0039>
-% PARENTHESIZED NUMBER TEN
-<U247D> "<U0028><U0031><U0030><U0029>"
-% PARENTHESIZED NUMBER ELEVEN
-<U247E> "<U0028><U0031><U0031><U0029>"
-% PARENTHESIZED NUMBER TWELVE
-<U247F> "<U0028><U0031><U0032><U0029>"
-% PARENTHESIZED NUMBER THIRTEEN
-<U2480> "<U0028><U0031><U0033><U0029>"
-% PARENTHESIZED NUMBER FOURTEEN
-<U2481> "<U0028><U0031><U0034><U0029>"
-% PARENTHESIZED NUMBER FIFTEEN
-<U2482> "<U0028><U0031><U0035><U0029>"
-% PARENTHESIZED NUMBER SIXTEEN
-<U2483> "<U0028><U0031><U0036><U0029>"
-% PARENTHESIZED NUMBER SEVENTEEN
-<U2484> "<U0028><U0031><U0037><U0029>"
-% PARENTHESIZED NUMBER EIGHTEEN
-<U2485> "<U0028><U0031><U0038><U0029>"
-% PARENTHESIZED NUMBER NINETEEN
-<U2486> "<U0028><U0031><U0039><U0029>"
-% PARENTHESIZED NUMBER TWENTY
-<U2487> "<U0028><U0032><U0030><U0029>"
-% DIGIT ONE FULL STOP
-<U2488> "<U0031><U002E>";<U0031>
-% DIGIT TWO FULL STOP
-<U2489> "<U0032><U002E>";<U0032>
-% DIGIT THREE FULL STOP
-<U248A> "<U0033><U002E>";<U0033>
-% DIGIT FOUR FULL STOP
-<U248B> "<U0034><U002E>";<U0034>
-% DIGIT FIVE FULL STOP
-<U248C> "<U0035><U002E>";<U0035>
-% DIGIT SIX FULL STOP
-<U248D> "<U0036><U002E>";<U0036>
-% DIGIT SEVEN FULL STOP
-<U248E> "<U0037><U002E>";<U0037>
-% DIGIT EIGHT FULL STOP
-<U248F> "<U0038><U002E>";<U0038>
-% DIGIT NINE FULL STOP
-<U2490> "<U0039><U002E>";<U0039>
-% NUMBER TEN FULL STOP
-<U2491> "<U0031><U0030><U002E>"
-% NUMBER ELEVEN FULL STOP
-<U2492> "<U0031><U0031><U002E>"
-% NUMBER TWELVE FULL STOP
-<U2493> "<U0031><U0032><U002E>"
-% NUMBER THIRTEEN FULL STOP
-<U2494> "<U0031><U0033><U002E>"
-% NUMBER FOURTEEN FULL STOP
-<U2495> "<U0031><U0034><U002E>"
-% NUMBER FIFTEEN FULL STOP
-<U2496> "<U0031><U0035><U002E>"
-% NUMBER SIXTEEN FULL STOP
-<U2497> "<U0031><U0036><U002E>"
-% NUMBER SEVENTEEN FULL STOP
-<U2498> "<U0031><U0037><U002E>"
-% NUMBER EIGHTEEN FULL STOP
-<U2499> "<U0031><U0038><U002E>"
-% NUMBER NINETEEN FULL STOP
-<U249A> "<U0031><U0039><U002E>"
-% NUMBER TWENTY FULL STOP
-<U249B> "<U0032><U0030><U002E>"
-% PARENTHESIZED LATIN SMALL LETTER A
-<U249C> "<U0028><U0061><U0029>";<U0061>
-% PARENTHESIZED LATIN SMALL LETTER B
-<U249D> "<U0028><U0062><U0029>";<U0062>
-% PARENTHESIZED LATIN SMALL LETTER C
-<U249E> "<U0028><U0063><U0029>";<U0063>
-% PARENTHESIZED LATIN SMALL LETTER D
-<U249F> "<U0028><U0064><U0029>";<U0064>
-% PARENTHESIZED LATIN SMALL LETTER E
-<U24A0> "<U0028><U0065><U0029>";<U0065>
-% PARENTHESIZED LATIN SMALL LETTER F
-<U24A1> "<U0028><U0066><U0029>";<U0066>
-% PARENTHESIZED LATIN SMALL LETTER G
-<U24A2> "<U0028><U0067><U0029>";<U0067>
-% PARENTHESIZED LATIN SMALL LETTER H
-<U24A3> "<U0028><U0068><U0029>";<U0068>
-% PARENTHESIZED LATIN SMALL LETTER I
-<U24A4> "<U0028><U0069><U0029>";<U0069>
-% PARENTHESIZED LATIN SMALL LETTER J
-<U24A5> "<U0028><U006A><U0029>";<U006A>
-% PARENTHESIZED LATIN SMALL LETTER K
-<U24A6> "<U0028><U006B><U0029>";<U006B>
-% PARENTHESIZED LATIN SMALL LETTER L
-<U24A7> "<U0028><U006C><U0029>";<U006C>
-% PARENTHESIZED LATIN SMALL LETTER M
-<U24A8> "<U0028><U006D><U0029>";<U006D>
-% PARENTHESIZED LATIN SMALL LETTER N
-<U24A9> "<U0028><U006E><U0029>";<U006E>
-% PARENTHESIZED LATIN SMALL LETTER O
-<U24AA> "<U0028><U006F><U0029>";<U006F>
-% PARENTHESIZED LATIN SMALL LETTER P
-<U24AB> "<U0028><U0070><U0029>";<U0070>
-% PARENTHESIZED LATIN SMALL LETTER Q
-<U24AC> "<U0028><U0071><U0029>";<U0071>
-% PARENTHESIZED LATIN SMALL LETTER R
-<U24AD> "<U0028><U0072><U0029>";<U0072>
-% PARENTHESIZED LATIN SMALL LETTER S
-<U24AE> "<U0028><U0073><U0029>";<U0073>
-% PARENTHESIZED LATIN SMALL LETTER T
-<U24AF> "<U0028><U0074><U0029>";<U0074>
-% PARENTHESIZED LATIN SMALL LETTER U
-<U24B0> "<U0028><U0075><U0029>";<U0075>
-% PARENTHESIZED LATIN SMALL LETTER V
-<U24B1> "<U0028><U0076><U0029>";<U0076>
-% PARENTHESIZED LATIN SMALL LETTER W
-<U24B2> "<U0028><U0077><U0029>";<U0077>
-% PARENTHESIZED LATIN SMALL LETTER X
-<U24B3> "<U0028><U0078><U0029>";<U0078>
-% PARENTHESIZED LATIN SMALL LETTER Y
-<U24B4> "<U0028><U0079><U0029>";<U0079>
-% PARENTHESIZED LATIN SMALL LETTER Z
-<U24B5> "<U0028><U007A><U0029>";<U007A>
-% CIRCLED LATIN CAPITAL LETTER A
-<U24B6> "<U0028><U0041><U0029>";<U0041>
-% CIRCLED LATIN CAPITAL LETTER B
-<U24B7> "<U0028><U0042><U0029>";<U0042>
-% CIRCLED LATIN CAPITAL LETTER C
-<U24B8> "<U0028><U0043><U0029>";<U0043>
-% CIRCLED LATIN CAPITAL LETTER D
-<U24B9> "<U0028><U0044><U0029>";<U0044>
-% CIRCLED LATIN CAPITAL LETTER E
-<U24BA> "<U0028><U0045><U0029>";<U0045>
-% CIRCLED LATIN CAPITAL LETTER F
-<U24BB> "<U0028><U0046><U0029>";<U0046>
-% CIRCLED LATIN CAPITAL LETTER G
-<U24BC> "<U0028><U0047><U0029>";<U0047>
-% CIRCLED LATIN CAPITAL LETTER H
-<U24BD> "<U0028><U0048><U0029>";<U0048>
-% CIRCLED LATIN CAPITAL LETTER I
-<U24BE> "<U0028><U0049><U0029>";<U0049>
-% CIRCLED LATIN CAPITAL LETTER J
-<U24BF> "<U0028><U004A><U0029>";<U004A>
-% CIRCLED LATIN CAPITAL LETTER K
-<U24C0> "<U0028><U004B><U0029>";<U004B>
-% CIRCLED LATIN CAPITAL LETTER L
-<U24C1> "<U0028><U004C><U0029>";<U004C>
-% CIRCLED LATIN CAPITAL LETTER M
-<U24C2> "<U0028><U004D><U0029>";<U004D>
-% CIRCLED LATIN CAPITAL LETTER N
-<U24C3> "<U0028><U004E><U0029>";<U004E>
-% CIRCLED LATIN CAPITAL LETTER O
-<U24C4> "<U0028><U004F><U0029>";<U004F>
-% CIRCLED LATIN CAPITAL LETTER P
-<U24C5> "<U0028><U0050><U0029>";<U0050>
-% CIRCLED LATIN CAPITAL LETTER Q
-<U24C6> "<U0028><U0051><U0029>";<U0051>
-% CIRCLED LATIN CAPITAL LETTER R
-<U24C7> "<U0028><U0052><U0029>";<U0052>
-% CIRCLED LATIN CAPITAL LETTER S
-<U24C8> "<U0028><U0053><U0029>";<U0053>
-% CIRCLED LATIN CAPITAL LETTER T
-<U24C9> "<U0028><U0054><U0029>";<U0054>
-% CIRCLED LATIN CAPITAL LETTER U
-<U24CA> "<U0028><U0055><U0029>";<U0055>
-% CIRCLED LATIN CAPITAL LETTER V
-<U24CB> "<U0028><U0056><U0029>";<U0056>
-% CIRCLED LATIN CAPITAL LETTER W
-<U24CC> "<U0028><U0057><U0029>";<U0057>
-% CIRCLED LATIN CAPITAL LETTER X
-<U24CD> "<U0028><U0058><U0029>";<U0058>
-% CIRCLED LATIN CAPITAL LETTER Y
-<U24CE> "<U0028><U0059><U0029>";<U0059>
-% CIRCLED LATIN CAPITAL LETTER Z
-<U24CF> "<U0028><U005A><U0029>";<U005A>
-% CIRCLED LATIN SMALL LETTER A
-<U24D0> "<U0028><U0061><U0029>";<U0061>
-% CIRCLED LATIN SMALL LETTER B
-<U24D1> "<U0028><U0062><U0029>";<U0062>
-% CIRCLED LATIN SMALL LETTER C
-<U24D2> "<U0028><U0063><U0029>";<U0063>
-% CIRCLED LATIN SMALL LETTER D
-<U24D3> "<U0028><U0064><U0029>";<U0064>
-% CIRCLED LATIN SMALL LETTER E
-<U24D4> "<U0028><U0065><U0029>";<U0065>
-% CIRCLED LATIN SMALL LETTER F
-<U24D5> "<U0028><U0066><U0029>";<U0066>
-% CIRCLED LATIN SMALL LETTER G
-<U24D6> "<U0028><U0067><U0029>";<U0067>
-% CIRCLED LATIN SMALL LETTER H
-<U24D7> "<U0028><U0068><U0029>";<U0068>
-% CIRCLED LATIN SMALL LETTER I
-<U24D8> "<U0028><U0069><U0029>";<U0069>
-% CIRCLED LATIN SMALL LETTER J
-<U24D9> "<U0028><U006A><U0029>";<U006A>
-% CIRCLED LATIN SMALL LETTER K
-<U24DA> "<U0028><U006B><U0029>";<U006B>
-% CIRCLED LATIN SMALL LETTER L
-<U24DB> "<U0028><U006C><U0029>";<U006C>
-% CIRCLED LATIN SMALL LETTER M
-<U24DC> "<U0028><U006D><U0029>";<U006D>
-% CIRCLED LATIN SMALL LETTER N
-<U24DD> "<U0028><U006E><U0029>";<U006E>
-% CIRCLED LATIN SMALL LETTER O
-<U24DE> "<U0028><U006F><U0029>";<U006F>
-% CIRCLED LATIN SMALL LETTER P
-<U24DF> "<U0028><U0070><U0029>";<U0070>
-% CIRCLED LATIN SMALL LETTER Q
-<U24E0> "<U0028><U0071><U0029>";<U0071>
-% CIRCLED LATIN SMALL LETTER R
-<U24E1> "<U0028><U0072><U0029>";<U0072>
-% CIRCLED LATIN SMALL LETTER S
-<U24E2> "<U0028><U0073><U0029>";<U0073>
-% CIRCLED LATIN SMALL LETTER T
-<U24E3> "<U0028><U0074><U0029>";<U0074>
-% CIRCLED LATIN SMALL LETTER U
-<U24E4> "<U0028><U0075><U0029>";<U0075>
-% CIRCLED LATIN SMALL LETTER V
-<U24E5> "<U0028><U0076><U0029>";<U0076>
-% CIRCLED LATIN SMALL LETTER W
-<U24E6> "<U0028><U0077><U0029>";<U0077>
-% CIRCLED LATIN SMALL LETTER X
-<U24E7> "<U0028><U0078><U0029>";<U0078>
-% CIRCLED LATIN SMALL LETTER Y
-<U24E8> "<U0028><U0079><U0029>";<U0079>
-% CIRCLED LATIN SMALL LETTER Z
-<U24E9> "<U0028><U007A><U0029>";<U007A>
-% CIRCLED DIGIT ZERO
-<U24EA> "<U0028><U0030><U0029>";<U0030>
-% BOX DRAWINGS LIGHT HORIZONTAL
-<U2500> <U002D>
-% BOX DRAWINGS HEAVY HORIZONTAL
-<U2501> <U003D>
-% BOX DRAWINGS LIGHT VERTICAL
-<U2502> <U007C>
-% BOX DRAWINGS HEAVY VERTICAL
-<U2503> <U007C>
-% BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
-<U2504> <U002D>
-% BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL
-<U2505> <U003D>
-% BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL
-<U2506> <U007C>
-% BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL
-<U2507> <U007C>
-% BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL
-<U2508> <U002D>
-% BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL
-<U2509> <U003D>
-% BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
-<U250A> <U007C>
-% BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL
-<U250B> <U007C>
-% BOX DRAWINGS LIGHT DOWN AND RIGHT
-<U250C> <U002B>
-% BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
-<U250D> <U002B>
-% BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
-<U250E> <U002B>
-% BOX DRAWINGS HEAVY DOWN AND RIGHT
-<U250F> <U002B>
-% BOX DRAWINGS LIGHT DOWN AND LEFT
-<U2510> <U002B>
-% BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
-<U2511> <U002B>
-% BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
-<U2512> <U002B>
-% BOX DRAWINGS HEAVY DOWN AND LEFT
-<U2513> <U002B>
-% BOX DRAWINGS LIGHT UP AND RIGHT
-<U2514> <U002B>
-% BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
-<U2515> <U002B>
-% BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
-<U2516> <U002B>
-% BOX DRAWINGS HEAVY UP AND RIGHT
-<U2517> <U002B>
-% BOX DRAWINGS LIGHT UP AND LEFT
-<U2518> <U002B>
-% BOX DRAWINGS UP LIGHT AND LEFT HEAVY
-<U2519> <U002B>
-% BOX DRAWINGS UP HEAVY AND LEFT LIGHT
-<U251A> <U002B>
-% BOX DRAWINGS HEAVY UP AND LEFT
-<U251B> <U002B>
-% BOX DRAWINGS LIGHT VERTICAL AND RIGHT
-<U251C> <U002B>
-% BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
-<U251D> <U002B>
-% BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
-<U251E> <U002B>
-% BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
-<U251F> <U002B>
-% BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
-<U2520> <U002B>
-% BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
-<U2521> <U002B>
-% BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
-<U2522> <U002B>
-% BOX DRAWINGS HEAVY VERTICAL AND RIGHT
-<U2523> <U002B>
-% BOX DRAWINGS LIGHT VERTICAL AND LEFT
-<U2524> <U002B>
-% BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
-<U2525> <U002B>
-% BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
-<U2526> <U002B>
-% BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
-<U2527> <U002B>
-% BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
-<U2528> <U002B>
-% BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
-<U2529> <U002B>
-% BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
-<U252A> <U002B>
-% BOX DRAWINGS HEAVY VERTICAL AND LEFT
-<U252B> <U002B>
-% BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
-<U252C> <U002B>
-% BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
-<U252D> <U002B>
-% BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
-<U252E> <U002B>
-% BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
-<U252F> <U002B>
-% BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
-<U2530> <U002B>
-% BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
-<U2531> <U002B>
-% BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
-<U2532> <U002B>
-% BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
-<U2533> <U002B>
-% BOX DRAWINGS LIGHT UP AND HORIZONTAL
-<U2534> <U002B>
-% BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
-<U2535> <U002B>
-% BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
-<U2536> <U002B>
-% BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
-<U2537> <U002B>
-% BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
-<U2538> <U002B>
-% BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
-<U2539> <U002B>
-% BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
-<U253A> <U002B>
-% BOX DRAWINGS HEAVY UP AND HORIZONTAL
-<U253B> <U002B>
-% BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
-<U253C> <U002B>
-% BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
-<U253D> <U002B>
-% BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
-<U253E> <U002B>
-% BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
-<U253F> <U002B>
-% BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
-<U2540> <U002B>
-% BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
-<U2541> <U002B>
-% BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
-<U2542> <U002B>
-% BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
-<U2543> <U002B>
-% BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
-<U2544> <U002B>
-% BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
-<U2545> <U002B>
-% BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
-<U2546> <U002B>
-% BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
-<U2547> <U002B>
-% BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
-<U2548> <U002B>
-% BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
-<U2549> <U002B>
-% BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
-<U254A> <U002B>
-% BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
-<U254B> <U002B>
-% BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL
-<U254C> <U002D>
-% BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL
-<U254D> <U003D>
-% BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL
-<U254E> <U007C>
-% BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL
-<U254F> <U007C>
-% BOX DRAWINGS DOUBLE HORIZONTAL
-<U2550> <U003D>
-% BOX DRAWINGS DOUBLE VERTICAL
-<U2551> <U007C>
-% BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
-<U2552> <U002B>
-% BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
-<U2553> <U002B>
-% BOX DRAWINGS DOUBLE DOWN AND RIGHT
-<U2554> <U002B>
-% BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
-<U2555> <U002B>
-% BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
-<U2556> <U002B>
-% BOX DRAWINGS DOUBLE DOWN AND LEFT
-<U2557> <U002B>
-% BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
-<U2558> <U002B>
-% BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
-<U2559> <U002B>
-% BOX DRAWINGS DOUBLE UP AND RIGHT
-<U255A> <U002B>
-% BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
-<U255B> <U002B>
-% BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
-<U255C> <U002B>
-% BOX DRAWINGS DOUBLE UP AND LEFT
-<U255D> <U002B>
-% BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
-<U255E> <U002B>
-% BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
-<U255F> <U002B>
-% BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
-<U2560> <U002B>
-% BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
-<U2561> <U002B>
-% BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
-<U2562> <U002B>
-% BOX DRAWINGS DOUBLE VERTICAL AND LEFT
-<U2563> <U002B>
-% BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
-<U2564> <U002B>
-% BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
-<U2565> <U002B>
-% BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
-<U2566> <U002B>
-% BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
-<U2567> <U002B>
-% BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
-<U2568> <U002B>
-% BOX DRAWINGS DOUBLE UP AND HORIZONTAL
-<U2569> <U002B>
-% BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
-<U256A> <U002B>
-% BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
-<U256B> <U002B>
-% BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
-<U256C> <U002B>
-% BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
-<U256D> <U002B>
-% BOX DRAWINGS LIGHT ARC DOWN AND LEFT
-<U256E> <U002B>
-% BOX DRAWINGS LIGHT ARC UP AND LEFT
-<U256F> <U002B>
-% BOX DRAWINGS LIGHT ARC UP AND RIGHT
-<U2570> <U002B>
-% BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
-<U2571> <U002F>
-% BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
-<U2572> <U005C>
-% BOX DRAWINGS LIGHT DIAGONAL CROSS
-<U2573> <U0058>
-% BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT
-<U257C> <U002D>
-% BOX DRAWINGS LIGHT UP AND HEAVY DOWN
-<U257D> <U007C>
-% BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT
-<U257E> <U002D>
-% BOX DRAWINGS HEAVY UP AND LIGHT DOWN
-<U257F> <U007C>
-% WHITE CIRCLE
-<U25CB> <U006F>
-% WHITE BULLET
-<U25E6> <U006F>
-% BLACK STAR
-<U2605> <U002A>
-% WHITE STAR
-<U2606> <U002A>
-% BALLOT BOX WITH X
-<U2612> <U0058>
-% SALTIRE
-<U2613> <U0058>
-% WHITE FROWNING FACE
-<U2639> "<U003A><U002D><U0028>"
-% WHITE SMILING FACE
-<U263A> "<U003A><U002D><U0029>"
-% BLACK SMILING FACE
-<U263B> "<U0028><U002D><U003A>"
-% MUSIC FLAT SIGN
-<U266D> <U0062>
-% MUSIC SHARP SIGN
-<U266F> <U0023>
-% UPPER BLADE SCISSORS
-<U2701> "<U0025><U003C>"
-% BLACK SCISSORS
-<U2702> "<U0025><U003C>"
-% LOWER BLADE SCISSORS
-<U2703> "<U0025><U003C>"
-% WHITE SCISSORS
-<U2704> "<U0025><U003C>"
-% VICTORY HAND
-<U270C> <U0056>
-% CHECK MARK
-<U2713> <U221A>
-% HEAVY CHECK MARK
-<U2714> <U221A>
-% MULTIPLICATION X
-<U2715> <U0078>
-% HEAVY MULTIPLICATION X
-<U2716> <U0078>
-% BALLOT X
-<U2717> <U0058>
-% HEAVY BALLOT X
-<U2718> <U0058>
-% OUTLINED GREEK CROSS
-<U2719> <U002B>
-% HEAVY GREEK CROSS
-<U271A> <U002B>
-% OPEN CENTRE CROSS
-<U271B> <U002B>
-% HEAVY OPEN CENTRE CROSS
-<U271C> <U002B>
-% LATIN CROSS
-<U271D> <U002B>
-% SHADOWED WHITE LATIN CROSS
-<U271E> <U002B>
-% OUTLINED LATIN CROSS
-<U271F> <U002B>
-% MALTESE CROSS
-<U2720> <U002B>
-% STAR OF DAVID
-<U2721> <U002A>
-% FOUR TEARDROP-SPOKED ASTERISK
-<U2722> <U002B>
-% FOUR BALLOON-SPOKED ASTERISK
-<U2723> <U002B>
-% HEAVY FOUR BALLOON-SPOKED ASTERISK
-<U2724> <U002B>
-% FOUR CLUB-SPOKED ASTERISK
-<U2725> <U002B>
-% BLACK FOUR POINTED STAR
-<U2726> <U002B>
-% WHITE FOUR POINTED STAR
-<U2727> <U002B>
-% STRESS OUTLINED WHITE STAR
-<U2729> <U002A>
-% CIRCLED WHITE STAR
-<U272A> <U002A>
-% OPEN CENTRE BLACK STAR
-<U272B> <U002A>
-% BLACK CENTRE WHITE STAR
-<U272C> <U002A>
-% OUTLINED BLACK STAR
-<U272D> <U002A>
-% HEAVY OUTLINED BLACK STAR
-<U272E> <U002A>
-% PINWHEEL STAR
-<U272F> <U002A>
-% SHADOWED WHITE STAR
-<U2730> <U002A>
-% HEAVY ASTERISK
-<U2731> <U002A>
-% OPEN CENTRE ASTERISK
-<U2732> <U002A>
-% EIGHT SPOKED ASTERISK
-<U2733> <U002A>
-% EIGHT POINTED BLACK STAR
-<U2734> <U002A>
-% EIGHT POINTED PINWHEEL STAR
-<U2735> <U002A>
-% SIX POINTED BLACK STAR
-<U2736> <U002A>
-% EIGHT POINTED RECTILINEAR BLACK STAR
-<U2737> <U002A>
-% HEAVY EIGHT POINTED RECTILINEAR BLACK STAR
-<U2738> <U002A>
-% TWELVE POINTED BLACK STAR
-<U2739> <U002A>
-% SIXTEEN POINTED ASTERISK
-<U273A> <U002A>
-% TEARDROP-SPOKED ASTERISK
-<U273B> <U002A>
-% OPEN CENTRE TEARDROP-SPOKED ASTERISK
-<U273C> <U002A>
-% HEAVY TEARDROP-SPOKED ASTERISK
-<U273D> <U002A>
-% SIX PETALLED BLACK AND WHITE FLORETTE
-<U273E> <U002A>
-% BLACK FLORETTE
-<U273F> <U002A>
-% WHITE FLORETTE
-<U2740> <U002A>
-% EIGHT PETALLED OUTLINED BLACK FLORETTE
-<U2741> <U002A>
-% CIRCLED OPEN CENTRE EIGHT POINTED STAR
-<U2742> <U002A>
-% HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK
-<U2743> <U002A>
-% SNOWFLAKE
-<U2744> <U002A>
-% TIGHT TRIFOLIATE SNOWFLAKE
-<U2745> <U002A>
-% HEAVY CHEVRON SNOWFLAKE
-<U2746> <U002A>
-% SPARKLE
-<U2747> <U002A>
-% HEAVY SPARKLE
-<U2748> <U002A>
-% BALLOON-SPOKED ASTERISK
-<U2749> <U002A>
-% EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
-<U274A> <U002A>
-% HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
-<U274B> <U002A>
-% LATIN SMALL LIGATURE FF
-<UFB00> "<U0066><U0066>"
-% LATIN SMALL LIGATURE FI
-<UFB01> <U009E>;"<U0066><U0069>"
-% LATIN SMALL LIGATURE FL
-<UFB02> <U009F>;"<U0066><U006C>"
-% LATIN SMALL LIGATURE FFI
-<UFB03> "<U0066><U0066><U0069>"
-% LATIN SMALL LIGATURE FFL
-<UFB04> "<U0066><U0066><U006C>"
-% LATIN SMALL LIGATURE LONG S T
-<UFB05> "<U017F><U0074>";"<U0073><U0074>"
-% LATIN SMALL LIGATURE ST
-<UFB06> "<U0073><U0074>"
-% ZERO WIDTH NO-BREAK SPACE
-<UFEFF> ""
-% REPLACEMENT CHARACTER
-<UFFFD> <U003F>
diff --git a/utils/tt2code b/utils/tt2code
deleted file mode 100755
index 170954d..0000000
--- a/utils/tt2code
+++ b/dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/perl -W
-
-print <<END;
-/*
- * This file is part of NetSurf, http://netsurf-browser.org/
- * Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
- * Copyright 2003 James Bursa <bursa\@users.sourceforge.net>
- */
-
-#include "utils/utils.h"
-
-void unicode_transliterate(unsigned int c, char **r)
-{
- char *s = *r;
- switch (c) {
-
-END
-
-LINE: while (<>) {
- chomp;
- next if m/^%/;
- next if m/^ *$/;
-
- m/^<U([0-9A-F]{4})> /g or die "invalid line '$_'";
- $z = $1;
- next if (hex($z) < 256);
-
- SUBST: while (m/\G"?((<U([0-9A-F]{4})>)*)"?;?/g) {
- next if $& eq '';
- $m = $1;
- if ($m eq '') {
- print "case 0x$z: break;\n";
- next;
- }
- chop $m;
- @s = split /></, substr $m, 1;
- foreach $s (@s) {
- $s = substr $s, 1;
- next SUBST if 255 < hex($s);
- }
-
- print "case 0x$z: ";
- foreach $s (@s) {
- print "*s++ = 0x$s; ";
- }
- print "break;\n";
- next LINE;
- }
-}
-
-print <<END;
-
-default: *s++ = '?'; break;
- }
-
- *r = s;
-}
-END
-
diff --git a/utils/useragent.c b/utils/useragent.c
index 5b8c9e1..91f4363 100644
--- a/utils/useragent.c
+++ b/utils/useragent.c
@@ -29,7 +29,7 @@
static const char *core_user_agent_string = NULL;
#ifndef NETSURF_UA_FORMAT_STRING
-#define NETSURF_UA_FORMAT_STRING "NetSurf/%d.%d (%s; %s)"
+#define NETSURF_UA_FORMAT_STRING "NetSurf/%d.%d (%s)"
#endif
/**
@@ -41,20 +41,17 @@ user_agent_build_string(void)
{
struct utsname un;
const char *sysname = "Unknown";
- const char *machine = "Unknown";
char *ua_string;
int len;
if (uname(&un) >= 0) {
sysname = un.sysname;
- machine = un.machine;
}
len = snprintf(NULL, 0, NETSURF_UA_FORMAT_STRING,
netsurf_version_major,
netsurf_version_minor,
- sysname,
- machine);
+ sysname);
ua_string = malloc(len + 1);
if (!ua_string) {
/** \todo this needs handling better */
@@ -64,8 +61,7 @@ user_agent_build_string(void)
NETSURF_UA_FORMAT_STRING,
netsurf_version_major,
netsurf_version_minor,
- sysname,
- machine);
+ sysname);
core_user_agent_string = ua_string;
diff --git a/utils/utils.h b/utils/utils.h
index f3dba44..8172d2d 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -153,7 +153,6 @@ char *remove_underscores(const char *s, bool replacespace);
char *cnv_space2nbsp(const char *s);
bool is_dir(const char *path);
void regcomp_wrapper(regex_t *preg, const char *regex, int cflags);
-void unicode_transliterate(unsigned int c, char **r);
char *human_friendly_bytesize(unsigned long bytesize);
const char *rfc1123_date(time_t t);
unsigned int wallclock(void);