From 066bdae19da1ab8d96f71425f2479b5eb50f3417 Mon Sep 17 00:00:00 2001 From: Joshua Thijssen Date: Tue, 7 Jan 2025 14:55:38 +0100 Subject: [PATCH] Working pango / freetype / cairo system --- Cargo.lock | 88 +++++++++++++++++++++-- Cargo.toml | 2 + src/bin/gtk-test.rs | 167 ++++++++++++++++++++++++++++---------------- src/font_manager.rs | 4 +- 4 files changed, 194 insertions(+), 67 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 24fc5fd..5f0075f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,6 +216,19 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", +] + [[package]] name = "core-graphics" version = "0.23.2" @@ -225,7 +238,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation", "core-graphics-types", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -240,6 +253,18 @@ dependencies = [ "libc", ] +[[package]] +name = "core-text" +version = "19.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" +dependencies = [ + "core-foundation", + "core-graphics 0.22.3", + "foreign-types 0.3.2", + "libc", +] + [[package]] name = "core-text" version = "20.1.0" @@ -247,8 +272,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5" dependencies = [ "core-foundation", - "core-graphics", - "foreign-types", + "core-graphics 0.23.2", + "foreign-types 0.5.0", "libc", ] @@ -396,8 +421,8 @@ dependencies = [ "bitflags 2.6.0", "byteorder", "core-foundation", - "core-graphics", - "core-text", + "core-graphics 0.23.2", + "core-text 20.1.0", "dirs", "dwrote", "float-ord", @@ -421,11 +446,22 @@ dependencies = [ "colog", "font-kit", "gtk4", + "harfbuzz-sys", + "harfbuzz_rs", "log", "pangocairo", "prettytable", ] +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + [[package]] name = "foreign-types" version = "0.5.0" @@ -433,7 +469,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared", + "foreign-types-shared 0.3.1", ] [[package]] @@ -447,12 +483,28 @@ dependencies = [ "syn", ] +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "foreign-types-shared" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "freetype" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a440748e063798e4893ceb877151e84acef9bea9a8c6800645cf3f1b3a7806e" +dependencies = [ + "freetype-sys", + "libc", +] + [[package]] name = "freetype-rs" version = "0.35.0" @@ -866,6 +918,30 @@ dependencies = [ "system-deps 7.0.3", ] +[[package]] +name = "harfbuzz-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf8c27ca13930dc4ffe474880040fe9e0f03c2121600dc9c95423624cab3e467" +dependencies = [ + "cc", + "core-graphics 0.22.3", + "core-text 19.2.0", + "foreign-types 0.3.2", + "freetype", + "pkg-config", +] + +[[package]] +name = "harfbuzz_rs" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c18cfc23920d010f7637b86240a5f8892dfdbcb4f0e60828f8a9dc6ff5521d" +dependencies = [ + "bitflags 1.3.2", + "harfbuzz-sys", +] + [[package]] name = "hashbrown" version = "0.15.2" diff --git a/Cargo.toml b/Cargo.toml index 97182f0..4f810db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,8 @@ gtk4 = { version = "0.9.5", features = ["v4_6"] } font-kit = "0.14.2" cairo-rs = { version = "0.19.4", features = ["use_glib", "freetype"] } pangocairo = "0.20.7" +harfbuzz_rs = "2.0.1" +harfbuzz-sys = "0.5.0" #[patch.crates-io] diff --git a/src/bin/gtk-test.rs b/src/bin/gtk-test.rs index a7d8c77..01d96d1 100644 --- a/src/bin/gtk-test.rs +++ b/src/bin/gtk-test.rs @@ -1,63 +1,81 @@ -use cairo::freetype::Face; -use gtk4::cairo::FontFace; -use cairo::FontFace as CairoFontFace; -use fontmanager::font_manager::{FontManager, FontStyle}; -use gtk4::{glib, pango, Application, ApplicationWindow, DrawingArea}; -use gtk4::prelude::{ApplicationExt, ApplicationExtManual, DrawingAreaExtManual, GtkWindowExt}; +use fontmanager::font_manager::{FontInfo, FontManager, FontStyle}; +use gtk4::{glib, Application, ApplicationWindow, DrawingArea}; +use gtk4::prelude::{ApplicationExt, ApplicationExtManual, DrawingAreaExt, DrawingAreaExtManual, GtkWindowExt, WidgetExt}; use pangocairo::functions::{create_layout, show_layout}; +use pangocairo::pango; const APP_ID: &str = "io.gosub.font-manager.gtk-test"; -const TEXT: &str = r"Lorem ipsum odor amet, consectetuer adipiscing elit. Sed sociosqu suscipit praesent ex integer hac eu lacus. Quam pretium porta litora conubia metus tempus. Faucibus conubia praesent euismod ultricies semper ultrices mollis lectus venenatis! Morbi cubilia mauris porttitor commodo tellus rutrum. Non feugiat orci fringilla at ornare enim egestas himenaeos inceptos. Lacinia tristique sed leo ante aliquam nam facilisi inceptos. Turpis fames nulla sapien neque; ligula vehicula platea suspendisse. Potenti elementum accumsan felis eros augue odio. +const TEXT: &str = r"§ 1 Of the Nature of Flatland -Viverra torquent malesuada ornare primis dictumst sodales; tellus porttitor. Posuere blandit potenti ullamcorper luctus a odio. Dictum vel cursus iaculis; quisque curabitur lacus. Velit accumsan dignissim aptent placerat habitasse lacinia. Venenatis primis urna venenatis mauris massa montes. Cursus convallis condimentum ultrices tristique habitant mollis cras metus. Donec praesent conubia donec vulputate parturient class. Sed aliquam sed ultricies conubia fringilla pretium. Rutrum ac sociosqu commodo odio himenaeos rutrum etiam. +I call our world Flatland, not because we call it so, but to make its nature clearer to you, my happy readers, who are privileged to live in Space. -Mattis dignissim blandit luctus nascetur amet rhoncus. Eleifend ad mi auctor mattis luctus accumsan taciti. Curabitur condimentum molestie consectetur sapien interdum dui. Nisi mattis faucibus ad platea duis inceptos. Pellentesque vulputate praesent iaculis velit; mauris lacus amet a. Platea ad sagittis litora sed cras nec. Netus sodales primis rutrum nascetur magna euismod. Et etiam lorem molestie nascetur at. Etiam parturient tortor semper auctor orci amet et. Nisi feugiat inceptos nostra quam senectus dui conubia parturient. +Imagine a vast sheet of paper on which straight Lines, Triangles, Squares, Pentagons, Hexagons, and other figures, instead of remaining fixed in their places, move freely about, on or in the surface, but without the power of rising above or sinking below it, very much like shadows—only hard with luminous edges—and you will then have a pretty correct notion of my country and countrymen. Alas, a few years ago, I should have said “my universe:” but now my mind has been opened to higher views of things. -Gravida tortor pellentesque lectus, scelerisque tellus a hendrerit. Nisi ipsum fringilla dis posuere pharetra magnis class augue congue. Maximus maximus nulla vulputate mollis est. Velit sagittis sociosqu augue habitant aenean. Urna nullam porta morbi litora; sollicitudin torquent senectus augue. Venenatis proin torquent habitant porttitor tristique potenti. Etiam bibendum augue fusce nostra himenaeos. Dapibus senectus hac sem mollis nam. Accumsan pellentesque consectetur finibus netus amet eros. Turpis condimentum torquent faucibus auctor adipiscing senectus. +In such a country, you will perceive at once that it is impossible that there should be anything of what you call a “solid” kind; but I dare say you will suppose that we could at least distinguish by sight the Triangles, Squares, and other figures, moving about as I have described them. On the contrary, we could see nothing of the kind, not at least so as to distinguish one figure from another. Nothing was visible, nor could be visible, to us, except Straight Lines; and the necessity of this I will speedily demonstrate. -Nostra sit arcu euismod mauris augue euismod. Amet enim pharetra suscipit non a. Sapien tellus condimentum lacinia nulla lectus aliquet. Vel condimentum eget ridiculus mus leo penatibus. Elementum euismod sit aptent cursus eu lobortis fames fames at. Metus convallis consectetur convallis aliquam commodo odio. Montes erat quisque aptent; tempus amet laoreet. Nulla senectus risus gravida sit consectetur nunc. Amet libero nisi sollicitudin est maximus. +Place a penny on the middle of one of your tables in Space; and leaning over it, look down upon it. It will appear a circle. -Magna netus odio ad adipiscing placerat consequat. Tellus quis maximus lacus, inceptos leo mollis. Litora erat fusce eleifend consequat risus risus auctor adipiscing. Commodo curabitur mattis phasellus volutpat varius consectetur. Quisque scelerisque laoreet primis non maximus diam vulputate curabitur. Cubilia venenatis ornare, accumsan commodo nam conubia. +But now, drawing back to the edge of the table, gradually lower your eye (thus bringing yourself more and more into the condition of the inhabitants of Flatland), and you will find the penny becoming more and more oval to your view, and at last when you have placed your eye exactly on the edge of the table (so that you are, as it were, actually a Flatlander) the penny will then have ceased to appear oval at all, and will have become, so far as you can see, a straight line. -Nisl placerat himenaeos curae lectus conubia mauris per cubilia. Ullamcorper ullamcorper fames interdum natoque nulla quisque rhoncus interdum. Tristique sagittis purus commodo viverra facilisis ullamcorper. Ipsum sem donec aliquam libero sit vitae himenaeos faucibus. Etiam nisl ut ex cubilia porta. Pretium mus sagittis fringilla vulputate consectetur conubia. Ipsum ut etiam risus, sed urna sem. Fusce justo conubia quis eleifend convallis lacus. Vivamus cras phasellus phasellus pulvinar in. +The same thing would happen if you were to treat in the same way a Triangle, or a Square, or any other figure cut out from pasteboard. As soon as you look at it with your eye on the edge of the table, you will find that it ceases to appear to you as a figure, and that it becomes in appearance a straight line. Take for example an equilateral Triangle—who represents with us a Tradesman of the respectable class. Figure 1 represents the Tradesman as you would see him while you were bending over him from above; figures 2 and 3 represent the Tradesman, as you would see him if your eye were close to the level, or all but on the level of the table; and if your eye were quite on the level of the table (and that is how we see him in Flatland) you would see nothing but a straight line. -Primis at dolor inceptos morbi hendrerit pretium. Ex volutpat est ipsum integer magna penatibus scelerisque. Pellentesque convallis tortor fringilla vel curabitur arcu. Mollis placerat est scelerisque sociosqu ligula molestie. Eleifend torquent augue metus placerat; ornare elementum semper porta? Lectus feugiat tortor duis turpis finibus odio rutrum felis. + When I was in Spaceland I heard that your sailors have very similar experiences while they traverse your seas and discern some distant island or coast lying on the horizon. The far-off land may have bays, forelands, angles in and out to any number and extent; yet at a distance you see none of these (unless indeed your sun shines bright upon them revealing the projections and retirements by means of light and shade), nothing but a grey unbroken line upon the water. -Apellentesque pretium semper maximus non ultricies ligula mi mus. Gravida quisque habitant porttitor neque congue pharetra erat. Sollicitudin suspendisse libero vivamus penatibus dui natoque nisi curabitur hendrerit. Ex proin posuere in orci cursus. Venenatis elementum mi class cursus nisl erat hendrerit at leo. Ornare orci ridiculus nibh eros vestibulum facilisis torquent nascetur. +Well, that is just what we see when one of our triangular or other acquaintances comes towards us in Flatland. As there is neither sun with us, nor any light of such a kind as to make shadows, we have none of the helps to the sight that you have in Spaceland. If our friend comes closer to us we see his line becomes larger; if he leaves us it becomes smaller; but still he looks like a straight line; be he a Triangle, Square, Pentagon, Hexagon, Circle, what you will—a straight Line he looks and nothing else. -Potenti enim dis quam pharetra vel. Eget class risus dignissim lectus inceptos adipiscing donec. Rutrum primis cursus dictum adipiscing lacinia ac. Euismod hac bibendum nascetur nec diam sed penatibus. Sed tempor aliquam quis ridiculus faucibus aptent sed. Elementum elementum convallis curabitur turpis imperdiet sagittis sed interdum. Eget maximus suspendisse mauris suscipit sagittis morbi massa torquent. +You may perhaps ask how under these disadvantagous circumstances we are able to distinguish our friends from one another: but the answer to this very natural question will be more fitly and easily given when I come to describe the inhabitants of Flatland. For the present let me defer this subject, and say a word or two about the climate and houses in our country. -Porttitor habitant taciti euismod quisque risus parturient tellus. Aelit sollicitudin taciti fusce magna hendrerit dictum sagittis vulputate. Montes netus auctor efficitur neque dolor tincidunt metus odio. Natoque dapibus facilisi elementum facilisis velit felis laoreet dictumst. Lectus id maximus venenatis ligula dolor pharetra. Ullamcorper suspendisse faucibus dapibus dapibus viverra? Aliquam vulputate commodo interdum habitant class torquent porttitor cubilia. +§ 2 Of the Climate and Houses in Flatland -Tincidunt sollicitudin metus penatibus odio duis. Per pulvinar augue a cras potenti tellus. Netus elementum eget duis risus tristique magna et metus. Nisi a viverra primis torquent dui penatibus, metus mauris. Malesuada fusce velit euismod maximus facilisis egestas commodo. Nunc etiam maximus habitant ultrices iaculis pretium. Tellus eros consequat sit felis eu iaculis. +As with you, so also with us, there are four points of the compass North, South, East, and West. -Fringilla cubilia consectetur maecenas urna dictum fringilla et. Dictumst lacus aenean amet lorem ut nisl, tempor mollis placerat. Dis risus sed per curabitur pulvinar ipsum. Auctor ultricies convallis id vitae hac molestie senectus. Pharetra ullamcorper viverra per per velit? Conubia vitae semper aliquet fusce feugiat vestibulum. +There being no sun nor other heavenly bodies, it is impossible for us to determine the North in the usual way; but we have a method of our own. By a Law of Nature with us, there is a constant attraction to the South; and, although in temperate climates this is very slight—so that even a Woman in reasonable health can journey several furlongs northward without much difficulty—yet the hampering effort of the southward attraction is quite sufficient to serve as a compass in most parts of our earth. Moreover, the rain (which falls at stated intervals) coming always from the North, is an additional assistance; and in the towns we have the guidance of the houses, which of course have their side-walls running for the most part North and South, so that the roofs may keep off the rain from the North. In the country, where there are no houses, the trunks of the trees serve as some sort of guide. Altogether, we have not so much difficulty as might be expected in determining our bearings. -Litora fringilla dis est potenti consequat; accumsan nibh. Egestas fringilla tristique penatibus, donec feugiat taciti integer. Vestibulum imperdiet integer posuere at tincidunt pharetra. Fames sagittis finibus neque cras libero donec. Sit ac lorem vehicula aptent tristique neque dui vestibulum sociosqu. Ex at pharetra dolor ridiculus pharetra, nisi mi. +Yet in our more temperate regions, in which the southward attraction is hardly felt, walking sometimes in a perfectly desolate plain where there have been no houses nor trees to guide me, I have been occasionally compelled to remain stationary for hours together, waiting till the rain came before continuing my journey. On the weak and aged, and especially on delicate Females, the force of attraction tells much more heavily than on the robust of the Male Sex, so that it is a point of breeding, if you meet a Lady on the street, always to give her the North side of the way—by no means an easy thing to do always at short notice when you are in rude health and in a climate where it is difficult to tell your North from your South. -Egestas est donec ultrices rutrum sapien ullamcorper aenean auctor commodo. Curae gravida integer leo sodales imperdiet. Elementum class felis torquent tortor vulputate semper ad. Convallis nostra torquent mollis phasellus maecenas maecenas. Nascetur consectetur a porta, suscipit duis nibh. Purus suspendisse sollicitudin quisque neque sodales. Imperdiet congue quis sodales ipsum suscipit primis ex. Nam mauris parturient justo etiam maximus senectus proin viverra ullamcorper. +Windows there are none in our houses: for the light comes to us alike in our homes and out of them, by day and by night, equally at all times and in all places, whence we know not. It was in old days, with our learned men, an interesting and oft-investigate question, “What is the origin of light?” and the solution of it has been repeatedly attempted, with no other result than to crowd our lunatic asylums with the would-be solvers. Hence, after fruitless attempts to suppress such investigations indirectly by making them liable to a heavy tax, the Legislature, in comparatively recent times, absolutely prohibited them. I—alas, I alone in Flatland—know now only too well the true solution of this mysterious problem; but my knowledge cannot be made intelligible to a single one of my countrymen; and I am mocked at—I, the sole possessor of the truths of Space and of the theory of the introduction of Light from the world of three Dimensions—as if I were the maddest of the mad! But a truce to these painful digressions: let me return to our homes. -Bibendum dui mauris velit libero ridiculus imperdiet penatibus urna magna. Torquent faucibus faucibus tristique ex netus aliquam auctor. Eros in nullam tristique interdum ullamcorper molestie sagittis imperdiet. Penatibus nullam tincidunt donec senectus dignissim curae maximus augue maximus. Ante faucibus quisque ullamcorper gravida proin sed dui fermentum. Per vulputate euismod praesent dolor ex; dignissim penatibus curabitur. Molestie inceptos quisque quis netus facilisi. Afeugiat congue interdum facilisi dui. Rutrum velit congue senectus quis laoreet mauris. +The most common form for the construction of a house is five-sided or pentagonal, as in the annexed figure. The two Northern sides RO, OF, constitute the roof, and for the most part have no doors; on the East is a small door for the Women; on the West a much larger one for the Men; the South side or floor is usually doorless. -Cursus vel interdum egestas accumsan tincidunt augue mauris consectetur. Lacus justo elit felis ac etiam molestie viverra justo. Natoque diam porttitor ultricies ac laoreet ultricies accumsan. Dapibus et lacinia commodo sapien efficitur maximus viverra nisi. Laoreet potenti curabitur arcu aliquam neque ante neque felis? Suspendisse lacinia lacinia scelerisque molestie nisi sed. Tellus aptent aliquam penatibus nam pulvinar gravida, mattis curae suscipit. Justo nascetur magnis pellentesque ac mattis lectus lectus. Platea pharetra cursus ex mauris nam dictum sollicitudin. + Square and triangular houses are not allowed, and for this reason. The angles of a Square (and still more those of an equilateral Triangle,) being much more pointed than those of a Pentagon, and the lines of inanimate objects (such as houses) being dimmer than the lines of Men and Women, it follows that there is no little danger lest the points of a square or triangular house residence might do serious injury to an inconsiderate or perhaps absentminded traveller suddenly running against them: and therefore, as early as the eleventh century of our era, triangular houses were universally forbidden by Law, the only exceptions being fortifications, powder-magazines, barracks, and other state buildings, which is not desirable that the general public should approach without circumspection. -Mauris lobortis vestibulum erat id cursus. Bibendum egestas ac sagittis dapibus ridiculus class nibh vivamus est. Aliquet convallis maximus litora enim finibus. Cubilia pharetra velit magnis habitant tempor faucibus ultricies. Libero habitasse nec vehicula praesent nostra neque leo ante. Ut est sagittis tempor pellentesque rhoncus a. Cursus tincidunt dignissim ligula imperdiet; mollis aliquet phasellus. Laoreet vestibulum finibus hac lacinia sed pharetra in. Per porttitor aliquet platea odio eros rhoncus eros. +At this period, square houses were still everywhere permitted, though discouraged by a special tax. But, about three centuries afterwards, the Law decided that in all towns containing a population above ten thousand, the angle of a Pentagon was the smallest house-angle that could be allowed consistently with the public safety. The good sense of the community has seconded the efforts of the Legislature; and now, even in the country, the pentagonal construction has superseded every other. It is only now and then in some very remote and backward agricultural district that an antiquarian may still discover a square house. -Praesent sem nibh tristique volutpat morbi nibh. Nibh velit sem vitae rhoncus non et aliquet eu. Dictumst tincidunt dapibus fames augue tellus cubilia lacus. Molestie sapien condimentum fames ridiculus duis orci inceptos luctus facilisis. Curae facilisi nullam ac sodales feugiat integer posuere ultricies. Sociosqu himenaeos amet et vivamus augue himenaeos montes fames. Litora efficitur sit porta mattis interdum duis eget. Hendrerit dui lectus malesuada a habitasse aliquet. Sociosqu mus eleifend cursus per facilisi urna. +§ 3 Concerning the Inhabitants of Flatland -Maximus pharetra natoque; quam massa magna condimentum pharetra nunc! Aenean vel porttitor congue varius proin. Augue aenean parturient aptent risus molestie cubilia eget etiam. Eu rutrum aliquet ac habitasse dictumst torquent non ac. Ridiculus posuere vel sit tempus vitae nec est. Aenean facilisi nascetur facilisi; facilisis turpis porttitor. +The greatest length or breadth of a full grown inhabitant of Flatland may be estimated at about eleven of your inches. Twelve inches may be regarded as a maximum. -Eu imperdiet sapien mattis convallis tempor cubilia. Condimentum urna vitae congue gravida nibh; aliquet habitant per. Scelerisque natoque class facilisis ex ultricies praesent morbi pretium. Quisque nisi porta aliquet habitant mattis purus. Diam curabitur primis id; consequat nisl bibendum nec convallis. Sem conubia erat pharetra penatibus porta. Sapien gravida nostra lectus amet tempus sapien? Et habitasse mattis ridiculus sem adipiscing nisi fermentum. Laoreet litora diam, laoreet ad nibh nullam velit potenti! +Our Women are Straight Lines. -Libero augue nam facilisi mi diam luctus egestas. Ad torquent adipiscing quam hac vulputate netus. Montes sapien mattis conubia malesuada commodo dui. Consectetur class augue facilisis volutpat sem dictum torquent magnis. Ridiculus sollicitudin pellentesque euismod himenaeos rutrum aliquet porttitor. Pharetra arcu orci ut iaculis pulvinar penatibus mi neque non. Nascetur in quam viverra venenatis malesuada, habitant urna mattis. Vel vel vehicula adipiscing fringilla amet erat. Dictumst donec nunc adipiscing iaculis natoque. +Our Soldiers and Lowest Class of Workmen are Triangles with two equal sides, each about eleven inches long, and a base or third side so short (often not exceeding half an inch) that they form at their vertices a very sharp and formidable angle. Indeed when their bases are of the most degraded type (not more than the eighth part of an inch in size), they can hardly be distinguished from Straight lines or Women; so extremely pointed are their vertices. With us, as with you, these Triangles are distinguished from others by being called Isosceles; and by this name I shall refer to them in the following pages. -Conubia mollis lorem eros mattis sollicitudin. Tincidunt suspendisse ante eleifend ac praesent. Vivamus himenaeos nascetur hendrerit magna euismod ut himenaeos; blandit orci. Nulla dapibus id justo congue quisque. In inceptos tempor sagittis bibendum ullamcorper mi aliquet. Ultricies dictumst massa praesent vestibulum egestas massa. +Our Middle Class consists of Equilateral or Equal-Sided Triangles. -Conubia litora fermentum malesuada pretium tristique. Tincidunt sociosqu donec tristique est ex mi fringilla. Sociosqu mus vel nibh pharetra hendrerit cursus eleifend luctus. Convallis vestibulum turpis auctor ut hac leo. Suscipit hendrerit nibh nostra euismod ornare adipiscing tincidunt. Amet rhoncus eleifend suscipit ridiculus dui enim iaculis ultrices. Arcu praesent ex vitae commodo faucibus dui vitae. Nibh mauris at sodales dapibus curae natoque. Vitae sodales per tristique nullam nec. Nibh elementum accumsan faucibus tortor torquent. +Our Professional Men and Gentlemen are Squares (to which class I myself belong) and Five-Sided Figures or Pentagons. -Purus pretium natoque aenean fermentum, commodo consectetur ultrices. Condimentum nec nam blandit aptent hac vitae enim. Vel tempor laoreet parturient; egestas commodo tincidunt magna. Feugiat fermentum odio netus lectus curabitur ullamcorper potenti et. Tristique sagittis lorem neque nec maximus penatibus. Condimentum montes habitasse dictum convallis condimentum ipsum vivamus nisl mauris. Primis rhoncus aliquam quisque quisque condimentum sapien quis. Curae sagittis nam eleifend luctus fringilla nunc, torquent mattis ac."; +Next above these come the Nobility, of whom there are several degrees, beginning at Six-Sided Figures, or Hexagons, and from thence rising in the number of their sides till they receive the honourable title of Polygonal, or many-Sided. Finally when the number of the sides becomes so numerous, and the sides themselves so small, that the figure cannot be distinguished from a circle, he is included in the Circular or Priestly order; and this is the highest class of all. + +It is a Law of Nature with us that a male child shall have one more side than his father, so that each generation shall rise (as a rule) one step in the scale of development and nobility. Thus the son of a Square is a Pentagon; the son of a Pentagon, a Hexagon; and so on. + +But this rule applies not always to the Tradesman, and still less often to the Soldiers, and to the Workmen; who indeed can hardly be said to deserve the name of human Figures, since they have not all their sides equal. With them therefore the Law of Nature does not hold; and the son of an Isosceles (i.e. a Triangle with two sides equal) remains Isosceles still. Nevertheless, all hope is not such out, even from the Isosceles, that his posterity may ultimately rise above his degraded condition. For, after a long series of military successes, or diligent and skillful labours, it is generally found that the more intelligent among the Artisan and Soldier classes manifest a slight increase of their third side or base, and a shrinkage of the two other sides. Intermarriages (arranged by the Priests) between the sons and daughters of these more intellectual members of the lower classes generally result in an offspring approximating still more to the type of the Equal-Sided Triangle. + +Rarely—in proportion to the vast numbers of Isosceles births—is a genuine and certifiable Equal-Sided Triangle produced from Isosceles parents.[1] Such a birth requires, as its antecedents, not only a series of carefully arranged intermarriages, but also a long-continued exercise of frugality and self-control on the part of the would-be ancestors of the coming Equilateral, and a patient, systematic, and continuous development of the Isosceles intellect through many generations. + +[1] “What need of a certificate?” a Spaceland critic may ask: “Is not the procreation of a Square Son a certificate from Nature herself, proving the Equal-sidedness of the Father?” I reply that no Lady of any position will mary an uncertified Triangle. Square offspring has sometimes resulted from a slightly Irregular Triangle; but in almost every such case the Irregularity of the first generation is visited on the third; which either fails to attain the Pentagonal rank, or relapses to the Triangular. + +The birth of a True Equilateral Triangle from Isosceles parents is the subject of rejoicing in our country for many furlongs round. After a strict examination conducted by the Sanitary and Social Board, the infant, if certified as Regular, is with solemn ceremonial admitted into the class of Equilaterals. He is then immediately taken from his proud yet sorrowing parents and adopted by some childless Equilateral, who is bound by oath never to permit the child henceforth to enter his former home or so much as to look upon his relations again, for fear lest the freshly developed organism may, by force of unconscious imitation, fall back again into his hereditary level. + +The occasional emergence of an Equilateral from the ranks of his serf-born ancestors is welcomed, not only by the poor serfs themselves, as a gleam of light and hope shed upon the monotonous squalor of their existence, but also by the Aristocracy at large; for all the higher classes are well aware that these rare phenomena, while they do little or nothing to vulgarize their own privileges, serve as almost useful barrier against revolution from below. + +Had the acute-angled rabble been all, without exception, absolutely destitute of hope and of ambition, they might have found leaders in some of their many seditious outbreaks, so able as to render their superior numbers and strength too much even for the wisdom of the Circles. But a wise ordinance of Nature has decreed that in proportion as the working-classes increase in intelligence, knowledge, and all virtue, in that same proportion their acute angle (which makes them physically terrible) shall increase also and approximate to their comparatively harmless angle of the Equilateral Triangle. Thus, in the most brutal and formidable off the soldier class—creatures almost on a level with women in their lack of intelligence—it is found that, as they wax in the mental ability necessary to employ their tremendous penetrating power to advantage, so do they wane in the power of penetration itself. + +How admirable is the Law of Compensation! And how perfect a proof of the natural fitness and, I may almost say, the divine origin of the aristocratic constitution of the States of Flatland! By a judicious use of this Law of Nature, the Polygons and Circles are almost always able to stifle sedition in its very cradle, taking advantage of the irrepressible and boundless hopefulness of the human mind. Art also comes to the aid of Law and Order. It is generally found possible—by a little artificial compression or expansion on the part of the State physicians—to make some of the more intelligent leaders of a rebellion perfectly Regular, and to admit them at once into the privileged classes; a much larger number, who are still below the standard, allured by the prospect of being ultimately ennobled, are induced to enter the State Hospitals, where they are kept in honourable confinement for life; one or two alone of the most obstinate, foolish, and hopelessly irregular are led to execution. + +Then the wretched rabble of the Isosceles, planless and leaderless, are either transfixed without resistance by the small body of their brethren whom the Chief Circle keeps in pay for emergencies of this kind; or else more often, by means of jealousies and suspicious skillfully fomented among them by the Circular party, they are stirred to mutual warfare, and perish by one another’s angles. No less than one hundred and twenty rebellions are recorded in our annals, besides minor outbreaks numbered at two hundred and thirty-five; and they have all ended thus. + +-= The End =-"; fn main() -> glib::ExitCode { colog::init(); @@ -81,41 +99,65 @@ fn build_ui(app: &Application) { .build(); let area = DrawingArea::default(); - area.set_draw_func(move |_area, gtk_cr, width, height| { - // let cr: &Context = unsafe { - // // SAFETY: Both gtk4::cairo::Context and cairo::Context use the same underlying `cairo_t`. - // &*(gtk_cr as *const gtk4::cairo::Context as *const Context) - // }; - - /// Red square to indicate stuff is being drawn on screen + area.set_hexpand(true); + area.set_vexpand(true); + area.set_draw_func(move |area, gtk_cr, width, _height| { + // Red square to indicate stuff is being drawn on screen gtk_cr.set_source_rgba(1.0, 0.0, 0.0, 1.0); gtk_cr.rectangle(0.0, 0.0, 100.0, 100.0); let _ = gtk_cr.fill(); - // Purple - gtk_cr.set_source_rgba(1.0, 0.0, 1.0, 1.0); - - /// Here we set the font. We find the font, load it and convert it from freetype font face to a cairo font face. + // Here we set the font. We find the font, load it and convert it from freetype font face to a cairo font face. let info = font_manager.find(vec!["comic sans ms"], FontStyle::Normal).expect("Failed to find font"); - let face = font_manager.load(info).expect("Failed to load font"); - let cface = freetype_to_cairo_font_face(&face, 64); - gtk_cr.set_font_face(&cface); - gtk_cr.set_font_size(12.0); + // let ft_face = font_manager.load(&info).expect("Failed to load font"); - /// Layout works nicely with bounding boxes and alignment, but i can't seem to get the fontface to render + // Layout works nicely with bounding boxes and alignment, but i can't seem to get the fontface to render let layout = create_layout(gtk_cr); + let desc = create_font_description(&info, 14.0); + layout.set_font_description(Some(&desc)); + layout.set_text(TEXT); layout.set_width(width * pango::SCALE); layout.set_alignment(pango::Alignment::Center); - gtk_cr.move_to(0.0, (height as f64) / 2.0); + let cur_y = 200; + let mut max_y = cur_y; + + // Create layout + gtk_cr.set_source_rgba(1.0, 0.0, 1.0, 1.0); + gtk_cr.move_to(0.0, cur_y as f64); + show_layout(>k_cr, &layout); + max_y += layout.pixel_size().1; + + // Nice bounding rectangle around the text + gtk_cr.set_source_rgba(0.0, 0.0, 0.0, 1.0); + gtk_cr.set_line_width(1.0); + gtk_cr.rectangle(0.0, cur_y as f64, width as f64, max_y as f64 - cur_y as f64); + let _ = gtk_cr.stroke(); + + // Add a little bit of padding + max_y += 25; + let cur_y = max_y; + + // Display the next text in a different font + let info = font_manager.find(vec!["arial"], FontStyle::Normal).expect("Failed to find font"); + let desc = create_font_description(&info, 12.0); + + layout.set_font_description(Some(&desc)); + gtk_cr.set_source_rgba(0.7, 0.2, 0.5, 1.0); + gtk_cr.move_to(0.0, cur_y as f64); show_layout(>k_cr, &layout); + max_y += layout.pixel_size().1; + // Bounding box around the text again + gtk_cr.set_source_rgba(0.0, 1.0, 1.0, 1.0); + gtk_cr.set_line_width(3.0); + gtk_cr.rectangle(0.0, cur_y as f64, width as f64, max_y as f64 - cur_y as f64); + let _ = gtk_cr.stroke(); - // Simply show the text.. it works as a long line of text but it does take into account the font face set above... - gtk_cr.set_font_size(12.0); - gtk_cr.move_to(200.0, 150.0); - gtk_cr.show_text(TEXT).unwrap(); + // Get current position and add the layout height. This is the new height of the canvas in this drawing area so + // we can scroll. + area.set_content_height(max_y as i32 + 50); }); // Of course, scrolling doesn't work... need to figure out why it doesn't work. @@ -131,11 +173,18 @@ fn build_ui(app: &Application) { window.present(); } -fn freetype_to_cairo_font_face(face: &Face, size: isize) -> FontFace { - // Tricky stuff... we need to use create_from_ft which exists in the cairo crate, but not in the gtk4::cairo crate - // becuase of feature flags. So we need to transmute the cairo::FontFace to a gtk4::cairo::FontFace. - // It seems to work for the regular set_text(0 function, so I assume this works as aspected. - face.set_char_size(0, size * 64, 0, 0).unwrap(); - let cface = CairoFontFace::create_from_ft(face).unwrap(); - unsafe { std::mem::transmute(cface) } +/// Convert a fontInfo from freetype into a pango font description. +fn create_font_description(info: &FontInfo, size: f64) -> pango::FontDescription { + let mut desc = pango::FontDescription::new(); + desc.set_family(&info.family.clone()); + + desc.set_style(match info.style { + FontStyle::Italic => pango::Style::Italic, + FontStyle::Oblique => pango::Style::Oblique, + FontStyle::Normal => pango::Style::Normal, + }); + + desc.set_size((size * pango::SCALE as f64) as i32); + + desc } \ No newline at end of file diff --git a/src/font_manager.rs b/src/font_manager.rs index bf4b3d1..a4e9975 100644 --- a/src/font_manager.rs +++ b/src/font_manager.rs @@ -127,7 +127,7 @@ impl FontManager { } /// Load the font face for the given font info - pub fn load(&self, font_info: FontInfo) -> Result { + pub fn load(&self, font_info: &FontInfo) -> Result { let cache_key = format!("{}:{}", font_info.family, font_info.style); if let Some(font_face) = self.face_cache.lock().unwrap().get(&cache_key) { info!(target: LOG_TARGET, "Font loaded from cache: {}", cache_key); @@ -135,7 +135,7 @@ impl FontManager { return Ok(font_face.clone()); } - let face = match self.ft_library.new_face(font_info.path, font_info.index.unwrap_or(0) as isize) { + let face = match self.ft_library.new_face(&font_info.path, font_info.index.unwrap_or(0) as isize) { Ok(face) => face, Err(e) => { error!(target: LOG_TARGET, "unable to load font: {}", e);