From ed96b4d9e17ed713781cb6cef6348bf428ada922 Mon Sep 17 00:00:00 2001 From: "James E. Petts" Date: Sat, 31 Jan 2009 00:35:37 +0000 Subject: [PATCH 01/61] First proper simutrans-experimental update --- Simutrans.sln | 5 +- Simutrans.vcproj | 13 +- bauer/brueckenbauer.cc | 2 + bauer/hausbauer.cc | 2 + bauer/tunnelbauer.cc | 7 + bauer/vehikelbauer.h | 3 + bauer/warenbauer.h | 7 +- bauer/wegbauer.cc | 188 +++++-- besch/bruecke_besch.h | 33 ++ besch/reader/bridge_reader.cc | 27 +- besch/reader/good_reader.cc | 2 +- besch/reader/tunnel_reader.cc | 23 +- besch/reader/vehicle_reader.cc | 39 +- besch/reader/way_obj_reader.cc | 13 + besch/reader/way_reader.cc | 28 +- besch/roadsign_besch.h | 5 +- besch/tunnel_besch.h | 33 +- besch/vehikel_besch.h | 52 +- besch/way_obj_besch.h | 24 + besch/weg_besch.h | 32 +- besch/writer/bridge_writer.cc | 63 ++- besch/writer/tunnel_writer.cc | 60 +- besch/writer/vehicle_writer.cc | 82 ++- besch/writer/way_obj_writer.cc | 54 +- besch/writer/way_writer.cc | 60 +- boden/grund.cc | 2 + boden/wege/kanal.cc | 1 + boden/wege/maglev.cc | 7 +- boden/wege/monorail.cc | 5 + boden/wege/narrowgauge.cc | 5 + boden/wege/schiene.cc | 6 + boden/wege/weg.cc | 45 +- boden/wege/weg.h | 39 ++ dataobj/einstellungen.cc | 134 ++++- dataobj/einstellungen.h | 88 +++ dataobj/koord.h | 4 + dataobj/ribi.h | 42 +- dataobj/route.cc | 2 +- dataobj/warenziel.h | 4 + dings/bruecke.cc | 8 +- dings/gebaeude.cc | 2 +- dings/tunnel.cc | 3 + dings/wayobj.cc | 15 +- gui/banner.cc | 22 +- gui/convoi_detail_t.cc | 63 ++- gui/depot_frame.cc | 87 ++- gui/stadt_info.cc | 14 +- ifc/fahrer.h | 3 + makeobj/makeobj.cc | 6 +- player/ai_goods.cc | 6 +- player/simplay.cc | 5 +- simcity.cc | 968 ++++++++++++++++++++++++++++----- simcity.h | 42 +- simconvoi.cc | 69 ++- simconvoi.h | 4 + simdings.cc | 1 + simfab.cc | 5 +- simfab.h | 34 +- simhalt.cc | 70 ++- simhalt.h | 11 + simmain.cc | 3 + simversion.h | 6 +- simware.cc | 15 +- simware.h | 48 +- simwerkz.cc | 18 +- simwin.cc | 13 +- simworld.cc | 107 +++- simworld.h | 46 +- utils/dr_rdpng.c | 4 +- vehicle/simvehikel.cc | 578 +++++++++++++++++--- vehicle/simvehikel.h | 48 +- vehicle/simverkehr.cc | 63 ++- vehicle/simverkehr.h | 24 +- 73 files changed, 3142 insertions(+), 510 deletions(-) diff --git a/Simutrans.sln b/Simutrans.sln index f94aa531a2e..8bfb66f0f41 100644 --- a/Simutrans.sln +++ b/Simutrans.sln @@ -1,6 +1,6 @@  -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual C++ Express 2005 +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Simutrans", "Simutrans.vcproj", "{0621B295-BEB7-4767-82F1-F27995610323}" EndProject Global @@ -18,4 +18,3 @@ Global HideSolutionNode = FALSE EndGlobalSection EndGlobal - diff --git a/Simutrans.vcproj b/Simutrans.vcproj index b8904c7fd37..42499465bc1 100644 --- a/Simutrans.vcproj +++ b/Simutrans.vcproj @@ -1,11 +1,12 @@ - @@ -152,6 +152,8 @@ SubSystem="2" OptimizeReferences="2" EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" TargetMachine="1" /> - diff --git a/bauer/brueckenbauer.cc b/bauer/brueckenbauer.cc index 75221f13654..e05ad63e716 100644 --- a/bauer/brueckenbauer.cc +++ b/bauer/brueckenbauer.cc @@ -502,6 +502,8 @@ void brueckenbauer_t::baue_auffahrt(karte_t* welt, spieler_t* sp, koord3d end, k bruecke->neuen_weg_bauen( weg, ribi_neu, sp ); } weg->set_max_speed( besch->get_topspeed() ); + weg->set_max_weight( besch->get_max_weight() ); + weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); } else { leitung_t *lt = bruecke->get_leitung(); if(!lt) { diff --git a/bauer/hausbauer.cc b/bauer/hausbauer.cc index e09b881d2ca..9449f161da4 100644 --- a/bauer/hausbauer.cc +++ b/bauer/hausbauer.cc @@ -37,6 +37,7 @@ /* * Die verschiedenen Gebäudegruppen sind in eigenen Listen gesammelt. + * The various groups are building their own lists collected. */ static vector_tpl wohnhaeuser; static vector_tpl gewerbehaeuser; @@ -49,6 +50,7 @@ slist_tpl hausbauer_t::ungebaute_denkmaeler; /* * Diese Tabelle ermöglicht das Auffinden einer Beschreibung durch ihren Namen + * This table allows you to find a description by its name */ static stringhashtable_tpl besch_names; diff --git a/bauer/tunnelbauer.cc b/bauer/tunnelbauer.cc index d9deb353226..3a429b740d8 100644 --- a/bauer/tunnelbauer.cc +++ b/bauer/tunnelbauer.cc @@ -312,6 +312,9 @@ DBG_MESSAGE("tunnelbauer_t::baue()","build from (%d,%d,%d) to (%d,%d,%d) ", pos. weg->set_besch(weg_besch); weg->set_max_speed(besch->get_topspeed()); welt->access(pos.get_2d())->boden_hinzufuegen(tunnel); + weg->set_max_weight(besch->get_max_weight()); + weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); + tunnel->neuen_weg_bauen(weg, ribi_t::doppelt(ribi), sp); tunnel->obj_add(new tunnel_t(welt, pos, sp, besch)); assert(!tunnel->ist_karten_boden()); @@ -331,6 +334,8 @@ DBG_MESSAGE("tunnelbauer_t::baue()","build from (%d,%d,%d) to (%d,%d,%d) ", pos. weg->set_besch(weg_besch); weg->set_max_speed(besch->get_topspeed()); welt->access(pos.get_2d())->boden_hinzufuegen(tunnel); + weg->set_max_weight(besch->get_max_weight()); + weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); tunnel->neuen_weg_bauen(weg, ribi_t::doppelt(ribi), sp); tunnel->obj_add(new tunnel_t(welt, pos, sp, besch)); assert(!tunnel->ist_karten_boden()); @@ -368,6 +373,8 @@ tunnelbauer_t::baue_einfahrt(karte_t *welt, spieler_t *sp, koord3d end, koord zv tunnel->neuen_weg_bauen( weg, ribi, sp ); } weg->set_max_speed( besch->get_topspeed() ); + weg->set_max_weight( besch->get_max_weight() ); + weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); tunnel->calc_bild(); if(sp!=NULL) { diff --git a/bauer/vehikelbauer.h b/bauer/vehikelbauer.h index 9ae06985fa8..b0e71b467f7 100644 --- a/bauer/vehikelbauer.h +++ b/bauer/vehikelbauer.h @@ -27,6 +27,9 @@ template class vector_tpl; * Baut Fahrzeuge. Fahrzeuge sollten nicht direct instanziiert werden * sondern immer von einem vehikelbauer_t erzeugt werden. * + * Builds vehicles. Vehicles should not be instantiated directly, + * but always from a vehikelbauer_t produced. (Google) + * * @author Hj. Malthaner */ class vehikelbauer_t diff --git a/bauer/warenbauer.h b/bauer/warenbauer.h index 13bd509e66d..8ff0282707b 100644 --- a/bauer/warenbauer.h +++ b/bauer/warenbauer.h @@ -17,7 +17,7 @@ class ware_besch_t; /** * Factory-Klasse fuer Waren. - * + * "Factory class for goods" (Google) * @author Hj. Malthaner */ class warenbauer_t @@ -40,7 +40,7 @@ class warenbauer_t static const ware_besch_t *passagiere; static const ware_besch_t *post; - static const ware_besch_t *nichts; + static const ware_besch_t *nichts; //"Nothing". static bool alles_geladen(); static bool register_besch(ware_besch_t *besch); @@ -52,6 +52,9 @@ class warenbauer_t * Beschreibung davon zurück. Gibt NULL zurück wenn die * Ware nicht bekannt ist. * + * Searches for information on software 'name' and gives + * the description of it back. Returns NULL if the product is not known. + * * @param name der nicht-übersetzte Warenname * @author Hj. Malthaner/V. Meyer */ diff --git a/bauer/wegbauer.cc b/bauer/wegbauer.cc index 6beb1d6686d..ec371b36111 100644 --- a/bauer/wegbauer.cc +++ b/bauer/wegbauer.cc @@ -17,6 +17,7 @@ #include "../simmesg.h" #include "../player/simplay.h" #include "../simplan.h" +#include "../simtools.h" #include "../simdepot.h" #include "wegbauer.h" @@ -108,9 +109,9 @@ bool wegbauer_t::alle_wege_geladen() bool wegbauer_t::register_besch(const weg_besch_t *besch) { - DBG_DEBUG("wegbauer_t::register_besch()", besch->get_name()); - alle_wegtypen.put(besch->get_name(), besch); - return true; + DBG_DEBUG("wegbauer_t::register_besch()", besch->get_name()); + alle_wegtypen.put(besch->get_name(), besch); + return true; } @@ -281,13 +282,13 @@ wegbauer_t::check_for_leitung(const koord zv, const grund_t *bd) const leitung_t* lt = bd->find(); if(lt!=NULL) { ribi_t::ribi lt_ribi = lt->get_ribi(); - // it is our way we want to cross: can we built a crossing here? - // both ways must be straight and no ends - return - ribi_t::ist_gerade(lt_ribi) - && !ribi_t::ist_einfach(lt_ribi) - && ribi_t::ist_gerade(ribi_typ(zv)) - && (lt_ribi&ribi_typ(zv))==0; + // it is our way we want to cross: can we built a crossing here? + // both ways must be straight and no ends + return + ribi_t::ist_gerade(lt_ribi) + && !ribi_t::ist_einfach(lt_ribi) + && ribi_t::ist_gerade(ribi_typ(zv)) + && (lt_ribi&ribi_typ(zv))==0; } // check for transformer if (bd->find() != NULL || bd->find() != NULL) { @@ -753,11 +754,35 @@ DBG_MESSAGE("wegbauer_t::is_allowed_step()","wrong ground already there!"); } break; - case luft: // hsiegeln: runway - ok = !to->ist_wasser() && (to->hat_weg(air_wt) || !to->hat_wege()) && to->find()==NULL && !fundament && check_building( from, zv ) && check_building( to, -zv ); - // calculate costs - *costs = welt->get_einstellungen()->way_count_straight; - break; + case river: + if( to->ist_wasser() ) { + ok = true; + // do not care while in ocean + *costs = 1; + } + else { + // only downstream + ok = from->get_pos().z>=to->get_pos().z && check_for_leitung(zv,to) && (to->hat_weg(water_wt) || !to->hat_wege()); + // calculate costs + if(ok) { + // check for depots/stops/... + if( !check_building( from, zv ) || !check_building( to, -zv ) ) { + return false; + } + // prefer existing rivers: + *costs = to->hat_weg(water_wt) ? 10 : 10+simrand(welt->get_einstellungen()->way_count_90_curve); + if(to->get_weg_hang()!=0) { + *costs += welt->get_einstellungen()->way_count_slope*10; + } + } + } + break; + + case luft: // hsiegeln: runway + ok = !to->ist_wasser() && (to->hat_weg(air_wt) || !to->hat_wege()) && to->find()==NULL && !fundament && check_building( from, zv ) && check_building( to, -zv ); + // calculate costs + *costs = welt->get_einstellungen()->way_count_straight; + break; } return ok; } @@ -999,15 +1024,15 @@ wegbauer_t::wegbauer_t(karte_t* wl, spieler_t* spl) : next_gr(32) */ void wegbauer_t::set_keep_existing_ways(bool yesno) { - keep_existing_ways = yesno; - keep_existing_faster_ways = false; + keep_existing_ways = yesno; + keep_existing_faster_ways = false; } void wegbauer_t::set_keep_existing_faster_ways(bool yesno) { - keep_existing_ways = false; - keep_existing_faster_ways = yesno; + keep_existing_ways = false; + keep_existing_faster_ways = yesno; } @@ -1015,9 +1040,9 @@ void wegbauer_t::set_keep_existing_faster_ways(bool yesno) void wegbauer_t::route_fuer(enum bautyp_t wt, const weg_besch_t *b, const tunnel_besch_t *tunnel, const bruecke_besch_t *br) { - bautyp = wt; - besch = b; - bruecke_besch = br; + bautyp = wt; + besch = b; + bruecke_besch = br; tunnel_besch = tunnel; if(wt&tunnel_flag && tunnel==NULL) { dbg->fatal("wegbauer_t::route_fuer()","needs a tunnel description for an underground route!"); @@ -1025,14 +1050,14 @@ wegbauer_t::route_fuer(enum bautyp_t wt, const weg_besch_t *b, const tunnel_besc if((wt&bautyp_mask)==luft) { wt = (bautyp_t)(wt&(bautyp_mask|bot_flag)); } - if(sp==NULL) { - bruecke_besch = NULL; + if(sp==NULL) { + bruecke_besch = NULL; tunnel_besch = NULL; - } + } #if AUTOMATIC_BRIDGES - else if(bruecke_besch==NULL) { - bruecke_besch = brueckenbauer_t::find_bridge((waytype_t)b->get_wtyp(),25,0); - } + else if(bruecke_besch==NULL) { + bruecke_besch = brueckenbauer_t::find_bridge((waytype_t)b->get_wtyp(),25,0); + } #endif DBG_MESSAGE("wegbauer_t::route_fuer()", "setting way type to %d, besch=%s, bruecke_besch=%s", @@ -1102,15 +1127,15 @@ wegbauer_t::intern_calc_route(const koord3d start3d, const koord3d ziel3d) // there are several variant for mantaining the open list // however, only binary heap and HOT queue with binary heap are worth considering #ifdef tpl_HOT_queue_tpl_h - //static HOT_queue_tpl queue; + //static HOT_queue_tpl queue; #else #ifdef tpl_binary_heap_tpl_h - static binary_heap_tpl queue; + static binary_heap_tpl queue; #else #ifdef tpl_sorted_heap_tpl_h - //static sorted_heap_tpl queue; + //static sorted_heap_tpl queue; #else - //static prioqueue_tpl queue; + //static prioqueue_tpl queue; #endif #endif #endif @@ -1547,6 +1572,21 @@ long ms=dr_time(); if(bautyp==luft && besch->get_styp()==1) { intern_calc_route_runways(start, ziel); } + else if(bautyp==river) { + // river only go downards => start and end are clear ... + if( start.z > ziel.z ) { + intern_calc_route( start, ziel ); + } + else { + intern_calc_route( ziel, start ); + } + while( route.get_count()>0 && welt->lookup(route[0])->get_grund_hang()==hang_t::flach ) { + // remove leading water ... + route.remove_at(0); + } + // now this is the true length of the river + max_n = route.get_count()-1; + } else { // we need start and target for on plain ground and never on monorails! grund_t *gr=welt->lookup(start); @@ -1800,6 +1840,8 @@ wegbauer_t::baue_tunnelboden() tunnel->neuen_weg_bauen(weg, calc_ribi(i), sp); tunnel->obj_add(new tunnel_t(welt, route[i], sp, tunnel_besch)); weg->set_max_speed(tunnel_besch->get_topspeed()); + weg->set_max_weight(tunnel_besch->get_max_weight()); + weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); tunnel->calc_bild(); cost -= tunnel_besch->get_preis(); spieler_t::add_maintenance( sp, -weg->get_besch()->get_wartung()); @@ -2010,6 +2052,83 @@ wegbauer_t::baue_leitung() +// make a river +void +wegbauer_t::baue_fluss() +{ + /* since the contraits of the wayfinder ensures that a river flows always downwards + * we can assume that the first tiles are the ocean. + * Usually the wayfinder would find either direction! + */ + + // Do we join an other river? + sint32 start_n = 0; + for( sint32 idx=start_n; idx<=max_n; idx++ ) { + if( welt->lookup(route[idx])->hat_weg(water_wt) ) { + start_n = idx; + } + } + if( start_n>= max_n ) { + // completly joined another river => nothing to do + return; + } + + // first lower riverbed + const sint8 start_h = route[start_n].z; + for( sint32 idx=start_n; idx<=max_n; idx++ ) { + koord3d pos = route[idx]; + if(pos.z<=start_h){ + // do not handle both joining and water ... + continue; + } + if( !welt->ebne_planquadrat( NULL, pos.get_2d(), pos.z-1 ) ) { + dbg->message( "wegbauer_t::baue_fluss()","lowering tile %s failed.", pos.get_str() ); + } + } + + // now build the river + for( sint32 i=start_n; i<=max_n; i++ ) { + grund_t* gr = welt->lookup_kartenboden(route[i].get_2d()); + if( gr->get_typ()!=grund_t::wasser ) { + // get direction + ribi_t::ribi ribi = calc_ribi(i); + bool extend = gr->weg_erweitern(water_wt, ribi); + if( !extend ) { + weg_t *sch=weg_t::alloc(water_wt); + sch->set_besch(besch); + gr->neuen_weg_bauen(sch, ribi, NULL); + } + } + } + +#if 0 +// problem: way is not alsways to same destination! + // we will make rivers gradually larger by stepping up their width + if( umgebung_t::river_types>1 ) { + for( sint32 idx=0; idx<=start_n; idx++ ) { + weg_t* w = welt->lookup_kartenboden(route[idx].get_2d())->get_weg(water_wt); + if(w) { + int type; + for( type=umgebung_t::river_types-1; type>0; type-- ) { + // llokup type + if( w->get_besch()==alle_wegtypen.get(umgebung_t::river_type[type]) ) { + break; + } + } + // still room to expand + if( type>0 ) { + // thus we enlarge + w->set_besch( alle_wegtypen.get(umgebung_t::river_type[type-1]) ); + w->calc_bild(); + } + } + } + } +#endif +} + + + void wegbauer_t::baue() { @@ -2048,13 +2167,16 @@ INT_CHECK("simbau 1072"); DBG_MESSAGE("wegbauer_t::baue", "schiene"); baue_schiene(); break; - case strasse: + case strasse: baue_strasse(); DBG_MESSAGE("wegbauer_t::baue", "strasse"); break; case leitung: baue_leitung(); break; + case river: + baue_fluss(); + break; } INT_CHECK("simbau 1087"); diff --git a/besch/bruecke_besch.h b/besch/bruecke_besch.h index 6bcb41eca49..4e33682b8bd 100644 --- a/besch/bruecke_besch.h +++ b/besch/bruecke_besch.h @@ -45,6 +45,7 @@ class bruecke_besch_t : public obj_besch_std_name_t { uint8 max_length; // =0 off, else maximum length uint8 max_height; // =0 off, else maximum length + uint32 max_weight; //@author: jamespetts. Weight limit for vehicles. // allowed eara uint16 intro_date; @@ -53,6 +54,12 @@ class bruecke_besch_t : public obj_besch_std_name_t { /* number of seasons (0 = none, 1 = no snow/snow */ sint8 number_seasons; + + /*Way constraints for, e.g., loading gauges, types of electrification, etc. + * @author: jamespetts*/ + uint8 way_constraints_permissive; + uint8 way_constraints_prohibitive; + public: /* * Nummerierung all der verschiedenen Schienstücke @@ -108,6 +115,12 @@ class bruecke_besch_t : public obj_besch_std_name_t { */ uint32 get_topspeed() const { return topspeed; } + /** + * Determines max weight in tonnes for vehicles allowed on this bridge + * @author jamespetts + */ + uint32 get_max_weight() const { return max_weight; } + /** * Distance of pillars (=0 for no pillars) * @author prissi @@ -143,6 +156,26 @@ class bruecke_besch_t : public obj_besch_std_name_t { * @author prissi */ int get_retire_year_month() const { return obsolete_date; } + + /* Way constraints: determines whether vehicles + * can travel on this way. This method decodes + * the byte into bool values. See here for + * information on bitwise operations: + * http://www.cprogramming.com/tutorial/bitwise_operators.html + * @author: jamespetts + * */ + const bool permissive_way_constraint_set(uint8 i) + { + return (way_constraints_permissive & 1<pillars_asymmetric = false; besch->max_length = 0; besch->max_height = 0; + besch->max_weight = 999; besch->intro_date = DEFAULT_INTRO_DATE*12; besch->obsolete_date = DEFAULT_RETIRE_DATE*12; besch->number_seasons = 0; + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; if(version == 1) { // Versioned node, version 1 @@ -137,6 +140,23 @@ obj_besch_t * bridge_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->pillars_asymmetric = (decode_uint8(p)!=0); besch->max_height = decode_uint8(p); besch->number_seasons = decode_uint8(p); + if(node.size == 28) + { + // 28 byte node = version 8a. New features, + // (weight limits and way constraints), but + // backwards compatible with version 8. + + besch->max_weight = decode_uint32(p); + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + } + else + { + besch->max_weight = 999; + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + } + } else { // old node, version 0 @@ -145,6 +165,9 @@ obj_besch_t * bridge_reader_t::read_node(FILE *fp, obj_node_info_t &node) decode_uint16(p); // Menupos, no more used besch->preis = decode_uint32(p); besch->topspeed = 999; // Safe default ... + besch->max_weight = 999; + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; } // pillars cannot be heigher than this to avoid drawing errors @@ -155,8 +178,8 @@ obj_besch_t * bridge_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->offset = version<8 ? 0 : 2; DBG_DEBUG("bridge_reader_t::read_node()", - "version=%d waytype=%d price=%d topspeed=%d,pillars=%i,max_length=%i", - version, besch->wegtyp, besch->preis, besch->topspeed,besch->pillars_every,besch->max_length); + "version=%d waytype=%d price=%d topspeed=%d,pillars=%i,max_length=%i,max_weight%d", + version, besch->wegtyp, besch->preis, besch->topspeed,besch->pillars_every,besch->max_length,besch->max_weight); return besch; } diff --git a/besch/reader/good_reader.cc b/besch/reader/good_reader.cc index d9a61fc60bf..5046ecffe84 100644 --- a/besch/reader/good_reader.cc +++ b/besch/reader/good_reader.cc @@ -21,7 +21,7 @@ void good_reader_t::register_obj(obj_besch_t *&data) bool good_reader_t::successfully_loaded() const { - return warenbauer_t::alles_geladen(); + return warenbauer_t::alles_geladen(); //"Alles geladen" = "Everything laoded" (Babelfish) } diff --git a/besch/reader/tunnel_reader.cc b/besch/reader/tunnel_reader.cc index 1d09d6470ec..aabcc3c289d 100644 --- a/besch/reader/tunnel_reader.cc +++ b/besch/reader/tunnel_reader.cc @@ -54,6 +54,20 @@ obj_besch_t * tunnel_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->intro_date = decode_uint16(p); besch->obsolete_date = decode_uint16(p); besch->number_seasons = decode_uint8(p); + if(node.size == 26) + { + // Node size == 26 - extra features to be read. Version 2a. + // Backwards compatible with version 2 with this code. + besch->max_weight = decode_uint32(p); + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + } + else + { + besch->max_weight = 999; + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + } } else if(version == 1) { // first versioned node, version 1 @@ -64,14 +78,19 @@ obj_besch_t * tunnel_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->intro_date = decode_uint16(p); besch->obsolete_date = decode_uint16(p); besch->number_seasons = 0; + besch->max_weight = 999; + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + + } else { dbg->fatal("tunnel_reader_t::read_node()","illegal version %d",version); } DBG_DEBUG("bridge_reader_t::read_node()", - "version=%d waytype=%d price=%d topspeed=%d, intro_year=%d", - version, besch->wegtyp, besch->preis, besch->topspeed, besch->intro_date/12); + "version=%d waytype=%d price=%d topspeed=%d, intro_year=%d, max_weight%d", + version, besch->wegtyp, besch->preis, besch->topspeed, besch->intro_date/12, besch->max_weight); } return besch; diff --git a/besch/reader/vehicle_reader.cc b/besch/reader/vehicle_reader.cc index ae3b6eafd2c..ae0cc7d1f49 100644 --- a/besch/reader/vehicle_reader.cc +++ b/besch/reader/vehicle_reader.cc @@ -152,7 +152,7 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->zuladung = decode_uint16(p); besch->geschw = decode_uint16(p); besch->gewicht = decode_uint16(p); - besch->leistung = decode_uint32(p); + besch->leistung = decode_uint32(p); //"performance" (Google) besch->betriebskosten = decode_uint16(p); besch->intro_date = decode_uint16(p); @@ -163,9 +163,26 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->sound = decode_sint8(p); besch->engine_type = decode_uint8(p); besch->len = decode_uint8(p); - besch->vorgaenger = decode_uint8(p); - besch->nachfolger = decode_uint8(p); + besch->vorgaenger = decode_uint8(p); //"Predecessors" (Google) + besch->nachfolger = decode_uint8(p); //"Successor" (Google) besch->freight_image_type = decode_uint8(p); + if(node.size == 35) + { + // Node size == 35 - extra features to be read. Version 8a. + // Backwards compatible with version 8 with this code. + besch->is_tilting = decode_uint8(p); + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + besch->catering_level = decode_uint8(p); + } + else + { + //Standard version 8: default values for new items. + besch->is_tilting = 0; + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + besch->catering_level = 0; + } } else { if( version!=0 ) { @@ -225,9 +242,14 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) // before version 8 vehicles could only have one freight image in each direction if(version<8) { - besch->freight_image_type=0; + besch->freight_image_type = 0; + besch->is_tilting = 0; + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + besch->catering_level = 0; } + if(besch->sound==LOAD_SOUND) { uint8 len=decode_sint8(p); char wavname[256]; @@ -248,7 +270,8 @@ DBG_MESSAGE("vehicle_reader_t::register_obj()","old sound %i to %i",old_id,besch "version=%d " "way=%d zuladung=%d preis=%d geschw=%d gewicht=%d leistung=%d " "betrieb=%d sound=%d vor=%d nach=%d " - "date=%d/%d gear=%d engine_type=%d len=%d", + "date=%d/%d gear=%d engine_type=%d len=%d is_tilting=%d catering_level=%d " + "way_constraints_permissive=%d way_constraints_prohibitive%d", version, besch->typ, besch->zuladung, @@ -264,7 +287,11 @@ DBG_MESSAGE("vehicle_reader_t::register_obj()","old sound %i to %i",old_id,besch besch->intro_date/12, besch->gear, besch->engine_type, - besch->len); + besch->len, + besch->is_tilting, + besch->catering_level, + besch->way_constraints_permissive, + besch->way_constraints_prohibitive); return besch; } diff --git a/besch/reader/way_obj_reader.cc b/besch/reader/way_obj_reader.cc index 914d3d53e28..8da737b74c3 100644 --- a/besch/reader/way_obj_reader.cc +++ b/besch/reader/way_obj_reader.cc @@ -48,6 +48,19 @@ obj_besch_t * way_obj_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->obsolete_date = decode_uint16(p); besch->wtyp = decode_uint8(p); besch->own_wtyp = decode_uint8(p); + if(node.size == 22) + { + // 22 byte node = version 1a. New features, + // (weight limits and way constraints), but + // backwards compatible with version 1. + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + } + else + { + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + } } else { dbg->fatal("way_obj_reader_t::read_node()","Invalid version %d", version); diff --git a/besch/reader/way_reader.cc b/besch/reader/way_reader.cc index 1fcf0bf5673..9b1ce8824f8 100644 --- a/besch/reader/way_reader.cc +++ b/besch/reader/way_reader.cc @@ -71,6 +71,20 @@ obj_besch_t * way_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->styp = decode_uint8(p); besch->draw_as_ding = decode_uint8(p); besch->number_seasons = decode_sint8(p); + if(node.size == 27) + { + //If node.size is 27, we have version 4a. + //Backwards compatible with version 4, but + //has extra functions (way constraints). + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + } + else + { + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + } + } else if(version==3) { // Versioned node, version 3 @@ -129,6 +143,13 @@ obj_besch_t * way_reader_t::read_node(FILE *fp, obj_node_info_t &node) else if(besch->wtyp==128) { besch->wtyp = powerline_wt; } + + if(version < 4) + { + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + } + if(version<=2 && besch->wtyp==air_wt && besch->topspeed>=250) { // runway! besch->styp = 1; @@ -136,7 +157,8 @@ obj_besch_t * way_reader_t::read_node(FILE *fp, obj_node_info_t &node) DBG_DEBUG("way_reader_t::read_node()", "version=%d price=%d maintenance=%d topspeed=%d max_weight=%d " - "wtype=%d styp=%d intro_year=%i", + "wtype=%d styp=%d intro_year=%i way_constraints_permissive = %d " + "way_constraints_prohibitive = %d", version, besch->price, besch->maintenance, @@ -144,7 +166,9 @@ obj_besch_t * way_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->max_weight, besch->wtyp, besch->styp, - besch->intro_date/12); + besch->intro_date/12, + besch->way_constraints_permissive, + besch->way_constraints_prohibitive); return besch; } diff --git a/besch/roadsign_besch.h b/besch/roadsign_besch.h index ad71a2faae1..8c58af97450 100644 --- a/besch/roadsign_besch.h +++ b/besch/roadsign_besch.h @@ -25,7 +25,10 @@ class skin_besch_t; * Beschreibung: * Straßenschildere * - * Kindknoten: + * Description: + * Street Signs + * + * Kindknoten: ("Child nodes" - Google) * 0 Name * 1 Copyright * 2 Bildliste diff --git a/besch/tunnel_besch.h b/besch/tunnel_besch.h index 3f2458f3363..c4b79de9ae0 100644 --- a/besch/tunnel_besch.h +++ b/besch/tunnel_besch.h @@ -35,14 +35,21 @@ class tunnel_besch_t : public obj_besch_std_name_t { uint32 preis; // 1/100 credits uint32 maintenance; // monthly cost for bits_per_month=18 uint8 wegtyp; // waytype for tunnel + uint32 max_weight; // maximum weight for vehicles. @author: jamespetts - // allowed eara + // allowed era uint16 intro_date; uint16 obsolete_date; - /* number of seasons (0 = none, 1 = no snow/snow + /* number of seasons (0 = none, 1 = no snow/snow) */ sint8 number_seasons; + + /*Way constraints for, e.g., loading gauges, types of electrification, etc. + * @author: jamespetts*/ + uint8 way_constraints_permissive; + uint8 way_constraints_prohibitive; + public: const bild_besch_t *get_hintergrund(hang_t::typ hang, uint8 season) const { @@ -92,9 +99,31 @@ class tunnel_besch_t : public obj_besch_std_name_t { uint32 get_topspeed() const { return topspeed; } + uint32 get_max_weight() const { return max_weight; } + uint16 get_intro_year_month() const { return intro_date; } uint16 get_retire_year_month() const { return obsolete_date; } + + /* Way constraints: determines whether vehicles + * can travel on this way. This method decodes + * the byte into bool values. See here for + * information on bitwise operations: + * http://www.cprogramming.com/tutorial/bitwise_operators.html + * @author: jamespetts + * */ + const bool permissive_way_constraint_set(uint8 i) + { + return (way_constraints_permissive & 1<(get_child(2)); } @@ -222,7 +233,9 @@ class vehikel_besch_t : public obj_besch_std_name_t { uint16 get_gewicht() const { return gewicht; } uint32 get_leistung() const { return leistung; } uint16 get_betriebskosten() const { return betriebskosten; } + uint16 get_betriebskosten(static karte_t *welt) const; //Overloaded method - includes increase for obsolescence. sint8 get_sound() const { return sound; } + /** * @return introduction year @@ -266,6 +279,33 @@ class vehikel_besch_t : public obj_besch_std_name_t { * @author prissi */ uint8 get_length() const { return len; } + + /*Whether this is a tilting train (and can take coerners faster + *@author: jamespetts*/ + bool get_tilting() const { return (is_tilting == 1); } + + /*Bitwise encoded way constraints (permissive) + *@author: jamespetts*/ + uint8 get_permissive_constraints() const { return way_constraints_permissive; } + + /*Bitwise encoded way constraints (prohibitive) + *@author: jamespetts*/ + uint8 get_prohibitive_constraints() const { return way_constraints_prohibitive; } + + bool permissive_way_constraint_set(uint8 i) const + { + return (way_constraints_permissive & 1< 0) ? max_weight : 999; } + /** * get way type * @see waytype_t @@ -173,8 +181,10 @@ class weg_besch_t : public obj_besch_std_name_t { * @return introduction year * @author Hj. Malthaner */ + uint16 get_intro_year_month() const { return intro_date; } + /** * @return introduction month * @author Hj. Malthaner @@ -192,6 +202,26 @@ class weg_besch_t : public obj_besch_std_name_t { { return (const skin_besch_t *)(get_child(5)); } + + /* Way constraints: determines whether vehicles + * can travel on this way. This method decodes + * the byte into bool values. See here for + * information on bitwise operations: + * http://www.cprogramming.com/tutorial/bitwise_operators.html + * @author: jamespetts + * */ + const bool permissive_way_constraint_set(uint8 i) const + { + return (way_constraints_permissive & 1< #include "../../utils/cstring_t.h" #include "../../dataobj/tabfile.h" #include "obj_node.h" @@ -12,7 +13,7 @@ void bridge_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& obj) { - obj_node_t node(this, 22, &parent); + obj_node_t node(this, 28, &parent); uint8 wegtyp = get_waytype(obj.get("waytype")); uint16 topspeed = obj.get_int("topspeed", 999); @@ -23,6 +24,7 @@ void bridge_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& o uint8 max_length = obj.get_int("max_lenght",0); // max_lenght==0: unlimited max_length = obj.get_int("max_length",max_length); // with correct spelling uint8 max_height = obj.get_int("max_height",0); // max_height==0: unlimited + uint32 max_weight = obj.get_int("max_weight",999); // prissi: timeline uint16 intro_date = obj.get_int("intro_year", DEFAULT_INTRO_DATE) * 12; @@ -33,20 +35,57 @@ void bridge_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& o sint8 number_seasons = 0; + // Way constraints + // One byte for permissive, one byte for prohibitive. + // Therefore, 8 possible constraints of each type. + // Permissive: way allows vehicles with matching constraint: + // vehicles not allowed on any other sort of way. Vehicles + // without that constraint also allowed on the way. + // Prohibitive: way allows only vehicles with matching constraint: + // vehicles with matching constraint allowed on other sorts of way. + // @author: jamespetts + + uint8 permissive_way_constraints = 0; + uint8 prohibitive_way_constraints = 0; + char buf_permissive[60]; + char buf_prohibitive[60]; + //Read the values from a file, and put them into an array. + for(uint8 i = 0; i < 8; i++) + { + sprintf(buf_permissive, "way_constraint_permissive[%d]", i); + sprintf(buf_prohibitive, "way_constraint_prohibitive[%d]", i); + uint8 tmp_permissive = (obj.get_int(buf_permissive, 255)); + uint8 tmp_prohibitive = (obj.get_int(buf_prohibitive, 255)); + + // Values must fit into one byte + // Must therefore be 0-7 + if(tmp_permissive > 7 || tmp_prohibitive > 7) + { + continue; + } + + //Compress values into a single byte using bitwise OR. + permissive_way_constraints = (tmp_permissive > 0) ? permissive_way_constraints | (uint8)pow(2, (double)tmp_permissive) : permissive_way_constraints | 1; + prohibitive_way_constraints = (tmp_prohibitive > 0) ? prohibitive_way_constraints | (uint8)pow(2, (double)tmp_prohibitive) : prohibitive_way_constraints | 1; + } + // Hajo: Version needs high bit set as trigger -> this is required // as marker because formerly nodes were unversionend uint16 version = 0x8008; - node.write_uint16(outfp, version, 0); - node.write_uint16(outfp, topspeed, 2); - node.write_uint32(outfp, preis, 4); - node.write_uint32(outfp, maintenance, 8); - node.write_uint8 (outfp, wegtyp, 12); - node.write_uint8 (outfp, pillars_every, 13); - node.write_uint8 (outfp, max_length, 14); - node.write_uint16(outfp, intro_date, 15); - node.write_uint16(outfp, obsolete_date, 17); - node.write_uint8 (outfp, pillar_asymmetric, 19); - node.write_uint8 (outfp, max_height, 20); + node.write_uint16(outfp, version, 0); + node.write_uint16(outfp, topspeed, 2); + node.write_uint32(outfp, preis, 4); + node.write_uint32(outfp, maintenance, 8); + node.write_uint8 (outfp, wegtyp, 12); + node.write_uint8 (outfp, pillars_every, 13); + node.write_uint8 (outfp, max_length, 14); + node.write_uint16(outfp, intro_date, 15); + node.write_uint16(outfp, obsolete_date, 17); + node.write_uint8 (outfp, pillar_asymmetric, 19); + node.write_uint8 (outfp, max_height, 20); + node.write_uint32(outfp, max_weight, 22); + node.write_uint8(outfp, permissive_way_constraints, 26); + node.write_uint8(outfp, prohibitive_way_constraints,27); static const char* const names[] = { "image", diff --git a/besch/writer/tunnel_writer.cc b/besch/writer/tunnel_writer.cc index 5a0f5050711..da352e781f8 100644 --- a/besch/writer/tunnel_writer.cc +++ b/besch/writer/tunnel_writer.cc @@ -1,3 +1,4 @@ +#include #include "../../utils/cstring_t.h" #include "../../dataobj/tabfile.h" #include "../../dataobj/ribi.h" @@ -14,12 +15,13 @@ void tunnel_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj) { int pos, i; - obj_node_t node(this, 20, &parent); + obj_node_t node(this, 26, &parent); - uint32 topspeed = obj.get_int("topspeed", 999); - uint32 preis = obj.get_int("cost", 0); - uint32 maintenance = obj.get_int("maintenance", 1000); + uint32 topspeed = obj.get_int("topspeed", 999); + uint32 preis = obj.get_int("cost", 0); + uint32 maintenance = obj.get_int("maintenance",1000); uint8 wegtyp = get_waytype(obj.get("waytype")); + uint32 max_weight = obj.get_int("max_weight", 999); // prissi: timeline uint16 intro_date = obj.get_int("intro_year", DEFAULT_INTRO_DATE) * 12; @@ -28,16 +30,52 @@ void tunnel_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj) uint16 obsolete_date = obj.get_int("retire_year", DEFAULT_RETIRE_DATE) * 12; obsolete_date += obj.get_int("retire_month", 1) - 1; + // Way constraints + // One byte for permissive, one byte for prohibitive. + // Therefore, 8 possible constraints of each type. + // Permissive: way allows vehicles with matching constraint: + // vehicles not allowed on any other sort of way. Vehicles + // without that constraint also allowed on the way. + // Prohibitive: way allows only vehicles with matching constraint: + // vehicles with matching constraint allowed on other sorts of way. + // @author: jamespetts + + uint8 permissive_way_constraints = 0; + uint8 prohibitive_way_constraints = 0; + char buf_permissive[60]; + char buf_prohibitive[60]; + //Read the values from a file, and put them into an array. + for(uint8 i = 0; i < 8; i++) + { + sprintf(buf_permissive, "way_constraint_permissive[%d]", i); + sprintf(buf_prohibitive, "way_constraint_prohibitive[%d]", i); + uint8 tmp_permissive = (obj.get_int(buf_permissive, 255)); + uint8 tmp_prohibitive = (obj.get_int(buf_prohibitive, 255)); + + //Compress values into a single byte using bitwise OR. + if(tmp_permissive < 8) + { + permissive_way_constraints = (tmp_permissive > 0) ? permissive_way_constraints | (uint8)pow(2, (double)tmp_permissive) : permissive_way_constraints | 1; + } + if(tmp_prohibitive < 8) + { + prohibitive_way_constraints = (tmp_prohibitive > 0) ? prohibitive_way_constraints | (uint8)pow(2, (double)tmp_prohibitive) : prohibitive_way_constraints | 1; + } + } + // Version uses always high bit set as trigger // version 2: snow images uint16 version = 0x8002; - node.write_uint16(fp, version, 0); - node.write_uint32(fp, topspeed, 2); - node.write_uint32(fp, preis, 6); - node.write_uint32(fp, maintenance, 10); - node.write_uint8 (fp, wegtyp, 14); - node.write_uint16(fp, intro_date, 15); - node.write_uint16(fp, obsolete_date, 17); + node.write_uint16(fp, version, 0); + node.write_uint32(fp, topspeed, 2); + node.write_uint32(fp, preis, 6); + node.write_uint32(fp, maintenance, 10); + node.write_uint8 (fp, wegtyp, 14); + node.write_uint16(fp, intro_date, 15); + node.write_uint16(fp, obsolete_date, 17); + node.write_uint32(fp, max_weight, 20); + node.write_uint8(fp, permissive_way_constraints, 24); + node.write_uint8(fp, prohibitive_way_constraints, 25); sint8 number_seasons = 0; diff --git a/besch/writer/vehicle_writer.cc b/besch/writer/vehicle_writer.cc index 834a08d9701..9cfef80f6ff 100644 --- a/besch/writer/vehicle_writer.cc +++ b/besch/writer/vehicle_writer.cc @@ -1,3 +1,4 @@ +#include #include "../../utils/simstring.h" #include "../../utils/cstring_t.h" #include "../../dataobj/tabfile.h" @@ -49,15 +50,35 @@ static uint8 get_engine_type(const char* engine_type, tabfileobj_t& obj) /** * Writes vehicle node data to file + * + * NOTE: The data must be written in _exactly_ + * the same sequence as it is to be read in the + * relevant reader file. The "total_len" field is + * the length in bytes of the VHCL node of the + * pak file. The VHCL node is the first node + * beneath the header node, and contains all of + * the _numerical_ information about the vehicle, + * such as the introduction date, running costs, + * etc.. Text (including filenames of sound files), + * and graphics are _not_ part of the VHCL node, + * and therefore do not count towards total length. + * Furthermore, the third argument to the node.write + * method must ascend sequentially with the number + * of bytes written so far (up 1 for a uint8, 2 for + * a uint16, 4 for a uint32 and so forth). Failure + * to observe these rules will result in data + * corruption and errors when the pak file is read + * by the main program. + * @author of note: jamespetts */ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj) { int i; uint8 uv8; - int total_len = 31; + int total_len = 35; - // prissi: must be done here, since it may affect the len of the header! + // prissi: must be done here, since it may affect the length of the header! cstring_t sound_str = ltrim( obj.get("sound") ); sint8 sound_id=NO_SOUND; if (sound_str.len() > 0) { @@ -141,7 +162,6 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj uint16 gear = (obj.get_int("gear", 100) * 64) / 100; node.write_uint16(fp, gear, 22); - // Hajodoc: Type of way this vehicle drives on // Hajoval: road, track, electrified_track, monorail_track, maglev_track, water const char* waytype = obj.get("waytype"); @@ -159,6 +179,7 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj xref_writer_t::instance()->write_obj(fp, node, obj_smoke, obj.get("smoke"), false); // Jetzt kommen die Bildlisten + // "Now the picture lists" (Google) static const char* const dir_codes[] = { "s", "w", "sw", "se", "n", "e", "ne", "nw" }; @@ -185,7 +206,7 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj for (i = 0; i < 8; i++) { char buf[40]; - // Hajodoc: Empty vehicle image for direction, direction in "s", "w", "sw", "se", unsymmetric vehicles need also "n", "e", "ne", "nw" + // Hajodoc: Empty vehicle image for direction, direction in "s", "w", "sw", "se", asymmetric vehicles need also "n", "e", "ne", "nw" sprintf(buf, "emptyimage[%s]", dir_codes[i]); str = obj.get(buf); if (str.len() > 0) { @@ -245,6 +266,7 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj // // Vorgänger/Nachfolgerbedingungen + // "Predecessor / Successor conditions" (Google) // uint8 besch_vorgaenger = 0; do { @@ -328,10 +350,58 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj node.write_sint8(fp, besch_nachfolger, 29); node.write_uint8(fp, (uint8) freight_max, 30); + // Whether this is a tilting train + // int + //@author: jamespetts + uint8 tilting = (obj.get_int("is_tilting", 0)); + node.write_uint8(fp, tilting, 31); + + // Way constraints + // One byte for permissive, one byte for prohibitive. + // Therefore, 8 possible constraints of each type. + // Permissive: way allows vehicles with matching constraint: + // vehicles not allowed on any other sort of way. Vehicles + // without that constraint also allowed on the way. + // Prohibitive: way allows only vehicles with matching constraint: + // vehicles with matching constraint allowed on other sorts of way. + // @author: jamespetts + + uint8 permissive_way_constraints = 0; + uint8 prohibitive_way_constraints = 0; + char buf_permissive[60]; + char buf_prohibitive[60]; + //Read the values from a file, and put them into an array. + for(uint8 i = 0; i < 8; i++) + { + sprintf(buf_permissive, "way_constraint_permissive[%d]", i); + sprintf(buf_prohibitive, "way_constraint_prohibitive[%d]", i); + uint8 tmp_permissive = (obj.get_int(buf_permissive, 255)); + uint8 tmp_prohibitive = (obj.get_int(buf_prohibitive, 255)); + + //Compress values into a single byte using bitwise OR. + if(tmp_permissive < 8) + { + permissive_way_constraints = (tmp_permissive > 0) ? permissive_way_constraints | (uint8)pow(2, (double)tmp_permissive) : permissive_way_constraints | 1; + } + if(tmp_prohibitive < 8) + { + prohibitive_way_constraints = (tmp_prohibitive > 0) ? prohibitive_way_constraints | (uint8)pow(2, (double)tmp_prohibitive) : prohibitive_way_constraints | 1; + } + } + node.write_uint8(fp, permissive_way_constraints, 32); + node.write_uint8(fp, prohibitive_way_constraints, 33); + + // Catering level. 0 = no catering. + // Higher numbers, better catering. + // Catering boosts passenger revenue. + // @author: jamespetts + uint8 catering_level = (obj.get_int("catering_level", 0)); + node.write_uint8(fp, catering_level, 34); + sint8 sound_str_len = sound_str.len(); if (sound_str_len > 0) { - node.write_sint8 (fp, sound_str_len, 31); - node.write_data_at(fp, sound_str, 32, sound_str_len); + node.write_sint8 (fp, sound_str_len, 35); + node.write_data_at(fp, sound_str, 36, sound_str_len); } node.write(fp); diff --git a/besch/writer/way_obj_writer.cc b/besch/writer/way_obj_writer.cc index c5cfcc356d8..5218f230f35 100644 --- a/besch/writer/way_obj_writer.cc +++ b/besch/writer/way_obj_writer.cc @@ -1,3 +1,4 @@ +#include #include "../../utils/cstring_t.h" #include "../../dataobj/tabfile.h" #include "obj_node.h" @@ -21,7 +22,7 @@ void way_obj_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& }; int ribi, hang; - obj_node_t node(this, 20, &parent); + obj_node_t node(this, 22, &parent); // Hajo: Version needs high bit set as trigger -> this is required @@ -40,14 +41,49 @@ void way_obj_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& uint8 wtyp = get_waytype(obj.get("waytype")); uint8 own_wtyp = get_waytype(obj.get("own_waytype")); - node.write_uint16(outfp, version, 0); - node.write_uint32(outfp, price, 2); - node.write_uint32(outfp, maintenance, 6); - node.write_uint32(outfp, topspeed, 10); - node.write_uint16(outfp, intro, 14); - node.write_uint16(outfp, retire, 16); - node.write_uint8 (outfp, wtyp, 18); - node.write_uint8 (outfp, own_wtyp, 19); + // Way constraints + // One byte for permissive, one byte for prohibitive. + // Therefore, 8 possible constraints of each type. + // Permissive: way allows vehicles with matching constraint: + // vehicles not allowed on any other sort of way. Vehicles + // without that constraint also allowed on the way. + // Prohibitive: way allows only vehicles with matching constraint: + // vehicles with matching constraint allowed on other sorts of way. + // @author: jamespetts + + uint8 permissive_way_constraints = 0; + uint8 prohibitive_way_constraints = 0; + char buf_permissive[60]; + char buf_prohibitive[60]; + //Read the values from a file, and put them into an array. + for(uint8 i = 0; i < 8; i++) + { + sprintf(buf_permissive, "way_constraint_permissive[%d]", i); + sprintf(buf_prohibitive, "way_constraint_prohibitive[%d]", i); + uint8 tmp_permissive = (obj.get_int(buf_permissive, 255)); + uint8 tmp_prohibitive = (obj.get_int(buf_prohibitive, 255)); + + //Compress values into a single byte using bitwise OR. + if(tmp_permissive < 8) + { + permissive_way_constraints = (tmp_permissive > 0) ? permissive_way_constraints | (uint8)pow(2, (double)tmp_permissive) : permissive_way_constraints | 1; + } + if(tmp_prohibitive < 8) + { + prohibitive_way_constraints = (tmp_prohibitive > 0) ? prohibitive_way_constraints | (uint8)pow(2, (double)tmp_prohibitive) : prohibitive_way_constraints | 1; + } + } + + node.write_uint16(outfp, version, 0); + node.write_uint32(outfp, price, 2); + node.write_uint32(outfp, maintenance, 6); + node.write_uint32(outfp, topspeed, 10); + node.write_uint16(outfp, intro, 14); + node.write_uint16(outfp, retire, 16); + node.write_uint8 (outfp, wtyp, 18); + node.write_uint8 (outfp, own_wtyp, 19); + node.write_uint8(outfp, permissive_way_constraints, 20); + node.write_uint8(outfp, prohibitive_way_constraints,21); write_head(outfp, node, obj); diff --git a/besch/writer/way_writer.cc b/besch/writer/way_writer.cc index fc48ca9099f..6f498d71d2c 100644 --- a/besch/writer/way_writer.cc +++ b/besch/writer/way_writer.cc @@ -1,3 +1,4 @@ +#include #include "../../utils/cstring_t.h" #include "../../dataobj/tabfile.h" #include "obj_node.h" @@ -21,8 +22,8 @@ void way_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& obj) }; int ribi, hang; - // Hajo: node size is 25 bytes - obj_node_t node(this, 26, &parent); + // Hajo: node size is 27 bytes + obj_node_t node(this, 27, &parent); // Hajo: Version needs high bit set as trigger -> this is required @@ -52,16 +53,51 @@ void way_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& obj) uint8 draw_as_ding = (obj.get_int("draw_as_ding", 0) == 1); sint8 number_seasons = 0; - node.write_uint16(outfp, version, 0); - node.write_uint32(outfp, price, 2); - node.write_uint32(outfp, maintenance, 6); - node.write_uint32(outfp, topspeed, 10); - node.write_uint32(outfp, max_weight, 14); - node.write_uint16(outfp, intro, 18); - node.write_uint16(outfp, retire, 20); - node.write_uint8 (outfp, wtyp, 22); - node.write_uint8 (outfp, styp, 23); - node.write_uint8 (outfp, draw_as_ding, 24); + // Way constraints + // One byte for permissive, one byte for prohibitive. + // Therefore, 8 possible constraints of each type. + // Permissive: way allows vehicles with matching constraint: + // vehicles not allowed on any other sort of way. Vehicles + // without that constraint also allowed on the way. + // Prohibitive: way allows only vehicles with matching constraint: + // vehicles with matching constraint allowed on other sorts of way. + // @author: jamespetts + + uint8 permissive_way_constraints = 0; + uint8 prohibitive_way_constraints = 0; + char buf_permissive[60]; + char buf_prohibitive[60]; + //Read the values from a file, and put them into an array. + for(uint8 i = 0; i < 8; i++) + { + sprintf(buf_permissive, "way_constraint_permissive[%d]", i); + sprintf(buf_prohibitive, "way_constraint_prohibitive[%d]", i); + uint8 tmp_permissive = (obj.get_int(buf_permissive, 255)); + uint8 tmp_prohibitive = (obj.get_int(buf_prohibitive, 255)); + + //Compress values into a single byte using bitwise OR. + if(tmp_permissive < 8) + { + permissive_way_constraints = (tmp_permissive > 0) ? permissive_way_constraints | (uint8)pow(2, (double)tmp_permissive) : permissive_way_constraints | 1; + } + if(tmp_prohibitive < 8) + { + prohibitive_way_constraints = (tmp_prohibitive > 0) ? prohibitive_way_constraints | (uint8)pow(2, (double)tmp_prohibitive) : prohibitive_way_constraints | 1; + } + } + + node.write_uint16(outfp, version, 0); + node.write_uint32(outfp, price, 2); + node.write_uint32(outfp, maintenance, 6); + node.write_uint32(outfp, topspeed, 10); + node.write_uint32(outfp, max_weight, 14); + node.write_uint16(outfp, intro, 18); + node.write_uint16(outfp, retire, 20); + node.write_uint8 (outfp, wtyp, 22); + node.write_uint8 (outfp, styp, 23); + node.write_uint8 (outfp, draw_as_ding, 24); + node.write_uint8(outfp, permissive_way_constraints, 26); + node.write_uint8(outfp, prohibitive_way_constraints,27); slist_tpl keys; char buf[40]; diff --git a/boden/grund.cc b/boden/grund.cc index bb9cadd450d..a103dadf6c6 100644 --- a/boden/grund.cc +++ b/boden/grund.cc @@ -227,6 +227,8 @@ void grund_t::rdwr(loadsave_t *file) w->set_besch(sch->get_besch()); w->set_max_speed(sch->get_max_speed()); w->set_ribi(sch->get_ribi_unmasked()); + weg->set_max_weight(sch->get_max_weight()); + weg->add_way_constraints(sch->get_way_constraints_permissive(), sch->get_way_constraints_prohibitive()); delete sch; weg = w; } diff --git a/boden/wege/kanal.cc b/boden/wege/kanal.cc index a15af0b8632..30bea37b1cb 100644 --- a/boden/wege/kanal.cc +++ b/boden/wege/kanal.cc @@ -66,5 +66,6 @@ kanal_t::rdwr(loadsave_t *file) if(old_max_speed>0) { set_max_speed(old_max_speed); } + } } diff --git a/boden/wege/maglev.cc b/boden/wege/maglev.cc index 2051d0499aa..c8c12bfb65d 100644 --- a/boden/wege/maglev.cc +++ b/boden/wege/maglev.cc @@ -28,11 +28,16 @@ maglev_t::rdwr(loadsave_t *file) if(get_besch()->get_wtyp()!=maglev_wt) { int old_max_speed = get_max_speed(); + int old_max_weight = get_max_weight(); const weg_besch_t *besch = wegbauer_t::weg_search( maglev_wt, (old_max_speed>0 ? old_max_speed : 120), 0, (weg_t::system_type)((get_besch()->get_styp()==weg_t::type_elevated)*weg_t::type_elevated) ); dbg->warning("maglev_t::rwdr()", "Unknown way replaced by maglev %s (old_max_speed %i)", besch->get_name(), old_max_speed ); set_besch(besch); - if(old_max_speed>0) { + if(old_max_speed > 0) { set_max_speed(old_max_speed); } + if(old_max_weight > 0) + { + set_max_weight(old_max_weight); + } } } diff --git a/boden/wege/monorail.cc b/boden/wege/monorail.cc index 688065bef12..279ea362ebb 100644 --- a/boden/wege/monorail.cc +++ b/boden/wege/monorail.cc @@ -23,11 +23,16 @@ void monorail_t::rdwr(loadsave_t *file) if(get_besch()->get_wtyp()!=monorail_wt) { int old_max_speed = get_max_speed(); + int old_max_weight = get_max_weight(); const weg_besch_t *besch = wegbauer_t::weg_search( monorail_wt, (old_max_speed>0 ? old_max_speed : 120), 0, (weg_t::system_type)((get_besch()->get_styp()==weg_t::type_elevated)*weg_t::type_elevated) ); dbg->warning("monorail_t::rwdr()", "Unknown way replaced by monorail %s (old_max_speed %i)", besch->get_name(), old_max_speed ); set_besch(besch); if(old_max_speed>0) { set_max_speed(old_max_speed); } + if(old_max_weight > 0) + { + set_max_weight(old_max_weight); + } } } diff --git a/boden/wege/narrowgauge.cc b/boden/wege/narrowgauge.cc index 922b2e40584..cd75228b6ec 100644 --- a/boden/wege/narrowgauge.cc +++ b/boden/wege/narrowgauge.cc @@ -24,11 +24,16 @@ narrowgauge_t::rdwr(loadsave_t *file) if(get_besch()->get_wtyp()!=narrowgauge_wt) { int old_max_speed = get_max_speed(); + int old_max_weight = get_max_weight(); const weg_besch_t *besch = wegbauer_t::weg_search( narrowgauge_wt, (old_max_speed>0 ? old_max_speed : 120), 0, (weg_t::system_type)((get_besch()->get_styp()==weg_t::type_elevated)*weg_t::type_elevated) ); dbg->warning("narrowgauge_t::rwdr()", "Unknown way replaced by narrow gauge %s (old_max_speed %i)", besch->get_name(), old_max_speed ); set_besch(besch); if(old_max_speed>0) { set_max_speed(old_max_speed); } + if(old_max_weight > 0) + { + set_max_weight(old_max_weight); + } } } diff --git a/boden/wege/schiene.cc b/boden/wege/schiene.cc index f1ac67b58a2..b2da76083af 100644 --- a/boden/wege/schiene.cc +++ b/boden/wege/schiene.cc @@ -165,6 +165,7 @@ schiene_t::rdwr(loadsave_t *file) file->rdwr_str(bname, 128 ); int old_max_speed=get_max_speed(); + int old_max_weight = get_max_weight(); const weg_besch_t *besch = wegbauer_t::get_besch(bname); if(besch==NULL) { int old_max_speed=get_max_speed(); @@ -179,5 +180,10 @@ schiene_t::rdwr(loadsave_t *file) set_max_speed(old_max_speed); } //DBG_MESSAGE("schiene_t::rdwr","track %s at (%i,%i) max_speed %i",bname,get_pos().x,get_pos().y,old_max_speed); + if(old_max_weight > 0) + { + set_max_weight(old_max_weight); + } + //DBG_MESSAGE("schiene_t::rdwr","track %s at (%i,%i) max_speed %i",bname,get_pos().x,get_pos().y,old_max_speed); } } diff --git a/boden/wege/weg.cc b/boden/wege/weg.cc index 40d191db806..ce8bfa319cf 100644 --- a/boden/wege/weg.cc +++ b/boden/wege/weg.cc @@ -134,6 +134,23 @@ void weg_t::set_max_speed(unsigned int s) max_speed = s; } +void weg_t::set_max_weight(uint32 w) +{ + max_weight = w; +} + +void weg_t::add_way_constraints(const uint8 permissive, const uint8 prohibitive) +{ + way_constraints_permissive |= permissive; + way_constraints_prohibitive |= prohibitive; +} + +void weg_t::reset_way_constraints() +{ + way_constraints_permissive = besch->get_way_constraints_permissive(); + way_constraints_prohibitive = besch->get_way_constraints_prohibitive(); +} + /** * Setzt neue Beschreibung. Ersetzt alte Höchstgeschwindigkeit @@ -144,11 +161,16 @@ void weg_t::set_besch(const weg_besch_t *b) { besch = b; if (hat_gehweg() && besch->get_wtyp() == road_wt && besch->get_topspeed() > 50) { + //Limit speeds for city roads. max_speed = 50; } else { max_speed = besch->get_topspeed(); } + + max_weight = besch->get_max_weight(); + way_constraints_permissive = besch->get_way_constraints_permissive(); + way_constraints_prohibitive = besch->get_way_constraints_prohibitive(); } @@ -249,13 +271,34 @@ void weg_t::info(cbuffer_t & buf) const buf.append(max_speed); buf.append(translator::translate("km/h\n")); + buf.append(translator::translate("\nMax. weight:")); + buf.append(" "); + buf.append(max_weight); + buf.append("t "); + buf.append("\n"); + for(sint8 i = -8; i < 8; i ++) + { + if(permissive_way_constraint_set(i + 8)) + { + buf.append(translator::translate("Way constraint permissive ")); + buf.append(i); + buf.append("\n"); + } + if(prohibitive_way_constraint_set(i)) + { + buf.append(translator::translate("Way constraint prohibitive %n\n")); + buf.append(i); + buf.append("\n"); + } + } +#ifdef DEBUG buf.append(translator::translate("\nRibi (unmasked)")); buf.append(get_ribi_unmasked()); buf.append(translator::translate("\nRibi (masked)")); buf.append(get_ribi()); buf.append("\n"); - +#endif if(has_sign()) { buf.append(translator::translate("\nwith sign/signal\n")); } diff --git a/boden/wege/weg.h b/boden/wege/weg.h index f3e5cfc4d19..465aab57c6b 100644 --- a/boden/wege/weg.h +++ b/boden/wege/weg.h @@ -107,6 +107,12 @@ class weg_t : public ding_t */ uint16 max_speed; + /** + * Likewise for weight + * @author: jamespetts + */ + uint32 max_weight; + image_id bild; /** @@ -121,6 +127,11 @@ class weg_t : public ding_t */ void init_statistics(); + /*Way constraints for, e.g., loading gauges, types of electrification, etc. + * @author: jamespetts*/ + uint8 way_constraints_permissive; + uint8 way_constraints_prohibitive; + public: weg_t(karte_t* welt, loadsave_t*) : ding_t(welt) { init(); } @@ -140,15 +151,43 @@ class weg_t : public ding_t */ void set_max_speed(unsigned int s); + void set_max_weight(uint32 w); + + //Adds the way constraints to the way. Note: does *not* replace them - they are added together. + void add_way_constraints(const uint8 permissive, const uint8 prohibitive); + + //Resets constraints to their base values. Used when removing way objects. + void weg_t::reset_way_constraints(); + + uint8 get_way_constraints_permissive() const { return way_constraints_permissive; } + uint8 get_way_constraints_prohibitive() const { return way_constraints_prohibitive; } + + + bool permissive_way_constraint_set(uint8 i) const + { + return (way_constraints_permissive & 1<get_version()>101000) { file->rdwr_bool( seperate_halt_capacities, "" ); file->rdwr_byte( pay_for_total_distance, "" ); + + file->rdwr_short( river_number, "" ); + file->rdwr_short( min_river_length, "" ); + file->rdwr_short( max_river_length, "" ); } } } @@ -478,13 +508,20 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s umgebung_t::max_acceleration = contents.get_int("fast_forward", umgebung_t::max_acceleration); umgebung_t::intercity_road_length = contents.get_int("intercity_road_length", umgebung_t::intercity_road_length); - cstring_t *test = new cstring_t(ltrim(contents.get("intercity_road_type"))); - if(test->len()>0) { + const char *test = ltrim(contents.get("intercity_road_type")); + if(*test && test) { delete umgebung_t::intercity_road_type; - umgebung_t::intercity_road_type = test; + umgebung_t::intercity_road_type = strdup(test); } - else { - delete test; + + // up to ten rivers are possible + for( int i = 0; i<10; i++ ) { + char name[32]; + sprintf( name, "river_type[%i]", i ); + const char *test = ltrim(contents.get(name)); + if(test && *test) { + umgebung_t::river_type[umgebung_t::river_types++] = strdup( test ); + } } umgebung_t::autosave = (contents.get_int("autosave", umgebung_t::autosave)); @@ -520,6 +557,10 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s city_road_type[255] = 0; } + river_number = contents.get_int("river_number", river_number ); + min_river_length = contents.get_int("river_min_length", min_river_length ); + max_river_length = contents.get_int("river_max_length", max_river_length ); + pak_diagonal_multiplier = contents.get_int("diagonal_multiplier", pak_diagonal_multiplier); factory_spacing = contents.get_int("factory_spacing", factory_spacing ); @@ -569,6 +610,89 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s way_max_bridge_len = contents.get_int("way_max_bridge_len", way_max_bridge_len); way_count_leaving_road = contents.get_int("way_leaving_road", way_count_leaving_road); + //Local bonus adjustment + min_bonus_max_distance = contents.get_int("min_bonus_max_distance", min_bonus_max_distance); + max_bonus_min_distance = contents.get_int("max_bonus_min_distance", max_bonus_min_distance); + local_bonus_multiplier = contents.get_int("local_bonus_multiplier_percent", local_bonus_multiplier); + + //Obsolete vehicles' running cost increase + obsolete_running_cost_increase_percent = contents.get_int("obsolete_running_cost_increase_percent", obsolete_running_cost_increase_percent); + obsolete_running_cost_increase_phase_years = contents.get_int("obsolete_running_cost_increase_phase_years", obsolete_running_cost_increase_phase_years); + + // Passenger destination ranges + local_passengers_min_distance = contents.get_int("local_passengers_min_distance", local_passengers_min_distance); + local_passengers_max_distance = contents.get_int("local_passengers_max_distance", local_passengers_max_distance); + midrange_passengers_min_distance = contents.get_int("midrange_passengers_min_distance", midrange_passengers_min_distance); + midrange_passengers_max_distance = contents.get_int("midrange_passengers_max_distance", midrange_passengers_max_distance); + longdistance_passengers_min_distance = contents.get_int("longdistance_passengers_min_distance", longdistance_passengers_min_distance); + longdistance_passengers_max_distance = contents.get_int("longdistance_passengers_max_distance", longdistance_passengers_max_distance); + + // Passenger routing settings + passenger_routing_packet_size = contents.get_int("passenger_routing_packet_size", passenger_routing_packet_size); + max_alternative_destinations = contents.get_int("max_alternative_destinations", max_alternative_destinations); + passenger_routing_local_chance = contents.get_int("passenger_routing_local_chance ", passenger_routing_local_chance); + passenger_routing_midrange_chance = contents.get_int("passenger_routing_midrange_chance", passenger_routing_midrange_chance); + base_car_preference_percent = contents.get_int("base_car_preference_percent", 90); + always_prefer_car_percent = contents.get_int("always_prefer_car_percent", 10); + congestion_density_factor = contents.get_int("congestion_density_factor", 12); + + //Cornering settings + max_corner_limit[waytype_t::road_wt] = contents.get_int("max_corner_limit_road", 200); + min_corner_limit[waytype_t::road_wt] = contents.get_int("min_corner_limit_road", 30); + max_corner_adjustment_factor[waytype_t::road_wt] = contents.get_int("max_corner_adjustment_factor_road", 75); + min_corner_adjustment_factor[waytype_t::road_wt] = contents.get_int("min_corner_adjustment_factor_road", 97); + min_direction_steps[waytype_t::road_wt] = contents.get_int("min_direction_steps_road", 3); + max_direction_steps[waytype_t::road_wt] = contents.get_int("max_direction_steps_road", 6); + curve_friction_factor[waytype_t::road_wt] = contents.get_int("curve_friction_factor_road", 0); + + max_corner_limit[waytype_t::track_wt] = contents.get_int("max_corner_limit_track", 425); + min_corner_limit[waytype_t::track_wt] = contents.get_int("min_corner_limit_track", 45); + max_corner_adjustment_factor[waytype_t::track_wt] = contents.get_int("max_corner_adjustment_factor_track", 50); + min_corner_adjustment_factor[waytype_t::track_wt] = contents.get_int("min_corner_adjustment_factor_track", 85); + min_direction_steps[waytype_t::track_wt] = contents.get_int("min_direction_steps_track", 4); + max_direction_steps[waytype_t::track_wt] = contents.get_int("max_direction_steps_track", 14); + curve_friction_factor[waytype_t::track_wt] = contents.get_int("curve_friction_factor_track", 0); + + max_corner_limit[waytype_t::tram_wt] = contents.get_int("max_corner_limit_tram", 425); + min_corner_limit[waytype_t::tram_wt] = contents.get_int("min_corner_limit_tram", 45); + max_corner_adjustment_factor[waytype_t::tram_wt] = contents.get_int("max_corner_adjustment_factor_tram", 50); + min_corner_adjustment_factor[waytype_t::tram_wt] = contents.get_int("min_corner_adjustment_factor_tram", 85); + min_direction_steps[waytype_t::tram_wt] = contents.get_int("min_direction_steps_tram", 4); + max_direction_steps[waytype_t::tram_wt] = contents.get_int("max_direction_steps_tram", 14); + curve_friction_factor[waytype_t::tram_wt] = contents.get_int("curve_friction_factor_tram", 0); + + max_corner_limit[waytype_t::tram_wt] = contents.get_int("max_corner_limit_tram", 250); + min_corner_limit[waytype_t::tram_wt] = contents.get_int("min_corner_limit_tram", 30); + max_corner_adjustment_factor[waytype_t::tram_wt] = contents.get_int("max_corner_adjustment_factor_tram", 60); + min_corner_adjustment_factor[waytype_t::tram_wt] = contents.get_int("min_corner_adjustment_factor_tram", 90); + min_direction_steps[waytype_t::tram_wt] = contents.get_int("min_direction_steps_tram", 3); + max_direction_steps[waytype_t::tram_wt] = contents.get_int("max_direction_steps_tram", 10); + curve_friction_factor[waytype_t::tram_wt] = contents.get_int("curve_friction_factor_tram", 0); + + max_corner_limit[waytype_t::monorail_wt] = contents.get_int("max_corner_limit_monorail", 425); + min_corner_limit[waytype_t::monorail_wt] = contents.get_int("min_corner_limit_monorail", 75); + max_corner_adjustment_factor[waytype_t::monorail_wt] = contents.get_int("max_corner_adjustment_factor_monorail", 50); + min_corner_adjustment_factor[waytype_t::monorail_wt] = contents.get_int("min_corner_adjustment_factor_monorail", 85); + min_direction_steps[waytype_t::monorail_wt] = contents.get_int("min_direction_steps_monorail", 5); + max_direction_steps[waytype_t::monorail_wt] = contents.get_int("max_direction_steps_monorail", 16); + curve_friction_factor[waytype_t::monorail_wt] = contents.get_int("curve_friction_factor_monorail", 0); + + max_corner_limit[waytype_t::maglev_wt] = contents.get_int("max_corner_limit_maglev", 500); + min_corner_limit[waytype_t::maglev_wt] = contents.get_int("min_corner_limit_maglev", 50); + max_corner_adjustment_factor[waytype_t::maglev_wt] = contents.get_int("max_corner_adjustment_factor_maglev", 40); + min_corner_adjustment_factor[waytype_t::maglev_wt] = contents.get_int("min_corner_adjustment_factor_maglev", 80); + min_direction_steps[waytype_t::maglev_wt] = contents.get_int("min_direction_steps_maglev", 4); + max_direction_steps[waytype_t::maglev_wt] = contents.get_int("max_direction_steps_maglev", 16); + curve_friction_factor[waytype_t::maglev_wt] = contents.get_int("curve_friction_factor_maglev", 0); + + max_corner_limit[waytype_t::narrowgauge_wt] = contents.get_int("max_corner_limit_narrowgauge", 250); + min_corner_limit[waytype_t::narrowgauge_wt] = contents.get_int("min_corner_limit_narrowgauge", 30); + max_corner_adjustment_factor[waytype_t::narrowgauge_wt] = contents.get_int("max_corner_adjustment_factor_narrowgauge", 66); + min_corner_adjustment_factor[waytype_t::narrowgauge_wt] = contents.get_int("min_corner_adjustment_factor_narrowgauge", 92); + min_direction_steps[waytype_t::narrowgauge_wt] = contents.get_int("min_direction_steps_narrowgauge", 3); + max_direction_steps[waytype_t::narrowgauge_wt] = contents.get_int("max_direction_steps_narrowgauge", 8); + curve_friction_factor[waytype_t::narrowgauge_wt] = contents.get_int("curve_friction_factor_narrowgauge", 0); + /* * Selection of savegame format through inifile */ diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index 0adf2da9664..df48e67e615 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -8,6 +8,7 @@ /** * Spieleinstellungen + * "Game options" * * Hj. Malthaner * @@ -56,6 +57,11 @@ class einstellungen_t double max_mountain_height; //01-Dec-01 Markus Weber Added double map_roughness; //01-Dec-01 Markus Weber Added + // river stuff + sint16 river_number; + sint16 min_river_length; + sint16 max_river_length; + uint8 allow_player_change; uint8 use_timeline; sint16 starting_year; @@ -141,6 +147,20 @@ class einstellungen_t */ uint8 pay_for_total_distance; + //Cornering settings + //@author: jamespetts + + //The array index corresponds + //to the waytype index. + + uint32 max_corner_limit[10]; + uint32 min_corner_limit[10]; + float max_corner_adjustment_factor[10]; + float min_corner_adjustment_factor[10]; + uint8 min_direction_steps[10]; + uint8 max_direction_steps[10]; + uint8 curve_friction_factor[10]; + public: /* the big cost section */ sint32 maint_building; // normal building @@ -181,6 +201,41 @@ class einstellungen_t uint32 way_max_bridge_len; sint32 way_count_leaving_road; + //@author: jamespetts + // Speed bonus local adjustment + uint16 min_bonus_max_distance; + uint16 max_bonus_min_distance; + uint16 local_bonus_multiplier; + + //@author: jamespetts + // Obsolete vehicle maintenance cost increases + uint16 obsolete_running_cost_increase_percent; + uint16 obsolete_running_cost_increase_phase_years; + + //@author: jamespetts + // Passenger destination ranges + // Use to set the extent to which passengers prefer local, medium, or long-range destinations. + // The distances can (and probably should) overlap. + uint16 local_passengers_min_distance; + uint16 local_passengers_max_distance; + uint16 midrange_passengers_min_distance; + uint16 midrange_passengers_max_distance; + uint16 longdistance_passengers_min_distance; + uint16 longdistance_passengers_max_distance; + + // @author: jamespetts + // Private ar settings + uint8 always_prefer_car_percent; + uint8 base_car_preference_percent; + uint8 congestion_density_factor; + + //@author: jamespetts + // Passenger routing settings + uint8 passenger_routing_packet_size; + uint8 max_alternative_destinations; + uint8 passenger_routing_local_chance; + uint8 passenger_routing_midrange_chance; + // true if active bool automaten[MAX_PLAYER_COUNT]; // 0 = emtpy, otherwise some vaule from simplay @@ -328,6 +383,39 @@ class einstellungen_t enum { TO_PREVIOUS, TO_TRANSFER, TO_DESTINATION }; uint8 get_pay_for_total_distance_mode() const { return pay_for_total_distance ; } void set_pay_for_total_distance_mode( uint8 b ) { pay_for_total_distance = b < 2 ? b : 0; } + sint16 get_river_number() const { return river_number; } void set_river_number( sint16 n ) { river_number=n; } sint16 get_min_river_length() const { return min_river_length; } void set_min_river_length( sint16 n ) { min_river_length=n; } sint16 get_max_river_length() const { return max_river_length; } void set_max_river_length( sint16 n ) { max_river_length=n; } uint16 get_min_bonus_max_distance() const { return min_bonus_max_distance; } + uint16 get_max_bonus_min_distance() const { return max_bonus_min_distance; } + uint16 get_local_bonus_multiplier() const { return local_bonus_multiplier; } + + uint16 get_obsolete_running_cost_increase_percent() const { return obsolete_running_cost_increase_percent; } + uint16 get_obsolete_running_cost_increase_phase_years() const { return obsolete_running_cost_increase_phase_years; } + + uint16 get_local_passengers_min_distance() const { return local_passengers_min_distance; } + uint16 get_local_passengers_max_distance() const { return local_passengers_max_distance; } + uint16 get_midrange_passengers_min_distance() const { return midrange_passengers_min_distance; } + uint16 get_midrange_passengers_max_distance() const { return midrange_passengers_max_distance; } + uint16 get_longdistance_passengers_min_distance() const { return longdistance_passengers_min_distance; } + uint16 get_longdistance_passengers_max_distance() const { return longdistance_passengers_max_distance; } + + uint8 get_passenger_routing_packet_size() const { return passenger_routing_packet_size; } + uint8 get_max_alternative_destinations() const { return max_alternative_destinations; } + uint8 get_passenger_routing_local_chance() const { return passenger_routing_local_chance; } + uint8 get_passenger_routing_midrange_chance() const { return passenger_routing_midrange_chance; } + + uint8 get_always_prefer_car_percent() const { return always_prefer_car_percent; } + uint8 get_base_car_preference_percent () const { return base_car_preference_percent; } + uint8 get_congestion_density_factor () const { return (congestion_density_factor > 0) ? congestion_density_factor : 1; } + + uint32 get_max_corner_limit(waytype_t waytype) const { return kmh_to_speed(max_corner_limit[waytype]); } + uint32 get_min_corner_limit (waytype_t waytype) const { return kmh_to_speed(min_corner_limit[waytype]); } + float get_max_corner_adjustment_factor (waytype_t waytype) const { return max_corner_adjustment_factor[waytype] / 100; } + float get_min_corner_adjustment_factor (waytype_t waytype) const { return min_corner_adjustment_factor[waytype] / 100; } + uint8 get_min_direction_steps (waytype_t waytype) const { return min_direction_steps[waytype]; } + uint8 get_max_direction_steps (waytype_t waytype) const { return max_direction_steps[waytype]; } + uint8 get_curve_friction_factor (waytype_t waytype) const { return curve_friction_factor[waytype]; } + + bool is_pay_for_total_distance() const { return pay_for_total_distance ; } + void set_pay_for_total_distance( bool b ) { pay_for_total_distance = b; } }; #endif diff --git a/dataobj/koord.h b/dataobj/koord.h index 50a474468b4..f92326c209b 100644 --- a/dataobj/koord.h +++ b/dataobj/koord.h @@ -109,6 +109,10 @@ static inline koord operator + (const koord& a, const koord& b) return koord(a.x + b.x, a.y + b.y); } +static inline bool operator <= (const koord & a, const koord & b) +{ + return (a.x == b.x) ? (a.y <= b.y) : (a.x < b.x); +} static inline koord operator - (const koord& a, const koord& b) { diff --git a/dataobj/ribi.h b/dataobj/ribi.h index a130c1e5159..6a96983391d 100644 --- a/dataobj/ribi.h +++ b/dataobj/ribi.h @@ -83,6 +83,10 @@ class hang_t { * brauchen wir etwas entsprechendes für Richtungsbits. Deshalb habe ich hier * eine Klasse mit einer Sammlung von Daten für richtungsbits angelegt * + * Hajo: After Volkers introduction of the NSOW array in the coordinates class + * we need something similar for direction bits. That is why I have a class with + * a collection of data created for direction bits. + * * @author Hansjörg Malthaner */ class ribi_t { @@ -96,24 +100,30 @@ class ribi_t { * 1=Nord, 2=Ost, 4=Sued, 8=West * * richtungsbits (ribi) koennen 16 Komb. darstellen. + * + * the enum direction is a generalization of the + * direction bits to designated constants, the + * values are as follows 1 = North, 2 = East, 4 = South, 8 = West + * + * direction bits (ribi) can 16 Komb. represent. */ enum _ribi { - keine=0, - nord = 1, - ost = 2, - nordost = 3, - sued = 4, - nordsued = 5, - suedost = 6, - nordsuedost = 7, - west = 8, - nordwest = 9, - ostwest = 10, + keine=0, //None + nord = 1, //North + ost = 2, //East + nordost = 3, //North-East + sued = 4, // South + nordsued = 5, + suedost = 6, //South-East + nordsuedost = 7, + west = 8, //West + nordwest = 9, //North-West + ostwest = 10, nordostwest = 11, - suedwest = 12, - nordsuedwest = 13, - suedostwest = 14, - alle = 15 + suedwest = 12, //South-West + nordsuedwest = 13, + suedostwest = 14, + alle = 15 //"Everything". }; typedef uint8 ribi; @@ -161,6 +171,7 @@ class ribi_t { static bool ist_kreuzung(ribi x) { return x > 0 && flags[x] == 0; } static dir get_dir(ribi x) { return dirs[x]; } + }; // @@ -168,6 +179,7 @@ class ribi_t { // // ribi_t::nord entspricht koord::nord entspricht hang_t::sued !!! // -> ich denke aufwaerts, also geht es auf einem Suedhang nach Norden! +// I think upwards, so it goes on a southern slope to the north! (Google) // hang_t::typ hang_typ(koord dir); // dir:nord -> hang:sued, ... ribi_t::ribi ribi_typ(koord dir); diff --git a/dataobj/route.cc b/dataobj/route.cc index a3695e0fc83..11db5e14ae9 100644 --- a/dataobj/route.cc +++ b/dataobj/route.cc @@ -400,7 +400,7 @@ bool route_t::intern_calc_route(karte_t *welt, const koord3d ziel, const koord3d // we took the target pos out of the closed list if(ziel==gr->get_pos()) { - ziel_erreicht = true; + ziel_erreicht = true; //"a goal reaches" (Babelfish). break; } diff --git a/dataobj/warenziel.h b/dataobj/warenziel.h index 30867ba82e0..be426066fd0 100644 --- a/dataobj/warenziel.h +++ b/dataobj/warenziel.h @@ -18,6 +18,10 @@ class loadsave_t; * Haltestellen benutzt. Grundlegende Elemente sind * eine Koordinate und ein Zeitstempel. * + * This class is for the management of targets + * used by bus stops. Essential elements are a + * coordinate and a time stamp. + * * @author Hj. Malthaner */ diff --git a/dings/bruecke.cc b/dings/bruecke.cc index e4a7538523e..aabe0c854de 100644 --- a/dings/bruecke.cc +++ b/dings/bruecke.cc @@ -92,7 +92,7 @@ void bruecke_t::rdwr(loadsave_t *file) -// correct speed and maitainace +// correct speed, maitainace and weight limit void bruecke_t::laden_abschliessen() { grund_t *gr = welt->lookup(get_pos()); @@ -117,7 +117,9 @@ void bruecke_t::laden_abschliessen() gr->neuen_weg_bauen( weg, 0, welt->get_spieler(1) ); } weg->set_max_speed(besch->get_topspeed()); - weg->set_besitzer(sp); + weg->set_max_weight(besch->get_max_weight()); + weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); + weg->set_besitzer(sp); //"besitzer" = owner (Babelfish) spieler_t::add_maintenance( sp, -weg->get_besch()->get_wartung()); } spieler_t::add_maintenance( sp, besch->get_wartung() ); @@ -137,6 +139,8 @@ void bruecke_t::entferne( spieler_t *sp2 ) weg_t *weg = gr->get_weg( besch->get_waytype() ); if(weg) { weg->set_max_speed( weg->get_besch()->get_topspeed() ); + weg->set_max_weight(weg->get_besch()->get_max_weight()); + weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); spieler_t::add_maintenance( sp, weg->get_besch()->get_wartung()); } } diff --git a/dings/gebaeude.cc b/dings/gebaeude.cc index c674169a93f..089aac72726 100644 --- a/dings/gebaeude.cc +++ b/dings/gebaeude.cc @@ -451,7 +451,7 @@ gebaeude_t::get_after_bild() const */ int gebaeude_t::get_passagier_level() const { - koord dim = tile->get_besch()->get_groesse(); + koord dim = tile->get_besch()->get_groesse(); //("Groesse" = "size") long pax = tile->get_besch()->get_level(); if (!is_factory && ptr.stadt != NULL) { // belongs to a city ... diff --git a/dings/tunnel.cc b/dings/tunnel.cc index 1253da7dcc1..5c5f83e4c3f 100644 --- a/dings/tunnel.cc +++ b/dings/tunnel.cc @@ -94,6 +94,7 @@ void tunnel_t::laden_abschliessen() // change maintainance weg_t *weg = gr->get_weg(besch->get_waytype()); if(weg) { + weg->set_max_speed(besch->get_topspeed()); weg->set_max_speed(besch->get_topspeed()); spieler_t::add_maintenance( sp, -weg->get_besch()->get_wartung()); } @@ -117,6 +118,8 @@ void tunnel_t::entferne( spieler_t *sp2 ) if(gr) { weg_t *weg = gr->get_weg( besch->get_waytype() ); weg->set_max_speed( weg->get_besch()->get_topspeed() ); + weg->set_max_weight( weg->get_besch()->get_max_weight() ); + weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); spieler_t::add_maintenance( sp, weg->get_besch()->get_wartung()); spieler_t::add_maintenance( sp, -besch->get_wartung() ); } diff --git a/dings/wayobj.cc b/dings/wayobj.cc index 4fa76ad96b0..3ef32b208bd 100644 --- a/dings/wayobj.cc +++ b/dings/wayobj.cc @@ -78,18 +78,21 @@ wayobj_t::~wayobj_t() if(weg) { // Weg wieder freigeben, wenn das Signal nicht mehr da ist. weg->set_electrify(false); - // restore old speed limit + // restore old speed limit and way constraints + weg->reset_way_constraints(); uint32 max_speed = weg->hat_gehweg() ? 50 : weg->get_besch()->get_topspeed(); if(gr->get_typ()==grund_t::tunnelboden) { tunnel_t *t = gr->find(1); if(t) { max_speed = t->get_besch()->get_topspeed(); + weg->add_way_constraints(t->get_besch()->get_way_constraints_permissive(), t->get_besch()->get_way_constraints_prohibitive()); } } if(gr->get_typ()==grund_t::brueckenboden) { bruecke_t *b = gr->find(1); if(b) { max_speed = b->get_besch()->get_topspeed(); + weg->add_way_constraints(b->get_besch()->get_way_constraints_permissive(), b->get_besch()->get_way_constraints_prohibitive()); } } weg->set_max_speed(max_speed); @@ -171,10 +174,11 @@ wayobj_t::laden_abschliessen() set_dir(dir); } + const waytype_t wt = (besch->get_wtyp()==tram_wt) ? track_wt : besch->get_wtyp(); + weg_t *weg = welt->lookup(get_pos())->get_weg(wt); + // electrify a way if we are a catenary - if(besch->get_own_wtyp()==overheadlines_wt) { - const waytype_t wt = (besch->get_wtyp()==tram_wt) ? track_wt : besch->get_wtyp(); - weg_t *weg = welt->lookup(get_pos())->get_weg(wt); + if(besch->get_own_wtyp()==overheadlines_wt) { if(weg) { // Weg wieder freigeben, wenn das Signal nicht mehr da ist. weg->set_electrify(true); @@ -187,6 +191,9 @@ wayobj_t::laden_abschliessen() } } + //Add the way constraints together. + weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); + if(get_besitzer()) { spieler_t::add_maintenance(get_besitzer(), besch->get_wartung()); } diff --git a/gui/banner.cc b/gui/banner.cc index afc90ba4fe4..ec7c2da9a88 100644 --- a/gui/banner.cc +++ b/gui/banner.cc @@ -54,19 +54,19 @@ void banner_t::zeichnen(koord /*pos*/, koord) int heading = (s == 0 ? 7 : COL_BLACK); int color = (s == 0 ? COL_WHITE : COL_BLACK); - display_proportional(xoff + s + 24+30, yoff + s + 10, "This is a beta version of Simutrans:", ALIGN_LEFT, heading, true); + display_proportional(xoff + s + 24+30, yoff + s + 10, "This is an experimental version of Simutrans:", ALIGN_LEFT, heading, true); display_proportional(xoff + s + 48+30, yoff + s + 22, "Version " VERSION_NUMBER " " VERSION_DATE, ALIGN_LEFT, color, true); - display_proportional(xoff + s + 24+30, yoff + s + 40, "This version is developed by", ALIGN_LEFT, heading, true); - display_proportional(xoff + s + 48+30, yoff + s + 56, "the simutrans team, based on", ALIGN_LEFT, color, true); - display_proportional(xoff + s + 48+30, yoff + s + 70, "Simutrans 0.84.21.2 by", ALIGN_LEFT, color, true); - display_proportional(xoff + s + 48+30, yoff + s + 82, "Hansjörg Malthaner et al.", ALIGN_LEFT, color, true); - display_proportional(xoff + s + 48+30, yoff + s + 94, "under Artistic Licence.", ALIGN_LEFT, color, true); - display_proportional(xoff + s + 24+30, yoff + s + 112, "Please send ideas and questions to:", ALIGN_LEFT, heading, true); - display_proportional(xoff + s + 48+30, yoff + s + 128, "Markus Pristovsek", ALIGN_LEFT, color, true); - display_proportional(xoff + s + 48+30, yoff + s + 140, "", ALIGN_LEFT, color, true); - display_proportional(xoff + s + 24+30, yoff + s + 158, "or visit the Simutrans pages on the web:", ALIGN_LEFT, heading, true); + display_proportional(xoff + s + 24+30, yoff + s + 40, "This experimental version", ALIGN_LEFT, heading, true); + display_proportional(xoff + s + 48+30, yoff + s + 56, "is modified by James E. Petts", ALIGN_LEFT, color, true); + display_proportional(xoff + s + 48+30, yoff + s + 70, "from Simutrans, 1997-2005", ALIGN_LEFT, color, true); + display_proportional(xoff + s + 48+30, yoff + s + 82, "(c) Hj. Malthaner; and", ALIGN_LEFT, color, true); + display_proportional(xoff + s + 48+30, yoff + s + 94, "2005-2009 maintained by", ALIGN_LEFT, color, true); + display_proportional(xoff + s + 24+30, yoff + s + 112, "Markus Pristovsek and the Simutrans team,", ALIGN_LEFT, heading, true); + display_proportional(xoff + s + 48+30, yoff + s + 128, "released under the Artistic Licence.", ALIGN_LEFT, color, true); + display_proportional(xoff + s + 48+30, yoff + s + 140, "For more information, please", ALIGN_LEFT, color, true); + display_proportional(xoff + s + 24+30, yoff + s + 158, "visit the Simutrans website or forum", ALIGN_LEFT, heading, true); display_proportional(xoff + s + 48+30, yoff + s + 174, "http://www.simutrans.com", ALIGN_LEFT, color, true); - display_proportional(xoff + s + 48+30, yoff + s + 186, "http://simutrans.sourceforge.net", ALIGN_LEFT, color, true); + display_proportional(xoff + s + 48+30, yoff + s + 186, "http://forum.simutrans.com", ALIGN_LEFT, color, true); } // now the scrolling diff --git a/gui/convoi_detail_t.cc b/gui/convoi_detail_t.cc index 869488e7976..ff60568df4b 100644 --- a/gui/convoi_detail_t.cc +++ b/gui/convoi_detail_t.cc @@ -206,6 +206,32 @@ void gui_vehicleinfo_t::zeichnen(koord offset) extra_y += LINESPACE; } + //Catering + if(v->get_besch()->get_catering_level() > 0) + { + if(v->get_besch()->get_ware()->get_catg_index() == 1) + { + //Catering vehicles that carry mail are treated as TPOs. + sprintf(buf , translator::translate("This is a travelling post office\n")); + display_proportional_clip( pos.x+w+offset.x, pos.y+offset.y+total_height+extra_y, buf, ALIGN_LEFT, COL_BLACK, true ); + extra_y += LINESPACE; + } + else + { + sprintf(buf, translator::translate("Catering level: %i\n"), v->get_besch()->get_catering_level()); + display_proportional_clip( pos.x+w+offset.x, pos.y+offset.y+total_height+extra_y, buf, ALIGN_LEFT, COL_BLACK, true ); + extra_y += LINESPACE; + } + } + + //Tilting + if(v->get_besch()->get_tilting()) + { + sprintf(buf, translator::translate("This is a tilting vehicle\n")); + display_proportional_clip( pos.x+w+offset.x, pos.y+offset.y+total_height+extra_y, buf, ALIGN_LEFT, COL_BLACK, true ); + extra_y += LINESPACE; + } + // friction sprintf( buf, "%s %i", translator::translate("Friction:"), v->get_frictionfactor() ); display_proportional_clip( pos.x+w+offset.x, pos.y+offset.y+total_height+extra_y, buf, ALIGN_LEFT, MONEY_PLUS, true ); @@ -217,7 +243,7 @@ void gui_vehicleinfo_t::zeichnen(koord offset) int len = 5+display_proportional_clip( pos.x+w+offset.x, pos.y+offset.y+total_height+extra_y, translator::translate("Max income:"), ALIGN_LEFT, COL_BLACK, true ); const sint32 grundwert128 = v->get_fracht_typ()->get_preis()<<7; const sint32 grundwert_bonus = v->get_fracht_typ()->get_preis()*(1000l+speed_base*v->get_fracht_typ()->get_speed_bonus()); - const sint32 price = (v->get_fracht_max()*(grundwert128>grundwert_bonus ? grundwert128 : grundwert_bonus))/30 - v->get_betriebskosten(); + const sint32 price = (v->get_fracht_max()*(grundwert128>grundwert_bonus ? grundwert128 : grundwert_bonus))/30 - v->get_betriebskosten(cnv->get_welt()); money_to_string( tmp, price/100.0 ); display_proportional_clip( pos.x+w+offset.x+len, pos.y+offset.y+total_height+extra_y, tmp, ALIGN_LEFT, price>0?MONEY_PLUS:MONEY_MINUS, true ); extra_y += LINESPACE; @@ -241,6 +267,41 @@ void gui_vehicleinfo_t::zeichnen(koord offset) } extra_y += returns*LINESPACE; } + + // Permissive way constraints + // (If vehicle has, way must have) + // @author: jamespetts + for(uint8 i = 0; i < 8; i++) + { + if(v->get_besch()->permissive_way_constraint_set(i)) + { + char tmpbuf1[13]; + sprintf(tmpbuf1, "\nMUST USE: "); + char tmpbuf[14]; + sprintf(tmpbuf, "Permissive %i", i); + sprintf(buf, "%s %s", translator::translate(tmpbuf1), translator::translate(tmpbuf)); + display_proportional_clip( pos.x+w+offset.x, pos.y+offset.y+total_height+extra_y, buf, ALIGN_LEFT, COL_BLACK, true ); + extra_y += LINESPACE; + } + } + + // Prohibitive way constraints + // (If way has, vehicle must have) + // @author: jamespetts + for(uint8 i = 0; i < 8; i++) + { + if(v->get_besch()->prohibitive_way_constraint_set(i)) + { + char tmpbuf1[13]; + sprintf(tmpbuf1, "\nMAY USE: "); + char tmpbuf[14]; + sprintf(tmpbuf, "Prohibitive %i", i); + sprintf(buf, "%s %s", translator::translate(tmpbuf1), translator::translate(tmpbuf)); + display_proportional_clip( pos.x+w+offset.x, pos.y+offset.y+total_height+extra_y, buf, ALIGN_LEFT, COL_BLACK, true ); + extra_y += LINESPACE; + } + } + //skip at least five lines total_height += max(extra_y,4*LINESPACE)+5; } diff --git a/gui/depot_frame.cc b/gui/depot_frame.cc index 3cf4e74bdaa..8f38d82a099 100644 --- a/gui/depot_frame.cc +++ b/gui/depot_frame.cc @@ -349,7 +349,7 @@ void depot_frame_t::layout(koord *gr) /* * Structure of [VINFO] is one multiline text. */ - int VINFO_HEIGHT = 86; + int VINFO_HEIGHT = 185; /* * Total width is the max from [CONVOI] and [ACTIONS] width. @@ -667,7 +667,7 @@ void depot_frame_t::build_vehicle_lists() if(veh_action == va_insert) { append = !(!convoi_t::pruefe_nachfolger(info, veh) || (veh && !convoi_t::pruefe_vorgaenger(info, veh))); } else if(veh_action == va_append) { - append = convoi_t::pruefe_vorgaenger(veh, info); + append = convoi_t::pruefe_vorgaenger(veh, info); //"Pruefe vorgaenger" = check predecessors (Google) } } if(append) { @@ -1346,10 +1346,11 @@ void depot_frame_t::draw_vehicle_info_text(koord pos) display_proportional( pos.x + 4, pos.y + tabs.get_pos().y + tabs.get_groesse().y + 16 + 4, c, ALIGN_LEFT, COL_BLACK, true ); if(veh_type) { + int k = 0; // lok oder waggon ? - if(veh_type->get_leistung() > 0) { + if(veh_type->get_leistung() > 0) { //"Leistung" = performance (Google) //lok - const int zuladung = veh_type->get_zuladung(); + const int zuladung = veh_type->get_zuladung(); //"Zuladung" = payload (Google) char name[128]; @@ -1362,29 +1363,31 @@ void depot_frame_t::draw_vehicle_info_text(koord pos) translator::translate("LOCO_INFO"), name, veh_type->get_preis()/100, - veh_type->get_betriebskosten()/100.0, + veh_type->get_betriebskosten(get_welt())/100.0, veh_type->get_leistung(), veh_type->get_geschw(), veh_type->get_gewicht() ); + //"Payload" (Google) if(zuladung>0) { - sprintf(buf + n, + n += sprintf(buf + n, translator::translate("LOCO_CAP"), zuladung, translator::translate(veh_type->get_ware()->get_mass()), veh_type->get_ware()->get_catg() == 0 ? translator::translate(veh_type->get_ware()->get_name()) : translator::translate(veh_type->get_ware()->get_catg_name()) ); + k = n; } } else { // waggon - sprintf(buf, + int n = sprintf(buf, translator::translate("WAGGON_INFO"), translator::translate(veh_type->get_name()), veh_type->get_preis()/100, - veh_type->get_betriebskosten()/100.0, + veh_type->get_betriebskosten(get_welt())/100.0, veh_type->get_zuladung(), translator::translate(veh_type->get_ware()->get_mass()), veh_type->get_ware()->get_catg() == 0 ? @@ -1393,32 +1396,84 @@ void depot_frame_t::draw_vehicle_info_text(koord pos) veh_type->get_gewicht(), veh_type->get_geschw() ); + + k = n; + } + + if(veh_type->get_catering_level() > 0) + { + if(veh_type->get_ware()->get_catg_index() == 1) + { + //Catering vehicles that carry mail are treated as TPOs. + k += sprintf(buf + k, translator::translate("This is a travelling post office")); + } + else + { + k += sprintf(buf + k, translator::translate("Catering level: %i"), veh_type->get_catering_level()); + } } + + // Permissive way constraints + // (If vehicle has, way must have) + // @author: jamespetts + for(uint8 i = 0; i < 8; i++) + { + if(veh_type->permissive_way_constraint_set(i)) + { + k += sprintf(buf + k, translator::translate("\nMUST USE: ")); + char tmpbuf[30]; + sprintf(tmpbuf, "Permissive %i", i); + k += sprintf(buf + k, translator::translate(tmpbuf)); + } + } + display_multiline_text( pos.x + 4, pos.y + tabs.get_pos().y + tabs.get_groesse().y + 31 + LINESPACE*1 + 4, buf, COL_BLACK); // column 2 - int n = sprintf(buf, "%s %s %04d\n", - translator::translate("Intro. date:"), + + int j = sprintf(buf, "%s %s %04d\n", + translator::translate("Intro. date:"), translator::get_month_name(veh_type->get_intro_year_month()%12), veh_type->get_intro_year_month()/12 ); if(veh_type->get_retire_year_month() !=DEFAULT_RETIRE_DATE*12) { - n += sprintf(buf+n, "%s %s %04d\n", + j += sprintf(buf + j, "%s %s %04d\n", translator::translate("Retire. date:"), translator::get_month_name(veh_type->get_retire_year_month()%12), veh_type->get_retire_year_month()/12 ); } if(veh_type->get_leistung() > 0 && veh_type->get_gear()!=64) { - n+= sprintf(buf+n, "%s %0.2f : 1\n", translator::translate("Gear:"), veh_type->get_gear()/64.0); + j+= sprintf(buf + j, "%s %0.2f : 1\n", translator::translate("Gear: "), veh_type->get_gear()/64.0); } - if(veh_type->get_copyright()!=NULL && veh_type->get_copyright()[0]!=0) { - n += sprintf(buf + n, translator::translate("Constructed by %s"), veh_type->get_copyright()); + if(veh_type->get_copyright()!=NULL && veh_type->get_copyright()[0]!=0) + { + j += sprintf(buf + j, translator::translate("Constructed by %s\n"), veh_type->get_copyright()); + } + if(veh_type->get_tilting()) + { + j += sprintf(buf + j, translator::translate("This is a tilting vehicle\n")); } - if(value != -1) { - sprintf(buf + strlen(buf), "%s %d Cr", translator::translate("Restwert:"), value); + if(value != -1) + { + sprintf(buf + strlen(buf), "%s %d Cr", translator::translate("Restwert: "), value); //"Restwert" = residual (Google) + } + + // Prohibitibve way constraints + // (If way has, vehicle must have) + // @author: jamespetts + j += sprintf(buf + j, "\n"); + for(uint8 i = 0; i < 8; i++) + { + if(veh_type->prohibitive_way_constraint_set(i)) + { + j += sprintf(buf + j, translator::translate("\nMAY USE: ")); + char tmpbuf[30]; + sprintf(tmpbuf, "Prohibitive %i", i); + j += sprintf(buf + j, translator::translate(tmpbuf)); + } } display_multiline_text( pos.x + 200, pos.y + tabs.get_pos().y + tabs.get_groesse().y + 31 + LINESPACE*2 + 4, buf, COL_BLACK); diff --git a/gui/stadt_info.cc b/gui/stadt_info.cc index e467b36d17c..3ceba23d9f8 100644 --- a/gui/stadt_info.cc +++ b/gui/stadt_info.cc @@ -24,15 +24,17 @@ const char *hist_type[MAX_CITY_HISTORY] = { "citicens", "Growth", "Buildings", "Verkehrsteilnehmer", "Transported", "Passagiere", "sended", "Post", - "Arrived", "Goods", "Electricity" + "Arrived", "Goods", "Congestion" }; +// Note: "Congestion" was "Electricity", but this value was unused. +//@author: jamespetts const int hist_type_color[MAX_CITY_HISTORY] = { COL_WHITE, COL_DARK_GREEN, COL_LIGHT_PURPLE, COL_POWERLINES, COL_LIGHT_BLUE, COL_BLUE, COL_LIGHT_YELLOW, COL_YELLOW, - COL_LIGHT_BROWN, COL_BROWN + COL_LIGHT_BROWN, COL_BROWN, COL_DARK_TURQOISE }; @@ -80,7 +82,8 @@ stadt_info_t::stadt_info_t(stadt_t* stadt_) : add_komponente(&year_month_tabs); // add filter buttons - for( int hist=0; histstadtinfo_options & (1<get_homeless() ); + b += sprintf(b, "%s: %d %%. \n", + translator::translate("Car ownership"), + c->get_private_car_ownership(c->get_welt()->get_timeline_year_month()) + ); + display_multiline_text(pos.x+8, pos.y+48, buf, COL_BLACK); display_array_wh(pos.x + 140, pos.y + 24, 128, 128, c->get_pax_ziele_alt()->to_array()); diff --git a/ifc/fahrer.h b/ifc/fahrer.h index a29ed1a8bf9..9022d96016d 100644 --- a/ifc/fahrer.h +++ b/ifc/fahrer.h @@ -12,6 +12,8 @@ class grund_t; /** * Interface für Verbindung von Fahrzeugen mit der Route. + * + * Interface for connection of vehicles with the route. (Google) * * @author Hj. Malthaner, 15.01.00 */ @@ -20,6 +22,7 @@ class fahrer_t public: virtual ~fahrer_t() {} + //Is passable (Babelfish) virtual bool ist_befahrbar(const grund_t* ) const = 0; /** diff --git a/makeobj/makeobj.cc b/makeobj/makeobj.cc index 03f97d1fae8..e1b46e740a6 100644 --- a/makeobj/makeobj.cc +++ b/makeobj/makeobj.cc @@ -33,8 +33,10 @@ int main(int argc, char* argv[]) argv++, argc--; } else { puts( - "\nMakeobj version " MAKEOBJ_VERSION " for simutrans " VERSION_NUMBER " and higher\n" - "(c) 2002-2006 V. Meyer , Hj. Malthaner, M. Pristovsek (markus@pristovsek.de)\n" + "\nMakeobj-Experimental, based on Makeobj version " MAKEOBJ_VERSION " for Simutrans-Experimental " VERSION_NUMBER " and higher\n" + "Experimental version by James E. Petts, derived from Makeobj, \n (c) 2002-2006 V. Meyer , Hj. Malthaner and \n" + "M. Pristovsek (markus@pristovsek.de). Files compiled with Makeobj-Experimental work with\n" + "Simutrans-Experimental and standard Simutrans.\n" ); } diff --git a/player/ai_goods.cc b/player/ai_goods.cc index 3881812d5e7..eece7eee8e3 100755 --- a/player/ai_goods.cc +++ b/player/ai_goods.cc @@ -835,7 +835,7 @@ DBG_MESSAGE("ai_goods_t::do_ki()","No roadway possible."); // only uneven number of cars bigger than 3 makes sense ... count_rail = max( 3, count_rail ); income_rail = (freight_price*best_rail_speed)/(2*dist+count_rail); - cost_rail = rail_weg->get_wartung() + (((count_rail+1)/2)*300)/dist + ((count_rail*rail_vehicle->get_betriebskosten()+rail_engine->get_betriebskosten())*best_rail_speed)/(2*dist+count_rail); + cost_rail = rail_weg->get_wartung() + (((count_rail+1)/2)*300)/dist + ((count_rail*rail_vehicle->get_betriebskosten(welt)+rail_engine->get_betriebskosten(welt))*best_rail_speed)/(2*dist+count_rail); DBG_MESSAGE("ai_goods_t::do_ki()","Netto credits per day for rail transport %.2f (income %.2f)",cost_rail/100.0, income_rail/100.0 ); cost_rail -= income_rail; } @@ -846,7 +846,7 @@ DBG_MESSAGE("ai_goods_t::do_ki()","No roadway possible."); // calculated here, since the above number was based on production count_road = CLIP( (dist*15)/best_road_speed, 2, count_road ); int freight_price = (freight->get_preis()*road_vehicle->get_zuladung()*count_road)/24*((8000+(best_road_speed-80)*freight->get_speed_bonus())/1000); - cost_road = road_weg->get_wartung() + 300/dist + (count_road*road_vehicle->get_betriebskosten()*best_road_speed)/(2*dist+5); + cost_road = road_weg->get_wartung() + 300/dist + (count_road*road_vehicle->get_betriebskosten(welt)*best_road_speed)/(2*dist+5); income_road = (freight_price*best_road_speed)/(2*dist+5); DBG_MESSAGE("ai_goods_t::do_ki()","Netto credits per day and km for road transport %.2f (income %.2f)",cost_road/100.0, income_road/100.0 ); cost_road -= income_road; @@ -940,7 +940,7 @@ DBG_MESSAGE("ai_goods_t::do_ki()","No roadway possible."); // for engine: gues number of cars long power_needed=(long)(((best_rail_speed*best_rail_speed)/2500.0+1.0)*(100.0+count_rail*(rail_vehicle->get_gewicht()+rail_vehicle->get_zuladung()*freight->get_weight_per_unit()*0.001))); const vehikel_besch_t *v=vehikelbauer_t::vehikel_search( track_wt, month_now, power_needed, best_rail_speed, NULL, false, false ); - if(v->get_betriebskosten()get_betriebskosten()) { + if(v->get_betriebskosten(welt)get_betriebskosten(welt)) { rail_engine = v; } } diff --git a/player/simplay.cc b/player/simplay.cc index e92d52a8001..870dfdb9415 100644 --- a/player/simplay.cc +++ b/player/simplay.cc @@ -423,7 +423,8 @@ void spieler_t::buche(const sint64 betrag, const koord pos, enum player_cost typ add_message(pos, betrag); } - if(!(labs((sint32)betrag)<=10000)) { + if(!(labs((sint32)betrag)<=10000) && !(welt->is_fast_forward())) { + // play sound only for more than 100 money units AND in normal speed struct sound_info info; info.index = SFX_CASH; @@ -607,7 +608,7 @@ void spieler_t::ai_bankrupt() automat = false; char buf[256]; sprintf(buf, translator::translate("%s\nwas liquidated."), get_name() ); - welt->get_message()->add_message( buf, koord::invalid, message_t::ai, player_nr ); + welt->get_message()->add_message( buf, koord::invalid, message_t::ai, PLAYER_FLAG|player_nr ); } diff --git a/simcity.cc b/simcity.cc index ec6cccdfce7..471ee84dd61 100644 --- a/simcity.cc +++ b/simcity.cc @@ -21,7 +21,6 @@ #include "player/simplay.h" #include "simplan.h" #include "simimg.h" -#include "vehicle/simverkehr.h" #include "simtools.h" #include "simhalt.h" #include "simfab.h" @@ -53,9 +52,106 @@ #include "utils/cbuffer_t.h" #include "utils/simstring.h" +#include "tpl/ptrhashtable_tpl.h" + karte_t* stadt_t::welt = NULL; // one is enough ... +sint16 number_of_cars; + +// Private car ownership information. +// @author: jamespetts +// (But much of this code is adapted from the speed bonus code, +// written by Prissi). + +class car_ownership_record_t { +public: + sint32 year; + sint16 ownership_percent; + car_ownership_record_t( sint32 y = 0, sint16 ownership = 0 ) { + year = y*12; + ownership_percent = ownership; + }; +}; + +static sint16 default_car_ownership_percent = 25; + +static vector_tpl car_ownership[1]; + +void stadt_t::privatecar_init(cstring_t objfilename) +{ + tabfile_t ownership_file; + // first take user data, then user global data + if (!ownership_file.open(objfilename+"config/privatecar.tab")) + { + dbg->message("stadt_t::privatecar_init()", "Error opening config/privatecar.tab.\nWill use default value." ); + return; + } + + tabfileobj_t contents; + ownership_file.read(contents); + + /* init the values from line with the form year, speed, year, speed + * must be increasing order! + */ + int *tracks = contents.get_ints("car_ownership"); + if((tracks[0]&1)==1) + { + dbg->message("stadt_t::privatecar_init()", "Ill formed line in config/privatecar.tab.\nWill use default value. Format is year,ownership percentage[ year,ownership percentage]!" ); + car_ownership->clear(); + return; + } + car_ownership[0].resize( tracks[0]/2 ); + for( int i=1; iget_count()) + { + uint i=0; + while( iget_count() && monthyear>=car_ownership[0][i].year ) { + i++; + } + if( i==car_ownership->get_count() ) + { + // maxspeed already? + return car_ownership[0][i-1].ownership_percent; + } + else if(i==0) + { + // minspeed below + return car_ownership[0][0].ownership_percent; + } + else + { + // interpolate linear + const sint32 delta_ownership_percent = car_ownership[0][i].ownership_percent - car_ownership[0][i-1].ownership_percent; + const sint32 delta_years = car_ownership[0][i].year - car_ownership[0][i-1].year; + return ( (delta_ownership_percent*(monthyear-car_ownership[0][i-1].year)) / delta_years ) + car_ownership[0][i-1].ownership_percent; + } + } + else + { + return default_car_ownership_percent; + } +} + + /********************************* From here on cityrules stuff *****************************************/ @@ -161,6 +257,7 @@ static const uint8 rotate_rules_270[] = { 48, 41, 34, 27, 20, 13, 6 }; + /** * Symbols in rules: * S = darf keine Strasse sein @@ -717,6 +814,9 @@ stadt_t::~stadt_t() // close info win destroy_win((long)this); + // Empty the list of city cars + current_cars.clear(); + // olny if there is still a world left to delete from if(welt->get_groesse_x()>1) { @@ -829,6 +929,9 @@ next_name:; } city_history_year[0][HIST_CITICENS] = get_einwohner(); city_history_month[0][HIST_CITICENS] = get_einwohner(); + + outgoing_private_cars = 0; + incoming_private_cars = 0; } @@ -848,6 +951,12 @@ stadt_t::stadt_t(karte_t* wl, loadsave_t* file) : name = NULL; stadtinfo_options = 3; + // These things are not yet saved as part of the city's history, + // as doing so would require reversioning saved games. + + incoming_private_cars = 0; + outgoing_private_cars = 0; + rdwr(file); verbinde_fabriken(); @@ -965,7 +1074,7 @@ void stadt_t::rdwr(loadsave_t* file) DBG_MESSAGE("stadt_t::rdwr()", "borders (%i,%i) -> (%i,%i)", lo.x, lo.y, ur.x, ur.y); // borders will be corrected later one anyways for newer versions - pruefe_grenzen( pos-koord(33,33) ); + pruefe_grenzen( pos-koord(33,33) ); //"Check limits" (Google) pruefe_grenzen( pos+koord(33,33) ); } } @@ -1128,6 +1237,7 @@ void stadt_t::step(long delta_t) while(stadt_t::step_bau_interval < next_bau_step) { calc_growth(); + outgoing_private_cars = 0; step_bau(); next_bau_step -= stadt_t::step_bau_interval; } @@ -1171,6 +1281,15 @@ void stadt_t::roll_history() city_history_month[0][HIST_BUILDING] = buildings.get_count(); city_history_month[0][HIST_GOODS_NEEDED] = 0; + // Congestion figures for the year should be an average of the last 12 months. + uint16 total_congestion = 0; + for(int i = 0; i < 12; i ++) + { + total_congestion += city_history_month[i][HIST_CONGESTION]; + } + + city_history_year[0][HIST_CONGESTION] = total_congestion / 12; + //need to roll year too? if (welt->get_last_month() == 0) { for (int i = MAX_CITY_HISTORY_YEARS - 1; i > 0; i--) { @@ -1185,12 +1304,13 @@ void stadt_t::roll_history() city_history_year[0][HIST_CITICENS] = get_einwohner(); city_history_year[0][HIST_BUILDING] = buildings.get_count(); city_history_year[0][HIST_GOODS_NEEDED] = 0; + } } -void stadt_t::neuer_monat() +void stadt_t::neuer_monat() //"New month" (Google) { const int gr_x = welt->get_groesse_x(); const int gr_y = welt->get_groesse_y(); @@ -1206,22 +1326,128 @@ void stadt_t::neuer_monat() roll_history(); + // Calculate the level of congestion. + // Used in determining growth and passenger preferences. + // From observations in game: anything < 2, not very congested. + // Anything > 4, very congested. + // @author: jamespetts + + float city_size = (float)(ur.x - lo.x) * (ur.y - lo.y); + float cars_per_tile = (float)city_history_month[1][HIST_CITYCARS] / city_size; + float population_density = (float)city_history_month[1][HIST_CITICENS] / city_size; + if(cars_per_tile <= 0.4) + { + city_history_month[0][HIST_CONGESTION] = 0; + } + else + { + float proportion = (((cars_per_tile - 0.4) / 4.5) * population_density) / welt->get_einstellungen()->get_congestion_density_factor(); + city_history_month[0][HIST_CONGESTION] = proportion * 100; + } + if (!stadtauto_t::list_empty()) { // spawn eventuall citycars // the more transported, the less are spawned // the larger the city, the more spawned ... - double pfactor = (double)(city_history_month[1][HIST_PAS_TRANSPORTED]) / (double)(city_history_month[1][HIST_PAS_GENERATED]+1); - double mfactor = (double)(city_history_month[1][HIST_MAIL_TRANSPORTED]) / (double)(city_history_month[1][HIST_MAIL_GENERATED]+1); - double gfactor = (double)(city_history_month[1][HIST_GOODS_RECIEVED]) / (double)(city_history_month[1][HIST_GOODS_NEEDED]+1); + + // Citycars now used as an accurate measure of actual traffic level, not just the number of cars generated + // graphically on the map. Thus, the "traffic level" setting no longer has an effect on the city cars graph, + // but still affects the number of actual cars generated. + + // Divide by a factor because number of cars drawn on screen should be a fraction of actual traffic, or else + // everywhere will become completely clogged with traffic. Linear rather than logorithmic scaling so + // that the player can have a better idea visually of the amount of traffic. - double factor = pfactor > mfactor ? (gfactor > pfactor ? gfactor : pfactor ) : mfactor; - factor = (1.0-factor)*city_history_month[1][HIST_CITICENS]; - factor = log10( factor ); - uint16 number_of_cars = simrand( (uint16)(factor * (double)welt->get_einstellungen()->get_verkehr_level()) ) / 16; +#ifdef DESTINATION_CITYCARS + // Subtract incoming trips and cars already generated to prevent double counting. + sint16 factor = city_history_month[1][HIST_CITYCARS] - incoming_private_cars - current_cars.count(); + + //Manual assignment of traffic level modifiers, since I could not find a suitable mathematical formula. + float traffic_level; + switch(welt->get_einstellungen()->get_verkehr_level()) + { + case 0: + traffic_level = 0; + break; + + case 1: + traffic_level = 0.001; + break; + + case 2: + traffic_level = 0.005; + break; + + case 3: + traffic_level = 0.01; + break; + + case 4: + traffic_level = 0.02; + break; - city_history_month[0][HIST_CITYCARS] = number_of_cars; - city_history_year[0][HIST_CITYCARS] += number_of_cars; + case 5: + traffic_level = 0.025; + break; + + case 6: + traffic_level = 0.05; + break; + + case 7: + traffic_level = 0.075; + break; + + case 8: + traffic_level = 0.1; + break; + + case 9: + traffic_level = 0.15; + break; + + case 10: + traffic_level = 0.2; + break; + + case 11: + traffic_level = 0.25; + break; + + case 12: + traffic_level = 0.33; + break; + + case 13: + traffic_level = 0.5; + break; + + case 14: + traffic_level = 0.66; + break; + + case 15: + traffic_level = 0.75; + break; + + case 16: + default: + traffic_level = 1; + }; + + number_of_cars = factor * traffic_level; + incoming_private_cars = 0; +#else + //uint16 number_of_cars = ((city_history_month[1][HIST_CITYCARS] * welt->get_einstellungen()->get_verkehr_level()) / 16) / 64; +#endif + + while(current_cars.count() > number_of_cars) + { + //Make sure that there are not too many cars on the roads. + stadtauto_t* car = current_cars.remove_first(); + car->kill(); + } koord k; koord pos = get_zufallspunkt(); @@ -1232,10 +1458,13 @@ void stadt_t::neuer_monat() } grund_t* gr = welt->lookup_kartenboden(k); - if (gr != NULL && gr->get_weg(road_wt) && ribi_t::is_twoway(gr->get_weg_ribi_unmasked(road_wt)) && gr->find() == NULL) { - stadtauto_t* vt = new stadtauto_t(welt, gr->get_pos(), koord::invalid); + if (gr != NULL && gr->get_weg(road_wt) && ribi_t::is_twoway(gr->get_weg_ribi_unmasked(road_wt)) && gr->find() == NULL) + { + slist_tpl *car_list = ¤t_cars; + stadtauto_t* vt = new stadtauto_t(welt, gr->get_pos(), koord::invalid, car_list); gr->obj_add(vt); welt->sync_add(vt); + current_cars.append(vt); number_of_cars--; } } @@ -1243,6 +1472,11 @@ void stadt_t::neuer_monat() } } +sint16 stadt_t::get_outstanding_cars() +{ + return number_of_cars - current_cars.count(); +} + void stadt_t::calc_growth() { @@ -1266,8 +1500,13 @@ void stadt_t::calc_growth() /* four parts contribute to town growth: * passenger transport 40%, mail 20%, goods (30%), and electricity (10%) + * + * Congestion detracts from growth, but towns can now grow as a result of private car + * transport as well as public transport: if private car ownership is high enough. + * (@author: jamespetts) */ - sint32 pas = (city_history_month[0][HIST_PAS_TRANSPORTED] * (40<<6)) / (city_history_month[0][HIST_PAS_GENERATED] + 1); + //sint32 pas = (city_history_month[0][HIST_PAS_TRANSPORTED] * (40<<6)) / (city_history_month[0][HIST_PAS_GENERATED] + 1); + sint32 pas = ((city_history_month[0][HIST_PAS_TRANSPORTED] + (city_history_month[0][HIST_CITYCARS] - outgoing_private_cars)) * (40<<6)) / (city_history_month[0][HIST_PAS_GENERATED] + 1); sint32 mail = (city_history_month[0][HIST_MAIL_TRANSPORTED] * (20<<6)) / (city_history_month[0][HIST_MAIL_GENERATED] + 1); sint32 electricity = 0; sint32 goods = city_history_month[0][HIST_GOODS_NEEDED]==0 ? 0 : (city_history_month[0][HIST_GOODS_RECIEVED] * (20<<6)) / (city_history_month[0][HIST_GOODS_NEEDED]); @@ -1282,10 +1521,21 @@ void stadt_t::calc_growth() } // now give the growth for this step - wachstum += (pas+mail+electricity+goods) / weight_factor; + sint32 growth_factor = (pas+mail+electricity+goods) / weight_factor; //"wachstum" = growth (Google) + + //Congestion adversely impacts on growth. At 100% congestion, there will be no growth. + float congestion_factor; + if(city_history_month[0][HIST_CONGESTION] > 0) + { + congestion_factor = (city_history_month[0][HIST_CONGESTION] / 100.0); + growth_factor -= (congestion_factor * growth_factor); + } + + wachstum += growth_factor; } + // does constructions ... void stadt_t::step_bau() { @@ -1316,10 +1566,25 @@ void stadt_t::step_bau() */ void stadt_t::step_passagiere() { -// DBG_MESSAGE("stadt_t::step_passagiere()", "%s step_passagiere called (%d,%d - %d,%d)\n", name, li, ob, re, un); -// long t0 = get_current_time_millis(); + //@author: jamespetts + // Passenger routing and generation metrics. + static uint16 local_passengers_min_distance = welt->get_einstellungen()->get_local_passengers_min_distance(); + static uint16 local_passengers_max_distance = welt->get_einstellungen()->get_local_passengers_max_distance(); + static uint16 midrange_passengers_min_distance = welt->get_einstellungen()->get_midrange_passengers_min_distance(); + static uint16 midrange_passengers_max_distance = welt->get_einstellungen()->get_midrange_passengers_max_distance(); + static uint16 longdistance_passengers_min_distance = welt->get_einstellungen()->get_longdistance_passengers_min_distance(); + static uint16 longdistance_passengers_max_distance = welt->get_einstellungen()->get_longdistance_passengers_max_distance(); + + static uint8 passenger_packet_size = welt->get_einstellungen()->get_passenger_routing_packet_size(); + static uint8 max_destinations = (welt->get_einstellungen()->get_max_alternative_destinations()) + 1; + static uint8 passenger_routing_local_chance = welt->get_einstellungen()->get_passenger_routing_local_chance(); + static uint8 passenger_routing_midrange_chance = welt->get_einstellungen()->get_passenger_routing_midrange_chance(); + + // DBG_MESSAGE("stadt_t::step_passagiere()", "%s step_passagiere called (%d,%d - %d,%d)\n", name, li, ob, re, un); + // long t0 = get_current_time_millis(); // post oder pax erzeugen ? + // "post or generate pax" const ware_besch_t* wtyp; if (simrand(400) < 300) { wtyp = warenbauer_t::passagiere; @@ -1355,12 +1620,16 @@ void stadt_t::step_passagiere() const halthandle_t* halt_list = plan->get_haltlist(); // suitable start search - halthandle_t start_halt = halthandle_t(); + fixed_list_tpl start_halts; for (uint h = 0; h < plan->get_haltlist_count(); h++) { halthandle_t halt = halt_list[h]; if (halt->is_enabled(wtyp) && halt->get_ware_summe(wtyp)<=halt->get_capacity(wtyp->get_index())) { - start_halt = halt; - break; + if(halt.is_bound() && !start_halts.add_to_tail_no_overwrite(&halt)) + { + // Stops looking for new halts if we have found too many to fit + // into the fixed size list. Number limited to keep the speed up. + break; + } } } @@ -1368,165 +1637,526 @@ void stadt_t::step_passagiere() city_history_year[0][history_type+1] += num_pax; city_history_month[0][history_type+1] += num_pax; - // only continue, if this is a good start halt - if (start_halt.is_bound()) { + // Check whether this batch of passengers has access to a private car each. + // Check run in batches to save computational effort. + bool has_private_car = (simrand(100) <= get_private_car_ownership(welt->get_timeline_year_month())); + + //Only continue if there are suitable start halts nearby, or the passengers have their own car. + if(start_halts.get_size() > 0 || has_private_car) + { + if(passenger_routing_local_chance < 1) + { + passenger_routing_local_chance = 33; + } + if(passenger_routing_midrange_chance < 1) + { + passenger_routing_midrange_chance = 33; + } + while(passenger_routing_midrange_chance + passenger_routing_local_chance > 99) + { + passenger_routing_midrange_chance = passenger_routing_midrange_chance / 2; + passenger_routing_local_chance = passenger_routing_local_chance / 2; + } + uint8 passenger_routing_longdistance_chance = 100 - (passenger_routing_local_chance + passenger_routing_midrange_chance); + //Add 1 because the simuconf.tab setting is for maximum *alternative* destinations, whereas we need maximum *actual* desintations + if(max_destinations > 16) max_destinations = 16; + if(passenger_packet_size < 1) passenger_packet_size = 7; + // Find passenger destination - for (int pax_routed = 0; pax_routed < num_pax; pax_routed += 7) { - // number of passengers that want to travel - // Hajo: for efficiency we try to route not every - // single pax, but packets. If possible, we do 7 passengers at a time - // the last packet might have less then 7 pax - int pax_left_to_do = min(7, num_pax - pax_routed); + for (int pax_routed = 0; pax_routed < num_pax; pax_routed += passenger_packet_size) { + + /* number of passengers that want to travel + * Hajo: for efficiency we try to route not every + * single pax, but packets. If possible, we do 7 passengers at a time + * the last packet might have less then 7 pax + * Number now not fixed at 7, but set in simuconf.tab (@author: jamespetts)*/ + + int pax_left_to_do = min(passenger_packet_size, num_pax - pax_routed); // Ziel für Passagier suchen + // "The aim for passenger search" pax_zieltyp will_return; - const koord ziel = finde_passagier_ziel(&will_return); -#ifdef DESTINATION_CITYCARS - //citycars with destination - if (pax_routed == 0) { - erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, ziel); + uint8 destination_count = simrand((max_destinations + 1)); + if(destination_count < 1) destination_count = 1; + + // Split passengers: 1/3rd are local only, + // 1/3rd are local or medium distance, + // and 1/3rd are of any distance. + // Note: a random town will be found if there are no towns within range. + uint8 passenger_routing_choice; + destination destinations[16]; + for(int destinations_assigned = 0; destinations_assigned < destination_count; destinations_assigned ++) + { + passenger_routing_choice = simrand(100); + + //if(pax_routed < (number_packets / 3)) + if(passenger_routing_choice <= passenger_routing_local_chance) + { + //Local + destinations[destinations_assigned] = finde_passagier_ziel(&will_return, local_passengers_min_distance, local_passengers_max_distance); + } + //else if(pax_routed < ((number_packets / 3) * 2)) + else if(passenger_routing_choice <= (passenger_routing_local_chance + passenger_routing_midrange_chance)) + { + //Medium + destinations[destinations_assigned] = finde_passagier_ziel(&will_return, midrange_passengers_min_distance, midrange_passengers_max_distance); + } + else + //else if(passenger_routing_choice >= (100 - passenger_routing_longdistance_chance)) + { + //Long distance + destinations[destinations_assigned] = finde_passagier_ziel(&will_return, longdistance_passengers_min_distance, longdistance_passengers_max_distance); //"Ziel" = "target" (Google) + } } -#endif - // Dario: Check if there's a stop near destination - const planquadrat_t* dest_plan = welt->lookup(ziel); - const halthandle_t* dest_list = dest_plan->get_haltlist(); + + int current_destination = 0; + bool route_good = false; bool can_walk_ziel = false; - // suitable end search - unsigned ziel_count = 0; - for (uint h = 0; h < dest_plan->get_haltlist_count(); h++) { - halthandle_t halt = dest_list[h]; - if (halt->is_enabled(wtyp)) { - ziel_count++; - if (halt == start_halt) { - can_walk_ziel = true; - break; // because we found at least one valid step ... - } - } - } + while(!route_good && !can_walk_ziel && current_destination < destination_count) + { - if (ziel_count == 0) { -// DBG_MESSAGE("stadt_t::step_passagiere()", "No stop near dest (%d, %d)", ziel.x, ziel.y); - // Thus, routing is not possible and we do not need to do a calculation. - // Mark ziel as destination without route and continue. - merke_passagier_ziel(ziel, COL_DARK_ORANGE); - start_halt->add_pax_no_route(pax_left_to_do); #ifdef DESTINATION_CITYCARS //citycars with destination - erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, ziel); + if(has_private_car) + { + if(start_halts.get_size() > 0) + { + halthandle_t start_halt = *start_halts.get_element(0); + if(start_halt.is_bound()) + { + erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, destinations[current_destination].location); + } + } + } #endif - continue; - } - - // check, if they can walk there? - if (can_walk_ziel) { - // so we have happy passengers - start_halt->add_pax_happy(pax_left_to_do); - merke_passagier_ziel(ziel, COL_YELLOW); - city_history_year[0][history_type] += pax_left_to_do; - city_history_month[0][history_type] += pax_left_to_do; - continue; - } + + // Dario: Check if there's a stop near destination + const planquadrat_t* dest_plan = welt->lookup(destinations[current_destination].location); + const halthandle_t* dest_list = dest_plan->get_haltlist(); + + halthandle_t start_halt; + + // suitable end search + unsigned ziel_count = 0; + for (uint h = 0; h < dest_plan->get_haltlist_count(); h++) { + halthandle_t halt = dest_list[h]; + if (halt->is_enabled(wtyp)) + { + ziel_count++; + for(int i = start_halts.get_size(); i >= 0; i--) + { + if(start_halts.get_size() > i && halt == *start_halts.get_element(i)) + { + can_walk_ziel = true; + start_halt = *start_halts.get_element(i); + } + } + break; // because we found at least one valid step ... + } + } - // ok, they are not in walking distance - ware_t pax(wtyp); - pax.set_zielpos(ziel); - pax.menge = (wtyp == warenbauer_t::passagiere ? pax_left_to_do : max(1, pax_left_to_do >> 2)); - - // now, finally search a route; this consumes most of the time - koord return_zwischenziel = koord::invalid; // for people going back ... - start_halt->suche_route(pax, will_return ? &return_zwischenziel : NULL); - - if (pax.get_ziel().is_bound()) { - // so we have happy traveling passengers - start_halt->starte_mit_route(pax); - start_halt->add_pax_happy(pax.menge); - // and show it - merke_passagier_ziel(ziel, COL_YELLOW); - city_history_year[0][history_type] += pax.menge; - city_history_month[0][history_type] += pax.menge; - } else { - start_halt->add_pax_no_route(pax_left_to_do); - merke_passagier_ziel(ziel, COL_DARK_ORANGE); + if (ziel_count == 0) { + // DBG_MESSAGE("stadt_t::step_passagiere()", "No stop near dest (%d, %d)", ziel.x, ziel.y); + // Thus, routing is not possible and we do not need to do a calculation. + // Mark ziel as destination without route and continue. + merke_passagier_ziel(destinations[current_destination].location, COL_DARK_ORANGE); + if(start_halts.get_size() > 0) + { + halthandle_t current_halt = *start_halts.get_element(0); + current_halt->add_pax_no_route(pax_left_to_do); + } + route_good = false; + + if(has_private_car) + { + + // No way of getting there by public transport, so must go + // by private car if available. + + // One day, it would be good if this could check to see whether + // there was a road between the origin and destination towns, too. + + //@author: jamespetts + + set_private_car_trip(pax_left_to_do, destinations[current_destination].town); + route_good = true; #ifdef DESTINATION_CITYCARS - //citycars with destination - erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, ziel); + //citycars with destinations + if(start_halt.is_bound()) + { + //"Produce road users" (Babelfish) + erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, destinations[current_destination].location); + } #endif - } + } + current_destination ++; + continue; + } - // send them also back - if (will_return != no_return && pax.get_ziel().is_bound()) { - // this comes most of the times for free and balances also the amounts! - halthandle_t ret_halt = pax.get_ziel(); - if (will_return != town_return) { - // restore normal mail amount => more mail from attractions and factories than going to them - pax.menge = pax_left_to_do; + // check, if they can walk there? + if (can_walk_ziel) { + // so we have happy passengers + start_halt->add_pax_happy(pax_left_to_do); + merke_passagier_ziel(destinations[0].location, COL_YELLOW); + city_history_year[0][history_type] += pax_left_to_do; + city_history_month[0][history_type] += pax_left_to_do; + route_good = true; + current_destination ++; + continue; } - // we just have to ensure, the ware can be delivered at this station - warenziel_t wz(start_halt, wtyp); - bool found = false; - for (uint i = 0; i < plan->get_haltlist_count(); i++) { - halthandle_t test_halt = halt_list[i]; - if (test_halt->is_enabled(wtyp) && (start_halt==test_halt || test_halt->get_warenziele(wtyp->get_catg_index())->contains(wz))) { - found = true; - start_halt = test_halt; + // ok, they are not in walking distance + ware_t pax(wtyp); //Journey start information needs to be added later. + pax.set_zielpos(destinations[current_destination].location); + pax.menge = (wtyp == warenbauer_t::passagiere ? pax_left_to_do : max(1, pax_left_to_do >> 2)); + //"Menge" = volume (Google) + + // now, finally search a route; this consumes most of the time + koord return_zwischenziel = koord::invalid; // for people going back ... + //start_halt->suche_route(pax, will_return ? &return_zwischenziel : NULL); + halthandle_t best_destination[3]; + uint8 best_journey_steps = 255; + + for(int i = start_halts.get_size() - 1; i >= 0; i--) + { + if(start_halts.get_size() < 1) + { break; } + halthandle_t current_halt = *start_halts.get_element(i); + current_halt->suche_route(pax, will_return ? &return_zwischenziel : NULL); + if(!pax.get_ziel().is_bound()) + { + //Only continue processing if there is a route. + continue; + } + route_good = true; + halthandle_t tmp[3]; + tmp[0] = pax.get_ziel(); + tmp[1] = pax.get_zwischenziel(); + tmp[2] = *start_halts.get_element(i); + // Will fail if there is another journey with the same number of steps, + // but this does not matter, since they both count as the same. + uint8 tmp2 = pax.get_journey_steps(); + if(tmp2 < best_journey_steps) + { + best_journey_steps = tmp2; + best_destination[0] = pax.get_ziel(); + best_destination[1] = pax.get_zwischenziel(); + best_destination[2] = tmp[2]; + } } + + //TODO: Improve means of selecting the best route here. + + if(route_good) + { + //Only add passengers to the start halt (etc.) if a route was found. + pax.set_ziel(best_destination[0]); + pax.set_zwischenziel(best_destination[1]); + pax.set_journey_steps(best_journey_steps); + start_halt = best_destination[2]; + pax.set_origin(start_halt); + pax.set_previous_transfer(start_halt); + pax.set_total_journey_start_time(welt->get_zeit_ms()); + pax.set_journey_leg_start_time(welt->get_zeit_ms()); + + // Now, decide whether passengers would prefer to use their private cars, + // even though they can travel by public transport. + if(has_private_car) + { + //Weighted random. + uint8 private_car_chance = simrand(100); + if(private_car_chance < 1) + { + // If the chances are zero, skip all the rest of this code. This + // will speed up processing, and enable reversion to older behaviour. + goto public_transport; + } + + // The basic preference for using a private car if available. + sint16 car_preference = welt->get_einstellungen()->get_base_car_preference_percent(); + + //First, adjust for distance. For very long-distance journies, cars are less popular. + uint16 distance = abs(destinations[current_destination].location.x - pos.x) + abs(destinations[current_destination].location.x - pos.y); + if(distance > (midrange_passengers_max_distance * 3)) + { + if(distance >= longdistance_passengers_max_distance) + { + car_preference /= 10; + } + else + { + float proportion = ((float)distance - (float)(midrange_passengers_max_distance * 3)) / (float)longdistance_passengers_max_distance; + car_preference /= (10 * proportion); + } + } + + // Secondly, congestion. Drivers will turn to public transport if the oirin or destination towns are congested. + + // This percentage of drivers will prefer to use the car however congested that it is. + static const sint16 always_prefer_car_percent = welt->get_einstellungen()->get_always_prefer_car_percent(); + + //Average congestion of origin and destination towns, and, at the same time, reduce factor. + uint8 congestion_total; + if(destinations[current_destination].town != NULL) + { + congestion_total = (city_history_month[0][HIST_CONGESTION] + destinations[current_destination].town->get_congestion()) / 4; + } + else + { + congestion_total = (city_history_month[0][HIST_CONGESTION] / 1.33); + } + sint16 congestion_factor = ((car_preference - congestion_total) > always_prefer_car_percent) ? congestion_total : (car_preference - always_prefer_car_percent); + car_preference -= congestion_factor; + + // Thirdly adjust for service quality of the public transport. + + //For some reason, the journey steps seem to be multiplied by 7. + uint8 hops = best_journey_steps / 7; + + //Firstly, the number of steps + float hop_factor; + switch(hops) + { + case 0: + case 1: + + hop_factor = 1.16; + break; + + case 2: + + hop_factor = 1.1; + break; + + case 3: + + hop_factor = 1; + break; + + case 4: + hop_factor = 0.8; + break; + + case 5: + hop_factor = 0.75; + break; + + case 6: + hop_factor = 0.66; + break; + + case 7: + hop_factor = 0.575; + break; + + case 8: + hop_factor = 0.48; + break; + + case 9: + hop_factor = 0.4; + break; + + default: + hop_factor = 0.33; + }; + + private_car_chance *= hop_factor; + + //Secondly, the number of unhappy passengers at the start station compared with the number of happy passengers. + float unhappy_total = start_halt->get_pax_unhappy() - start_halt->get_pax_happy(); + float unhappy_factor; + if(unhappy_total > 0) + { + unhappy_factor = unhappy_total / start_halt->get_capacity(0); + } + else + { + unhappy_factor = 0.0; + } - // now try to add them to the target halt - sint32 max_ware =ret_halt->get_capacity(wtyp->get_index()); + if(unhappy_factor > 0.8) + { + private_car_chance /= unhappy_factor; + } + + //Finally, determine whether the private car is used. + if(private_car_chance <= car_preference) + { + set_private_car_trip(num_pax, destinations[current_destination].town); + #ifdef DESTINATION_CITYCARS + //citycars with destination + if(start_halt.is_bound()) + { + erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, destinations[current_destination].location); + } + #endif + current_destination ++; + break; + } + } + + public_transport : + + //This code should only be reached if the passengers do not use a private car. + start_halt->starte_mit_route(pax); + start_halt->add_pax_happy(pax.menge); + // and show it + merke_passagier_ziel(destinations[current_destination].location, COL_YELLOW); + city_history_year[0][history_type] += pax.menge; + city_history_month[0][history_type] += pax.menge; + + } else { + if(start_halts.get_size() > 0) + { + start_halt = *start_halts.get_element(0); //If there is no route, it does not matter where passengers express their unhappiness. + start_halt->add_pax_no_route(pax_left_to_do); + merke_passagier_ziel(destinations[current_destination].location, COL_DARK_ORANGE); + } + if(has_private_car) + { + //Must use private car, since there is no route. + set_private_car_trip(num_pax, destinations[current_destination].town); + #ifdef DESTINATION_CITYCARS + //citycars with destination + if(start_halt.is_bound()) + { + erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, destinations[current_destination].location); + } + #endif + } + } + + // send them also back + if (will_return != no_return && route_good) { + // this comes most of the times for free and balances also the amounts! + halthandle_t ret_halt = pax.get_ziel(); + if (will_return != town_return) { + // restore normal mail amount => more mail from attractions and factories than going to them + pax.menge = pax_left_to_do; + } + + // we just have to ensure, the ware can be delivered at this station + warenziel_t wz(start_halt, wtyp); + bool found = false; + for (uint i = 0; i < plan->get_haltlist_count(); i++) { + halthandle_t test_halt = halt_list[i]; + if (test_halt->is_enabled(wtyp) && (start_halt==test_halt || test_halt->get_warenziele(wtyp->get_catg_index())->contains(wz))) { + found = true; + start_halt = test_halt; + break; + } + } + + // now try to add them to the target halt + sint32 max_ware = ret_halt->get_capacity(wtyp->get_index()); if (ret_halt->get_ware_summe(wtyp) <= max_ware) { // prissi: not overcrowded and can recieve => add them if (found) { - ware_t return_pax (wtyp); - - return_pax.menge = pax_left_to_do; - return_pax.set_zielpos(k); - return_pax.set_ziel(start_halt); - return_pax.set_zwischenziel(welt->lookup(return_zwischenziel)->get_halt()); - - ret_halt->starte_mit_route(return_pax); - ret_halt->add_pax_happy(pax_left_to_do); - } else { - // no route back - ret_halt->add_pax_no_route(pax_left_to_do); + ware_t return_pax (wtyp, ret_halt, welt->get_zeit_ms()); + return_pax.menge = pax_left_to_do; + return_pax.set_zielpos(k); + return_pax.set_ziel(start_halt); + return_pax.set_zwischenziel(welt->lookup(return_zwischenziel)->get_halt()); + return_pax.set_journey_steps(best_journey_steps); + + ret_halt->starte_mit_route(return_pax); + ret_halt->add_pax_happy(pax_left_to_do); + } else { + // no route back + ret_halt->add_pax_no_route(pax_left_to_do); + if(has_private_car) + { + //Must use private car, since there is no route back. + set_private_car_trip(num_pax, destinations[current_destination].town); + } + + } + } + else { + // return halt crowded + ret_halt->add_pax_unhappy(pax_left_to_do); + if(has_private_car) + { + //Must use private car, since the halt is crowded. + set_private_car_trip(num_pax, destinations[current_destination].town); + } } } - else { - // return halt crowded - ret_halt->add_pax_unhappy(pax_left_to_do); - } + INT_CHECK( "simcity 1579" ); + current_destination ++; } - INT_CHECK( "simcity 1579" ); } - } else { + } + else + { // the unhappy passengers will be added to all crowded stops // however, there might be no stop too - for( uint h=0; hget_haltlist_count(); h++ ) { - halthandle_t halt = halt_list[h]; - if (halt->is_enabled(wtyp)) { -// assert(halt->get_ware_summe(wtyp)>halt->get_capacity(); - halt->add_pax_unhappy(num_pax); - } - } // all passengers without suitable start: // fake one ride to get a proper display of destinations (although there may be more) ... pax_zieltyp will_return; - const koord ziel = finde_passagier_ziel(&will_return); -#ifdef DESTINATION_CITYCARS - //citycars with destination - erzeuge_verkehrsteilnehmer(k, step_count, ziel); -#endif - merke_passagier_ziel(ziel, COL_DARK_ORANGE); - // we do not show no route for destination stop! + //const koord ziel = finde_passagier_ziel(&will_return); + destination destination_now = finde_passagier_ziel(&will_return); + + if(!has_private_car) + { + //If the passengers do not have their own private transport, they will be unhappy. + for( uint h=0; hget_haltlist_count(); h++ ) { + halthandle_t halt = halt_list[h]; + if (halt->is_enabled(wtyp)) { + //assert(halt->get_ware_summe(wtyp)>halt->get_capacity(); + halt->add_pax_unhappy(num_pax); + } + } + + #ifdef DESTINATION_CITYCARS + //citycars with destination + erzeuge_verkehrsteilnehmer(k, step_count, destination_now.location); + #endif + merke_passagier_ziel(destination_now.location, COL_DARK_ORANGE); + // we do not show no route for destination stop! + } + else + { + // Otherwise, they have a car and can get to their destination. + // They are not recorded as passengers, and drop out of the system. + // (Except to be recorded as private car trips). + set_private_car_trip(num_pax, destination_now.town); + } } + // long t1 = get_current_time_millis(); + // DBG_MESSAGE("stadt_t::step_passagiere()", "Zeit für Passagierstep: %ld ms\n", (long)(t1 - t0)); +} + -// long t1 = get_current_time_millis(); -// DBG_MESSAGE("stadt_t::step_passagiere()", "Zeit für Passagierstep: %ld ms\n", (long)(t1 - t0)); +inline void +stadt_t::set_private_car_trip(int passengers, stadt_t* destination_town) +{ + if(destination_town == NULL || (destination_town->get_pos().x == pos.x && destination_town->get_pos().y == pos.y)) + { + // Destination town is not set - so going to a factory or tourist attraction. + // Or origin and destination towns are the same. + // Count as a local trip + city_history_year[0][HIST_CITYCARS] += passengers; + city_history_month[0][HIST_CITYCARS] += passengers; + } + else + { + //Inter-city trip + city_history_year[0][HIST_CITYCARS] += passengers; + city_history_month[0][HIST_CITYCARS] += passengers; + + //Also add private car trips to the *destination*. + destination_town->set_private_car_trips(passengers); + + //And mark the trip as outgoing for growth calculations + outgoing_private_cars += passengers; + } } @@ -1556,35 +2186,70 @@ koord stadt_t::get_zufallspunkt() const /* this function generates a random target for passenger/mail * changing this strongly affects selection of targets and thus game strategy */ -koord stadt_t::finde_passagier_ziel(pax_zieltyp* will_return) + +stadt_t::destination stadt_t::finde_passagier_ziel(pax_zieltyp* will_return, uint16 min_distance, uint16 max_distance) { const int rand = simrand(100); + destination current_destination; + current_destination.town = NULL; + current_destination.type = 1; // about 1/3 are workers if (rand < FACTORY_PAX && arbeiterziele.get_sum_weight() > 0) { const fabrik_t* fab = arbeiterziele.at_weight(simrand(arbeiterziele.get_sum_weight())); *will_return = factoy_return; // worker will return - return fab->get_pos().get_2d(); + current_destination.type = FACTORY_PAX; + current_destination.location = fab->get_pos().get_2d(); + return current_destination; } else if (rand < TOURIST_PAX + FACTORY_PAX && welt->get_ausflugsziele().get_sum_weight() > 0) { *will_return = tourist_return; // tourists will return const gebaeude_t* gb = welt->get_random_ausflugsziel(); - return gb->get_pos().get_2d(); + current_destination.type = TOURIST_PAX ; + current_destination.location = gb->get_pos().get_2d(); + return current_destination; } else { // if we reach here, at least a single town existes ... - const stadt_t* zielstadt = welt->get_random_stadt(); + //const stadt_t* zielstadt = welt->get_random_stadt(); // we like nearer towns more - if (abs(zielstadt->pos.x - pos.x) + abs(zielstadt->pos.y - pos.y) > 120) { + //if (abs(zielstadt->pos.x - pos.x) + abs(zielstadt->pos.y - pos.y) > 120) { // retry once ... - zielstadt = welt->get_random_stadt(); + // zielstadt = welt->get_random_stadt(); + //} + + // Ensure that the returned town is within the distance range specified, + // or else find a new town and repeat. + stadt_t* zielstadt; + bool town_within_range = false; + uint8 retry_count = 0; + do + { + zielstadt = welt->get_random_town(); + if(abs(zielstadt->pos.x - pos.x) + abs(zielstadt->pos.y - pos.y) >= min_distance && (zielstadt->pos.x - pos.x) + abs(zielstadt->pos.y - pos.y)<= max_distance) + { + town_within_range = true; + } + //Prevent infinite loops here if there are no suitable towns at all. + retry_count++; + if(retry_count > 32) town_within_range = true; } + while(!town_within_range); // long distance traveller? => then we return + // zielstadt = "Destination city" *will_return = (this != zielstadt) ? town_return : no_return; - return zielstadt->get_zufallspunkt(); + current_destination.location = zielstadt->get_zufallspunkt(); //"random dot" + current_destination.town = zielstadt; + return current_destination; } } +stadt_t::destination stadt_t::finde_passagier_ziel(pax_zieltyp* will_return) +{ + //Default version, gives wide range of distances. + return finde_passagier_ziel(will_return, 0, 4096); +} + void stadt_t::merke_passagier_ziel(koord k, uint8 color) { @@ -2039,9 +2704,10 @@ void stadt_t::erzeuge_verkehrsteilnehmer(koord pos, sint32 level, koord target) } #endif if (!stadtauto_t::list_empty()) { - stadtauto_t* vt = new stadtauto_t(welt, gr->get_pos(), target); + stadtauto_t* vt = new stadtauto_t(welt, gr->get_pos(), target, ¤t_cars); gr->obj_add(vt); welt->sync_add(vt); + current_cars.append(vt); } return; } diff --git a/simcity.h b/simcity.h index eab3d65f6ac..b18713e25e4 100644 --- a/simcity.h +++ b/simcity.h @@ -14,6 +14,9 @@ #include "tpl/vector_tpl.h" #include "tpl/weighted_vector_tpl.h" #include "tpl/array2d_tpl.h" +#include "tpl/slist_tpl.h" + +#include "vehicle/simverkehr.h" class karte_t; class spieler_t; @@ -35,11 +38,11 @@ enum city_cost { HIST_CITYCARS, // number of citycars generated HIST_PAS_TRANSPORTED, // number of passengers who could start their journey HIST_PAS_GENERATED, // total number generated - HIST_MAIL_TRANSPORTED, // letters that could be sended + HIST_MAIL_TRANSPORTED, // letters that could be sent HIST_MAIL_GENERATED, // all letters generated HIST_GOODS_RECIEVED, // times all storages were not empty HIST_GOODS_NEEDED, // times sotrages checked - HIST_POWER_RECIEVED, // power consumption (not used at the moment!) + HIST_CONGESTION, // Level of congestion in the city, expressed in percent.(Was power consumption - discused) MAX_CITY_HISTORY // Total number of items in array }; @@ -82,6 +85,8 @@ class stadt_t * @author Hj. Malthaner */ static bool cityrules_init(cstring_t objpathname); + static void stadt_t::privatecar_init(cstring_t objfilename); + sint16 stadt_t::get_private_car_ownership(sint32 monthyear); private: static karte_t *welt; @@ -148,6 +153,16 @@ class stadt_t */ void roll_history(void); + inline void set_private_car_trip(int passengers, stadt_t* destination_town); + + // This is needed to prevent double counting of incoming traffic. + sint16 incoming_private_cars; + + //This is needed because outgoing cars are disregarded when calculating growth. + sint16 outgoing_private_cars; + + slist_tpl current_cars; + public: /** * Returns pointer to history for city @@ -156,11 +171,20 @@ class stadt_t sint64* get_city_history_year() { return *city_history_year; } sint64* get_city_history_month() { return *city_history_month; } + sint16 get_outstanding_cars(); + // just needed by stadt_info.cc static inline karte_t* get_welt() { return welt; } uint32 stadtinfo_options; + void set_private_car_trips(uint16 number) + { + city_history_month[0][HIST_CITYCARS] += number; + city_history_year[0][HIST_CITYCARS] += number; + incoming_private_cars += number; + } + /* end of histroy related thingies */ private: sint32 best_haus_wert; @@ -397,11 +421,21 @@ class stadt_t void neuer_monat(); + //@author: jamespetts + struct destination + { + koord location; + uint16 type; //1 = town; others as #define above. + stadt_t* town; //NULL if the type is not a town. + }; + + /** * such ein (zufälliges) ziel für einen Passagier * @author Hj. Malthaner */ - koord finde_passagier_ziel(pax_zieltyp *will_return); + destination finde_passagier_ziel(pax_zieltyp* will_return); + destination finde_passagier_ziel(pax_zieltyp* will_return, uint16 min_distance, uint16 max_distance); /** * Gibt die Gruendungsposition der Stadt zurueck. @@ -428,6 +462,8 @@ class stadt_t void zeige_info(void); void add_factory_arbeiterziel(fabrik_t *fab); + + uint8 get_congestion() { return city_history_month[0][HIST_CONGESTION]; } }; #endif diff --git a/simconvoi.cc b/simconvoi.cc index 655869b9ca0..1a5b7df596a 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -71,7 +71,7 @@ static const char * state_names[convoi_t::MAX_STATES] = { "INITIAL", - "FAHRPLANEINGABE", + "FAHRPLANEINGABE", //"Schedule input" "ROUTING_1", "", "", @@ -713,7 +713,7 @@ void convoi_t::step() // Hajo: now calculate a new route drive_to(v->get_pos(), fpl->get_current_eintrag().pos); if(!route.empty()) { - vorfahren(); + vorfahren(); //"Front" (Google) } else { state = NO_ROUTE; @@ -1169,7 +1169,6 @@ bool convoi_t::set_schedule(schedule_t * f) } - schedule_t *convoi_t::create_schedule() { if(fpl == NULL) { @@ -1253,7 +1252,7 @@ convoi_t::can_go_alte_richtung() //DBG_MESSAGE("convoi_t::go_alte_richtung()","alte=%d, neu_rwr=%d",alte_richtung,neue_richtung_rwr); // we continue our journey; however later cars need also a correct route entry - // eventually we need to add their positions to the convois route + // eventually we need to add their positions to the convoi's route koord3d pos = fahr[0]->get_pos(); assert(pos==route.position_bei(0)); if(welt->lookup(pos)->get_depot()) { @@ -1631,7 +1630,7 @@ convoi_t::rdwr(loadsave_t *file) } state = INITIAL; } - // add to blockstrecke + // add to blockstrecke "block stretch" (Google). Possibly "block section"? if(v->get_waytype()==track_wt || v->get_waytype()==monorail_wt || v->get_waytype()==maglev_wt || v->get_waytype()==narrowgauge_wt) { schiene_t* sch = (schiene_t*)gr->get_weg(v->get_waytype()); if(sch) { @@ -1856,6 +1855,8 @@ void convoi_t::get_freight_info(cbuffer_t & buf) ware_t ware = iter_vehicle_ware.get_current(); for(unsigned i=0; icapacity; for(i=0; i0 && i!=warenbauer_t::INDEX_NONE) { + //TODO: Replace this with the new constructor with the origin and timekeeping values. ware_t ware(warenbauer_t::get_info(i)); ware.menge = max_loaded_waren[i]; if(ware.get_catg()==0) { @@ -1944,6 +1946,9 @@ void convoi_t::open_schedule_window() /* Fahrzeuge passen oft nur in bestimmten kombinationen * die Beschraenkungen werden hier geprueft, die für die Nachfolger von * vor gelten - daher muß vor != NULL sein.. + * TRANSLATION: (Google) + * Vehicles are often triggered only in certain combinations restrictions are approved, + * the successor to continue to apply - therefore must be done before != NULL. */ bool convoi_t::pruefe_nachfolger(const vehikel_besch_t *vor, const vehikel_besch_t *hinter) @@ -1963,6 +1968,7 @@ convoi_t::pruefe_nachfolger(const vehikel_besch_t *vor, const vehikel_besch_t *h if(hinter == soll) { // Diese Beschränkung erlaubt unseren Nachfolger + // This restriction allows our successors (Google translations) return true; } } @@ -1974,14 +1980,19 @@ convoi_t::pruefe_nachfolger(const vehikel_besch_t *vor, const vehikel_besch_t *h /* Fahrzeuge passen oft nur in bestimmten kombinationen * die Beschraenkungen werden hier geprueft, die für die Vorgänger von * hinter gelten - daher muß hinter != NULL sein. + * + * Vehicles are often only fit in certain combinations, + * the restrictions are approved, the predecessor of + * behind apply - must be behind! = NULL. (Google) */ bool convoi_t::pruefe_vorgaenger(const vehikel_besch_t *vor, const vehikel_besch_t *hinter) { - const vehikel_besch_t *soll; + const vehikel_besch_t *soll; //"Soll" = should (Google) if(!hinter->get_vorgaenger_count()) { // Alle Vorgänger erlaubt + // "All previous permits" (Google). return true; } for(int i=0; i < hinter->get_vorgaenger_count(); i++) { @@ -1993,6 +2004,7 @@ convoi_t::pruefe_vorgaenger(const vehikel_besch_t *vor, const vehikel_besch_t *h if(vor == soll) { // Diese Beschränkung erlaubt unseren Vorgänger + // This restriction allows our predecessors (Google) return true; } } @@ -2089,7 +2101,8 @@ void convoi_t::calc_gewinn() for(unsigned i=0; icalc_gewinn(v->last_stop_pos, v->get_pos().get_2d() ); + convoi_t *tmp = this; + gewinn += v->calc_gewinn(v->last_stop_pos, v->get_pos().get_2d(), tmp ); v->last_stop_pos = v->get_pos().get_2d(); } @@ -2105,6 +2118,7 @@ void convoi_t::calc_gewinn() /** * convoi an haltestelle anhalten + * "Convoi stop at stop" (Google translations) * @author Hj. Malthaner * * V.Meyer: ladegrad is now stored in the object (not returned) @@ -2141,13 +2155,9 @@ void convoi_t::hat_gehalten(koord k, halthandle_t halt) break; } - // we need not to call this on the same position - if( v->last_stop_pos != v->get_pos().get_2d() ) { - // calc_revenue - gewinn += v->calc_gewinn(v->last_stop_pos, v->get_pos().get_2d() ); - v->last_stop_pos = v->get_pos().get_2d(); - } - + // we need not to call this on the same position if( v->last_stop_pos != v->get_pos().get_2d() ) { // calc_revenue + convoi_t *tmp = this; + gewinn += v->calc_gewinn(v->last_stop_pos, v->get_pos().get_2d(), tmp ); v->last_stop_pos = v->get_pos().get_2d(); freight_info_resort |= v->entladen(k, halt); if(!no_load) { // do not load anymore @@ -2406,12 +2416,12 @@ convoi_t::init_financial_history() } } -sint32 -convoi_t::get_running_cost() const +sint32 convoi_t::get_running_cost() const { sint32 running_cost = 0; - for (unsigned i = 0; iget_betriebskosten(); + for (unsigned i = 0; iget_betriebskosten(welt); //"get_operatingCost" (Google). "Fahr" = "Drive" (Babelfish) + running_cost += vehicle_running_cost; } return running_cost; } @@ -2467,6 +2477,27 @@ uint8 convoi_t::get_status_color() const return COL_BLACK; } +uint8 +convoi_t::get_catering_level(uint8 type) const +{ + uint8 max_catering_level = 0; + uint8 current_catering_level; + for(sint16 i = fahr.get_size() - 1; i >= 0; i --) + { + vehikel_t* v = get_vehikel(i); + if(v == NULL) + { + continue; + } + current_catering_level = v->get_besch()->get_catering_level(); + if(current_catering_level > max_catering_level && v->get_besch()->get_ware()->get_catg_index() == type) + { + max_catering_level = current_catering_level; + } + } + return max_catering_level; +} + /** diff --git a/simconvoi.h b/simconvoi.h index 8db4fe02e56..e9b4cdaf36a 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -778,6 +778,10 @@ class convoi_t : public sync_steppable, public overtaker_t // Overtaking for convois virtual bool can_overtake(overtaker_t *other_overtaker, int other_speed, int steps_other, int diagonal_length); + + //Returns the maximum catering level of the category type given in the convoy. + //@author: jamespetts + uint8 get_catering_level(uint8 type) const; }; #endif diff --git a/simdings.cc b/simdings.cc index 8208ff3acdb..09f3e42f6d9 100644 --- a/simdings.cc +++ b/simdings.cc @@ -129,6 +129,7 @@ ding_t::~ding_t() /** * setzt den Besitzer des dings * (public wegen Rathausumbau - V.Meyer) + * "sets the owner of the thing" (Babelfish) * @author Hj. Malthaner */ void ding_t::set_besitzer(spieler_t *sp) diff --git a/simfab.cc b/simfab.cc index 8af6a102aa3..5b23b006b51 100644 --- a/simfab.cc +++ b/simfab.cc @@ -948,6 +948,7 @@ void fabrik_t::verteile_waren(const uint32 produkt) halthandle_t halt = haltlist[i]; // Über alle Ziele iterieren + // "Iterate over all goals" (Babelfish) for(uint32 n=0; nverbraucht(ausgang[produkt].get_typ())) >= 0) { - ware_t ware(ausgang[produkt].get_typ()); + //ware_t ware(ausgang[produkt].get_typ()); + ware_t ware(ausgang[produkt].get_typ(), halt, welt->get_zeit_ms()); ware.menge = menge; ware.set_zielpos( lieferziel ); @@ -1003,6 +1005,7 @@ void fabrik_t::verteile_waren(const uint32 produkt) } // Auswertung der Ergebnisse + // "Evaluation of the results" (Babelfish) if (!dist_list.empty()) { slist_iterator_tpl iter (dist_list); diff --git a/simfab.h b/simfab.h index a8df465c3c6..df45b22359e 100644 --- a/simfab.h +++ b/simfab.h @@ -56,7 +56,11 @@ class ware_production_t * hergestellt oder verbraucht wird, 0 wenn gerade nichts * hergestellt oder verbraucht wird und > 0 sonst * (entspricht Vorrat/Verbrauch). - * + * + * A class of factories in Simutrans. + * Factories produce and consume goods and supplies near bus stops. + * The query functions return -1 if a product is never produced or consumed, + * 0 when nothing is manufactured or consumed and> 0 otherwise (equivalent to stocks / consumption). * @date 1998 * @see haltestelle_t * @author Hj. Malthaner @@ -73,6 +77,8 @@ class fabrik_t private: /** * Die möglichen Lieferziele + * + * The possible delivery targets * @author Hj. Malthaner */ vector_tpl lieferziele; @@ -92,6 +98,7 @@ class fabrik_t /** * Die erzeugten waren auf die Haltestellen verteilen + * The produced were distributed at the stops * @author Hj. Malthaner */ void verteile_waren(const uint32 produkt); @@ -107,18 +114,21 @@ class fabrik_t /** * Bauposition gedreht? + * Building position turned? * @author V.Meyer */ uint8 rotate; /** * produktionsgrundmenge + * "production fundamental set" * @author Hj. Malthaner */ sint32 prodbase; /** * multiplikator für die Produktionsgrundmenge + * multiplier for the production of basic quantity * @author Hj. Malthaner */ sint32 prodfaktor; @@ -128,6 +138,7 @@ class fabrik_t /** * Zeitakkumulator für Produktion + * Time accumulator for production * @author Hj. Malthaner */ sint32 delta_sum; @@ -190,6 +201,7 @@ class fabrik_t /** * Fügt ein neues Lieferziel hinzu + * Adds a new delivery goal * @author Hj. Malthaner */ void add_lieferziel(koord ziel); @@ -203,11 +215,11 @@ class fabrik_t void rem_supplier(koord pos); /** - * @return menge der ware typ - * -1 wenn typ nicht produziert wird - * sonst die gelagerte menge + * @return menge der ware typ ("quantity of the goods type") + * -1 wenn typ nicht produziert wird ("if not type is produced") + * sonst die gelagerte menge ("otherwise the stored quantity") */ - sint32 input_vorrat_an(const ware_besch_t *ware); // Vorrat von Warentyp + sint32 input_vorrat_an(const ware_besch_t *ware); // Vorrat von Warentyp ("Inventories of product") sint32 vorrat_an(const ware_besch_t *ware); // Vorrat von Warentyp // returns all power and consume it @@ -224,13 +236,13 @@ class fabrik_t * 0 wenn Produktionsstopp, * -1 wenn Ware nicht verarbeitet wird */ - sint32 verbraucht(const ware_besch_t *); // Nimmt fab das an ?? - sint32 hole_ab(const ware_besch_t *, sint32 menge ); // jemand will waren abholen + sint32 verbraucht(const ware_besch_t *); // Nimmt fab das an ?? ("Notes to the fab?") + sint32 hole_ab(const ware_besch_t *, sint32 menge ); // jemand will waren abholen ("someone wants to pick up were") sint32 liefere_an(const ware_besch_t *, sint32 menge); sint32 get_abgabe_letzt(sint32 t) { return ausgang[t].abgabe_letzt; } - void step(long delta_t); // fabrik muss auch arbeiten + void step(long delta_t); // fabrik muss auch arbeiten ("factory must also work") void neuer_monat(); const char *get_name() const { return besch ? translator::translate(besch->get_name()) : "unnamed"; } @@ -247,12 +259,15 @@ class fabrik_t /** * gibt eine NULL-Terminierte Liste von Fabrikpointern zurück * + * a zero-scheduled list of factory pointers returns * @author Hj. Malthaner */ static vector_tpl & sind_da_welche(karte_t *welt, koord min, koord max); /** * gibt true zurueck wenn sich ein fabrik im feld befindet + * + * "gives true back if factory in the field is" * * @author Hj. Malthaner */ @@ -260,10 +275,13 @@ class fabrik_t static bool ist_bauplatz(karte_t *welt, koord pos, koord groesse, bool water, climate_bits cl); // hier die methoden zum parametrisieren der Fabrik + // "here the methods to parameterize the factory" /** * Baut die Gebäude für die Fabrik * + * "Build the buildings for the factory" + * * @author Hj. Malthaner, V. Meyer */ void baue(sint32 rotate); diff --git a/simhalt.cc b/simhalt.cc index df4ea3dd20c..7c7144f3d74 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -715,7 +715,7 @@ haltestelle_t::step() * Called every month * @author Hj. Malthaner */ -void haltestelle_t::neuer_monat() +void haltestelle_t::neuer_monat() //"New month" { if( welt->get_active_player()==besitzer_p && status_color == COL_RED ) { char buf[256]; @@ -758,7 +758,7 @@ void haltestelle_t::reroute_goods() // Hajo: // Step 1: re-route goods now and then to adapt to changes in // world layout, remove all goods which destination was removed from the map - // prissi; + // prissi: // also the empty entries of the array are cleared for(int j=warray->get_count()-1; j>=0; j-- ) { ware_t & ware = (*warray)[j]; @@ -1193,6 +1193,7 @@ void haltestelle_t::suche_route(ware_t &ware, koord *next_to_ziel) route_tail = node; #endif // betretene Haltestellen markieren + //enter stops mark (Google) tmp_halt->marke = current_mark; } } @@ -1214,10 +1215,12 @@ void haltestelle_t::suche_route(ware_t &ware, koord *next_to_ziel) if(tmp) { // ziel gefunden + // Goal found ware.set_ziel( tmp->halt ); if(tmp->link == NULL) { // kein zwischenziel + // no intermediate target ware.set_zwischenziel(ware.get_ziel()); if(next_to_ziel!=NULL) { // for reverse route the next hop, but not hop => enter start @@ -1230,12 +1233,13 @@ void haltestelle_t::suche_route(ware_t &ware, koord *next_to_ziel) *next_to_ziel = tmp->link->halt->get_basis_pos(); } // zwischenziel ermitteln + // determine between goal while(tmp->link->link) { tmp = tmp->link; } ware.set_zwischenziel(tmp->halt); } - + ware.set_journey_steps(step); } else { // no suitable target station found @@ -1285,6 +1289,7 @@ void haltestelle_t::add_pax_unhappy(int n) +//" to provide factory" (Google) void haltestelle_t::liefere_an_fabrik(const ware_t& ware) { slist_iterator_tpl fab_iter(fab_list); @@ -1342,7 +1347,6 @@ bool haltestelle_t::recall_ware( ware_t& w, uint32 menge ) } - // will load something compatible with wtyp into the car which schedule is fpl ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t *fpl) { @@ -1356,6 +1360,10 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t // da wir schon an der aktuellem haltestelle halten // startet die schleife ab 1, d.h. dem naechsten halt + + // there we already at the current stop hold start + // sharpen starting from 1, i.e. the next stop (Babelfish) + for( uint8 i=1; iget_aktuell()) % count; @@ -1365,6 +1373,8 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t break; } else if( plan_halt.is_bound() && warray->get_count()>0 ) { + //@author: isidoro + bool is_full=(plan_halt->sum_all_waiting_goods()>plan_halt->get_capacity(wtyp->get_catg_index()) && wtyp!=warenbauer_t::passagiere && wtyp!=warenbauer_t::post); // The random offset will ensure that all goods have an equal chance to be loaded. sint32 offset = simrand(warray->get_count()); @@ -1383,6 +1393,11 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t // compatible car and right target stop? if( tmp.get_zwischenziel()==plan_halt ) { + //@author: isidoro + // if full and not destination, skip + if (is_full && tmp.get_zwischenziel()!=tmp.get_ziel()) { + continue; + } // not too much? ware_t neu(tmp); @@ -1484,15 +1499,25 @@ uint32 haltestelle_t::sum_all_waiting_goods() const //15-Feb-2002 Markus bool haltestelle_t::vereinige_waren(const ware_t &ware) { + //This is the method that merges identical goods arriving at a halt. + // pruefen ob die ware mit bereits wartender ware vereinigt werden kann + // examine whether the software with hardware already waiting to be united vector_tpl * warray = waren[ware.get_besch()->get_catg_index()]; if(warray!=NULL) { for(unsigned i=0; iget_count(); i++ ) { ware_t &tmp = (*warray)[i]; // es wird auf basis von Haltestellen vereinigt + // It is based on stopping united // prissi: das ist aber ein Fehler für alle anderen Güter, daher Zielkoordinaten für alles, was kein passagier ist ... - if(ware.same_destination(tmp)) { + // prissi: but that is a mistake for all other goods, therefore target coordinates for everything that is not a passenger + //if(ware.same_destination(tmp)) { + + // Check that the goods are really identical: needed for origin tracking and timing. + //@author: jamespetts + if(&ware == &tmp) + { tmp.menge += ware.menge; resort_freight_info = true; return true; @@ -1534,7 +1559,7 @@ void haltestelle_t::add_ware_to_halt(ware_t ware) */ uint32 haltestelle_t::starte_mit_route(ware_t ware) { - if(ware.get_ziel()==self) { + if(ware.get_ziel()== self) { if(ware.is_freight()) { // muss an fabrik geliefert werden liefere_an_fabrik(ware); @@ -1554,6 +1579,7 @@ uint32 haltestelle_t::starte_mit_route(ware_t ware) } } + // passt das zu bereits wartender ware ? if(vereinige_waren(ware)) { // dann sind wir schon fertig; @@ -1572,7 +1598,7 @@ uint32 haltestelle_t::starte_mit_route(ware_t ware) * if no route is found, it will be removed * @author prissi */ -uint32 haltestelle_t::liefere_an(ware_t ware) +uint32 haltestelle_t::liefere_an(ware_t ware) //"Deliver" (Babelfish) { // no valid next stops? if(!ware.get_ziel().is_bound() || !ware.get_zwischenziel().is_bound()) { @@ -1581,13 +1607,16 @@ dbg->warning("haltestelle_t::liefere_an()","%d %s delivered to %s have no longer return ware.menge; } - // did we arrived? - if(welt->lookup(ware.get_zielpos())->is_connected(self)) { + // Have we arrived? + if(welt->lookup(ware.get_zielpos())->is_connected(self)) + { if(ware.is_freight()) { // muss an fabrik geliefert werden + // "must be supplied at factory" (Babelfish) liefere_an_fabrik(ware); } - else if(ware.get_besch()==warenbauer_t::passagiere) { + else if(ware.get_besch()==warenbauer_t::passagiere) + { // arriving passenger may create pedestrians if(welt->get_einstellungen()->get_show_pax()) { int menge = ware.menge; @@ -1603,12 +1632,18 @@ dbg->warning("haltestelle_t::liefere_an()","%d %s delivered to %s have no longer } // do we have already something going in this direction here? - if(vereinige_waren(ware)) { + if(vereinige_waren(ware)) { //"Combine ware" (Babelfish) return ware.menge; } // not near enough => we need to do a rerouting suche_route(ware); + + // Sets the intermediate origin and timings. + //@author: jamespetts + ware.set_previous_transfer(self); + ware.set_journey_leg_start_time(welt->get_zeit_ms()); + INT_CHECK("simhalt 1364"); // target no longer there => delete @@ -1616,6 +1651,15 @@ dbg->warning("haltestelle_t::liefere_an()","%d %s delivered to %s have no longer DBG_MESSAGE("haltestelle_t::liefere_an()","%s: delivered goods (%d %s) to ??? via ??? could not be routed to their destination!",get_name(), ware.menge, translator::translate(ware.get_name()) ); return ware.menge; } + + //@author: isidoro + // Passengers and next transfer station crowded ==> become unhappy and discarded + if((ware.get_besch()==warenbauer_t::passagiere || ware.get_besch()==warenbauer_t::post) && ware.get_zwischenziel().is_bound() && ware.get_ziel().is_bound() && ware.get_zwischenziel()!=ware.get_ziel() && ware.get_zwischenziel()->get_ware_summe(warenbauer_t::passagiere)>ware.get_zwischenziel()->get_capacity(0)) { + if (ware.get_besch()==warenbauer_t::passagiere) { + ware.get_zwischenziel()->add_pax_unhappy(ware.menge); + } + return ware.menge; + } // passt das zu bereits wartender ware ? if(vereinige_waren(ware)) { @@ -1630,11 +1674,11 @@ dbg->warning("haltestelle_t::liefere_an()","%d %s delivered to %s have no longer } - #ifdef USE_QUOTE // rating of this place ... const char * -haltestelle_t::quote_bezeichnung(int quote, convoihandle_t cnv) const +//haltestelle_t::quote_bezeichnung(int quote, convoihandle_t cnv) const +haltestelle_t::quote_bezeichnung(int quote) const { const char *str = "unbekannt"; diff --git a/simhalt.h b/simhalt.h index 68de5f0c37a..f719081fbaa 100644 --- a/simhalt.h +++ b/simhalt.h @@ -184,6 +184,7 @@ class haltestelle_t slist_tpl warenziele[3]; // loest warte_menge ab + // "solves wait mixes off" (Babelfish); "solves warte volume from" (Google) vector_tpl **waren; /** @@ -236,8 +237,11 @@ class haltestelle_t */ uint32 marke; +//#define USE_QUOTE + #ifdef USE_QUOTE // for station rating + //const char * quote_bezeichnung(int quote, convoihandle_t cnv) const; const char * quote_bezeichnung(int quote) const; #endif @@ -458,7 +462,10 @@ class haltestelle_t /** * holt ware ab + * fetches ware from (Google) + * * @return abgeholte menge + * @return collected volume (Google) * @author Hj. Malthaner */ ware_t hole_ab(const ware_besch_t *warentyp, uint32 menge, schedule_t *fpl); @@ -467,6 +474,10 @@ class haltestelle_t * werden kann, kann ware_t gelöscht werden! D.h. man darf ware nach * aufruf dieser Methode nicht mehr referenzieren! * + * Ware to deliver. If the goods to waiting to be taken product + * can be ware_t may be deleted! I.e. we must, after calling this + * method no longer refer! (Google) + * * The second version is like the first, but will not recalculate the route * This is used for inital passenger, since they already know a route * diff --git a/simmain.cc b/simmain.cc index 68543847ace..60dc4087ba0 100644 --- a/simmain.cc +++ b/simmain.cc @@ -587,6 +587,9 @@ int simu_main(int argc, char** argv) print("Reading speedbonus configuration ...\n"); vehikelbauer_t::speedbonus_init(umgebung_t::objfilename); + print("Reading private car ownership configuration ...\n"); + stadt_t::privatecar_init(umgebung_t::objfilename); + print("Reading forest configuration ...\n"); baum_t::forestrules_init(umgebung_t::objfilename); diff --git a/simversion.h b/simversion.h index 49821cf825b..72dfe38d2b7 100644 --- a/simversion.h +++ b/simversion.h @@ -3,8 +3,10 @@ #define MAKEOBJ_VERSION "49" -#define VERSION_NUMBER "101.1 Nightly" -#define WIDE_VERSION_NUMBER L"101.1 Nightly" +//#define VERSION_NUMBER "101.1 Nightly" +#define VERSION_NUMBER "101.1 Experimental" +//#define WIDE_VERSION_NUMBER L"101.1 Nightly" +#define WIDE_VERSION_NUMBER L"101.1 Experimental" #define VERSION_DATE __DATE__ diff --git a/simware.cc b/simware.cc index da7d7eb52de..a0bc19804c6 100644 --- a/simware.cc +++ b/simware.cc @@ -38,6 +38,19 @@ ware_t::ware_t(const ware_besch_t *wtyp) : ziel(), zwischenziel(), zielpos(-1, - { menge = 0; index = wtyp->get_index(); + total_journey_start_time = journey_leg_start_time = 0; + halthandle_t x; + origin = previous_transfer = x; +} + +// Constructor for new revenue system: packet of cargo keeps track of its origin. +//@author: jamespetts +ware_t::ware_t(const ware_besch_t *wtyp, halthandle_t o, uint32 t) : ziel(), zwischenziel(), zielpos(-1, -1) +{ + menge = 0; + index = wtyp->get_index(); + origin = previous_transfer = o; + total_journey_start_time = journey_leg_start_time = t; } ware_t::ware_t(karte_t *welt,loadsave_t *file) @@ -108,7 +121,7 @@ ware_t::rdwr(karte_t *welt,loadsave_t *file) void -ware_t::laden_abschliessen(karte_t *welt) +ware_t::laden_abschliessen(karte_t *welt) //"Invite finish" (Google); "load lock" (Babelfish). { // since some halt was referred by with several koordinates // this routine will correct it diff --git a/simware.h b/simware.h index 0d2b563428a..d4e4b435209 100644 --- a/simware.h +++ b/simware.h @@ -10,6 +10,7 @@ class ware_besch_t; class karte_t; /** Eine Klasse zur Verwaltung von Informationen ueber Fracht und Waren */ +// "A class for the management of information on cargo and goods" (Google translations) class ware_t { friend class warenbauer_t; @@ -25,24 +26,42 @@ class ware_t private: /** - * Koordinate der Zielhaltestelle + * Koordinate der Zielhaltestelle ("Coordinate of the goal stop" - Babelfish). * @author Hj. Malthaner */ halthandle_t ziel; /** - * Koordinte des nächsten Zwischenstops + * Koordinte des nächsten Zwischenstops ("Co-ordinate of the next stop") * @author Hj. Malthaner */ halthandle_t zwischenziel; + //@author: jamespetts + //A handle to the ultimate origin. + halthandle_t origin; + + //The immediately previous transfer (*not* hop) + halthandle_t previous_transfer; + + //The time at which the packet's whole journey began, in ticks. + uint32 total_journey_start_time; + + //The time at which the current leg of the journey began, in ticks. + uint32 journey_leg_start_time; + /** * die engültige Zielposition, * das ist i.a. nicht die Zielhaltestellenposition * @author Hj. Malthaner */ + // "the final target position, which is on behalf not the goal stop position" koord zielpos; + //@author: jamespetts + //The number of remaining steps on this packet's journey. + uint8 journey_steps; + public: const halthandle_t &get_ziel() const { return ziel; } void set_ziel(const halthandle_t &ziel) { this->ziel = ziel; } @@ -55,11 +74,13 @@ class ware_t ware_t(); ware_t(const ware_besch_t *typ); + ware_t(const ware_besch_t *typ, halthandle_t o, uint32 t); ware_t(karte_t *welt,loadsave_t *file); /** * gibt den nicht-uebersetzten warennamen zurück * @author Hj. Malthaner + * "There the non-translated names were back" */ const char *get_name() const { return get_besch()->get_name(); } const char *get_mass() const { return get_besch()->get_mass(); } @@ -67,6 +88,16 @@ class ware_t uint8 get_catg() const { return get_besch()->get_catg(); } uint8 get_index() const { return index; } + //@author: jamespetts + halthandle_t get_origin() const { return origin; } + void set_origin(halthandle_t value) { origin = value; } + halthandle_t get_previous_transfer() const { return previous_transfer; } + void set_previous_transfer(halthandle_t value) { previous_transfer = value; } + uint32 get_total_journey_start_time() const { return total_journey_start_time; } + void set_total_journey_start_time(uint32 value) { total_journey_start_time = value; } + uint32 get_journey_leg_start_time() const { return journey_leg_start_time; } + void set_journey_leg_start_time(uint32 value) { journey_leg_start_time = value; } + const ware_besch_t* get_besch() const { return index_to_besch[index]; } void set_besch(const ware_besch_t* type); @@ -84,9 +115,20 @@ class ware_t menge == w.menge && ziel == w.ziel && zwischenziel == w.zwischenziel && - zielpos == w.zielpos; + zielpos == w.zielpos && + origin == w.origin && + previous_transfer == w.previous_transfer && + // Goods generated within 15 secs (at default speed) of each other + // treated as identical if identical in all other respects. + !(total_journey_start_time > w.total_journey_start_time + 15000) && + !(total_journey_start_time < w.total_journey_start_time - 15000) && + !(journey_leg_start_time > w.journey_leg_start_time + 15000) && + !(journey_leg_start_time < w.journey_leg_start_time - 15000); } + uint8 get_journey_steps() { return journey_steps; } + void set_journey_steps(uint8 value) { journey_steps = value; } + int operator!=(const ware_t &w) { return !(*this == w); } // mail and passengers just care about target station diff --git a/simwerkz.cc b/simwerkz.cc index 3b6b30d59bd..178999d59a2 100644 --- a/simwerkz.cc +++ b/simwerkz.cc @@ -1266,11 +1266,12 @@ const weg_besch_t * wkz_wegebau_t::get_besch(bool remember) const char *wkz_wegebau_t::get_tooltip(spieler_t *sp) { const weg_besch_t *besch = get_besch(false); - sprintf(toolstr, "%s, %ld$ (%ld$), %dkm/h", + sprintf(toolstr, "%s, %ld$ (%ld$), %dkm/h, %dt", translator::translate(besch->get_name()), besch->get_preis()/100l, (besch->get_wartung()<<(sp->get_welt()->ticks_bits_per_tag-18))/100l, - besch->get_topspeed()); + besch->get_topspeed(), + besch->get_max_weight()); return toolstr; } @@ -1523,6 +1524,7 @@ const char *wkz_brueckenbau_t::get_tooltip(spieler_t *sp) if(besch->get_waytype()!=powerline_wt) { n += sprintf(toolstr+n, ", %dkm/h", besch->get_topspeed()); } + n += sprintf(toolstr+n, ", %dt", besch->get_max_weight()); if(besch->get_max_length()>0) { n += sprintf(toolstr+n, ", %dkm", besch->get_max_length()); } @@ -1549,7 +1551,9 @@ const char *wkz_tunnelbau_t::get_tooltip(spieler_t *sp) (besch->get_wartung()<<(sp->get_welt()->ticks_bits_per_tag-18))/100); if(besch->get_waytype()!=powerline_wt) { - n += sprintf(toolstr+n, ", %dkm/h", besch->get_topspeed()); + n += sprintf(toolstr+n, ", %dkm/h, %dt", + besch->get_topspeed(), + besch->get_max_weight()); } return toolstr; } @@ -1920,7 +1924,7 @@ DBG_MESSAGE("wkz_station_building_aux()", "building mail office/station building for( int r=0; r<2; r++ ) { koord testsize = (r&1)==0 ? size : koord(size.y,size.x); for( sint8 j=3; j>=0; j-- ) { - koord offset(((j&1)^1)*(testsize.x-1),(j&1)*(testsize.y-1)); + koord offset(((j&1)^1)*(testsize.x-1),((j>>1)&1)*(testsize.y-1)); if(welt->ist_platz_frei(pos-offset, testsize.x, testsize.y, NULL, besch->get_allowed_climate_bits())) { // well, at least this is theoretical possible here any_ok = true; @@ -1930,7 +1934,7 @@ DBG_MESSAGE("wkz_station_building_aux()", "building mail office/station building int best_halt_n = 0, best_halt_s = 0, best_halt_e = 0, best_halt_w = 0; // test also diagonal corners (that is why from -1 to size!) for( sint16 y=-1; y<=testsize.y; y++ ) { - // left ( for all tiles, even bridges) + // left (for all tiles, even bridges) const planquadrat_t *pl = welt->lookup( test_start+koord(-1,y) ); if( pl && pl->get_halt().is_bound() && sp==pl->get_halt()->get_besitzer() ) { halt = pl->get_halt(); @@ -2032,7 +2036,7 @@ DBG_MESSAGE("wkz_station_building_aux()", "building mail office/station building return "Tile not empty."; } // is there no halt to connect? - if(!halt.is_bound()) { + if( !halt.is_bound() || any_halt==0 ) { return "Post muss neben\nHaltestelle\nliegen!\n"; } @@ -3213,7 +3217,7 @@ const char *wkz_add_citycar_t::work( karte_t *welt, spieler_t *sp, koord3d k ) if( gr != NULL && ribi_t::is_twoway(gr->get_weg_ribi_unmasked(road_wt)) && gr->find() == NULL) { // add citycar - stadtauto_t* vt = new stadtauto_t(welt, gr->get_pos(), koord::invalid); + stadtauto_t* vt = new stadtauto_t(welt, gr->get_pos(), koord::invalid, &(welt->unassigned_cars)); gr->obj_add(vt); welt->sync_add(vt); return NULL; diff --git a/simwin.cc b/simwin.cc index 23bade0ba4c..1c0bb39b788 100644 --- a/simwin.cc +++ b/simwin.cc @@ -1085,13 +1085,14 @@ void win_display_flush(double konto) // @author prissi - also show date if desired switch(umgebung_t::show_month) { // german style - case 4: sprintf(time, "%s, %d. %s %d %d:%02dh", - translator::translate(seasons[wl->get_jahreszeit()]), - tage, - translator::get_month_name(month%12), + case 4: sprintf(time, "%s, %d %s %d %d:%02dh TICKS: %d", + translator::translate(seasons[wl->get_jahreszeit()]), //Season + tage, //Day + translator::get_month_name(month%12), //Month year, - stunden, - minuten + stunden, //"Hours" (Google) + minuten, //Minutes + ticks //HACK: Testing purposes only. ); break; // us style diff --git a/simworld.cc b/simworld.cc index 4374c48bab9..42513d60fad 100644 --- a/simworld.cc +++ b/simworld.cc @@ -43,6 +43,8 @@ #include "tpl/vector_tpl.h" +#include "tpl/binary_heap_tpl.h" +#include "tpl/ordered_vector_tpl.h" #include "boden/boden.h" #include "boden/wasser.h" @@ -525,6 +527,8 @@ karte_t::destroy() { DBG_MESSAGE("karte_t::destroy()", "destroying world"); + is_shutting_down = true; + // rotate the map until it can be saved for( int i=0; i<4 && nosave; i++ ) { DBG_MESSAGE("karte_t::destroy()", "rotating"); @@ -622,6 +626,8 @@ DBG_MESSAGE("karte_t::destroy()", "world destroyed"); printf("World destroyed.\n"); msg->clear(); + + is_shutting_down = false; } @@ -643,6 +649,7 @@ void karte_t::rem_convoi(convoihandle_t& cnv) /** * Zugriff auf das Städte Array. + * Access to the cities array. * @author Hj. Malthaner */ const stadt_t *karte_t::get_random_stadt() const @@ -650,6 +657,12 @@ const stadt_t *karte_t::get_random_stadt() const return stadt.at_weight(simrand(stadt.get_sum_weight())); } +stadt_t *karte_t::get_random_town() +{ + //Non-const version of get_random_stadt(). + return stadt.at_weight(simrand(stadt.get_sum_weight())); +} + void karte_t::add_stadt(stadt_t *s) { einstellungen->set_anzahl_staedte(einstellungen->get_anzahl_staedte()+1); @@ -753,11 +766,84 @@ void karte_t::init_felder() nosave = false; } - +void karte_t::create_rivers( sint16 number ) +{ + // First check, wether there is a canal: + const weg_besch_t* river_besch = wegbauer_t::get_besch( umgebung_t::river_type[umgebung_t::river_types-1], 0 ); + if( river_besch == NULL ) { + // should never reaching here ... + dbg->warning("karte_t::create_rivers()","There is no river defined!\n"); + return; + } + // create a vector of the highest points + vector_tpl water_tiles; + weighted_vector_tpl mountain_tiles; + sint8 last_height = 1; + koord last_koord(0,0); + const sint16 max_dist = cached_groesse_karte_y+cached_groesse_karte_x; + + // trunk of 16 will ensure that rivers are long enough apart ... + for( sint16 y = 8; y < cached_groesse_karte_y; y+=16 ) + { + for( sint16 x = 8; x < cached_groesse_karte_x; x+=16 ) + { + koord k(x,y); + grund_t *gr = lookup_kartenboden(k); + const sint8 h = gr->get_hoehe()-get_grundwasser(); + if( gr->ist_wasser() ) + { + // may be good to start a river here + water_tiles.push_back(k); + } + else if( h>=last_height || abs_distance(last_koord,k)>simrand(max_dist)) + { + // something worth to add here + if( h>last_height ) + { + last_height = h; + } + last_koord = k; + mountain_tiles.append( k, h, 256 ); + } + } + } + if( water_tiles.get_count() == 0 ) + { + dbg->message("karte_t::create_rivers()","There aren't any water tiles!\n"); + return; + } + // now make rivers + while( number>0 && mountain_tiles.get_count()>0 ) + { + koord start = mountain_tiles.at_weight( simrand(mountain_tiles.get_sum_weight()) ); + koord end = water_tiles[ simrand(water_tiles.get_count()) ]; + sint16 dist = abs_distance(start,end); + if( dist > einstellungen->get_min_river_length() && dist < einstellungen->get_max_river_length() ) + { + // should be at least of decent length + wegbauer_t riverbuilder(this, spieler[1]); + riverbuilder.route_fuer(wegbauer_t::river, river_besch); + riverbuilder.set_maximum( dist*50 ); + riverbuilder.calc_route( lookup_kartenboden(end)->get_pos(), lookup_kartenboden(start)->get_pos() ); + if( riverbuilder.max_n >= einstellungen->get_min_river_length() ) + { + // do not built too short rivers + riverbuilder.baue(); + number --; + } + mountain_tiles.remove( start ); + } + } +} void karte_t::distribute_groundobjs_cities(int new_anzahl_staedte, sint16 old_x, sint16 old_y) { DBG_DEBUG("karte_t::distribute_groundobjs_cities()","distributing groundobjs"); + + if( umgebung_t::river_types>0 && einstellungen->get_river_number()>0 ) { + create_rivers( einstellungen->get_river_number() ); + } + if( umgebung_t::ground_object_probability > 0 ) { // add eyecandy like rocky, moles, flowers, ... koord k; @@ -765,7 +851,7 @@ DBG_DEBUG("karte_t::distribute_groundobjs_cities()","distributing groundobjs"); for( k.y=0; k.yget_typ()==grund_t::boden) { + if( gr->get_typ()==grund_t::boden && !gr->hat_wege() ) { queried --; if( queried<0 ) { const groundobj_besch_t *besch = groundobj_t::random_groundobj_for_climate( get_climate(gr->get_hoehe()), gr->get_grund_hang() ); @@ -829,16 +915,15 @@ DBG_DEBUG("karte_t::distribute_groundobjs_cities()","Erzeuge stadt %i with %ld i finance_history_year[0][WORLD_CITICENS] = finance_history_month[0][WORLD_CITICENS] = last_month_bev; // Hajo: connect some cities with roads - const weg_besch_t* besch = wegbauer_t::get_besch(*umgebung_t::intercity_road_type); + const weg_besch_t* besch = wegbauer_t::get_besch(umgebung_t::intercity_road_type); if(besch == 0) { dbg->warning("karte_t::init()", "road type '%s' not found", (const char*)*umgebung_t::intercity_road_type); // Hajo: try some default (might happen with timeline ... ) besch = wegbauer_t::weg_search(road_wt,80,get_timeline_year_month(),weg_t::type_flat); } - // Hajo: No owner so that roads can be removed! - wegbauer_t bauigel (this, 0); - bauigel.route_fuer(wegbauer_t::strasse, besch); + wegbauer_t bauigel (this, spieler[1] ); + bauigel.route_fuer(wegbauer_t::strasse, besch, NULL, brueckenbauer_t::find_bridge(road_wt,15,get_timeline_year_month()) ); bauigel.set_keep_existing_ways(true); bauigel.set_maximum(umgebung_t::intercity_road_length); @@ -942,6 +1027,7 @@ void karte_t::init(einstellungen_t* sets, sint8 *h_field) *einstellungen = *sets; // names during creation time einstellungen->set_name_language_iso( umgebung_t::language_iso ); + einstellungen->set_use_timeline( einstellungen->get_use_timeline()&1 ); x_off = y_off = 0; @@ -2272,9 +2358,11 @@ void karte_t::neuer_monat() // roll city history and copy the new citicens (i.e. the new weight) into the stadt array // no INT_CHECK() here, or dialoges will go crazy!!! weighted_vector_tpl new_weighted_stadt(stadt.get_count() + 1); + outstanding_cars = 0; for (weighted_vector_tpl::const_iterator i = stadt.begin(), end = stadt.end(); i != end; ++i) { stadt_t* s = *i; s->neuer_monat(); + outstanding_cars += s->get_outstanding_cars(); new_weighted_stadt.append(s, s->get_einwohner(), 64); INT_CHECK("simworld 1278"); } @@ -2290,6 +2378,13 @@ void karte_t::neuer_monat() } } + while(unassigned_cars.count() > outstanding_cars) + { + //Make sure that there are not too many cars on the roads. + stadtauto_t* car = unassigned_cars.remove_first(); + car->kill(); + } + INT_CHECK("simworld 1289"); // DBG_MESSAGE("karte_t::neuer_monat()","halts"); diff --git a/simworld.h b/simworld.h index ee31fb9c766..470fd848ae4 100644 --- a/simworld.h +++ b/simworld.h @@ -88,6 +88,14 @@ class karte_t #define MAX_WORLD_HISTORY_YEARS (12) // number of years to keep history #define MAX_WORLD_HISTORY_MONTHS (12) // number of months to keep history + bool get_is_shutting_down() { return is_shutting_down; } + + // City cars that are not assigned to a particular city are stored in this list. + // @author:jamespetts + slist_tpl unassigned_cars; + + void add_unassigned_car(stadtauto_t* car) { unassigned_cars.append(car); outstanding_cars --; } + private: // die Einstellungen einstellungen_t *einstellungen; @@ -108,6 +116,12 @@ class karte_t koord werkzeug_last_pos; // last position a tool was called uint8 werkzeug_last_button; + // Whether the map is currently being destroyed. + // Useful to prevent access violations if objects with + // references to other objects that are destroyed first + // reference members of those objects in their destructors. + bool is_shutting_down; + /** * redraw whole map */ @@ -195,6 +209,10 @@ class karte_t // the recorded history so far sint64 finance_history_year[MAX_WORLD_HISTORY_YEARS][MAX_WORLD_COST]; sint64 finance_history_month[MAX_WORLD_HISTORY_MONTHS][MAX_WORLD_COST]; + + // The number of cars that should be in the world somewhere, but are not + // in any particular city's list. + sint16 outstanding_cars; // word record of speed ... class speed_record_t { @@ -354,7 +372,7 @@ class karte_t // restores history for older savegames void restore_history(); - /** + /* * Will create rivers. */ void create_rivers(sint16 number); /** * Distribute groundobjs and cities on the map but not * in the rectangle from (0,0) till (old_x, old_y). * It's now an extra function so we don't need the code twice. @@ -513,12 +531,16 @@ class karte_t * anzahl ticks pro tag in bits * @see ticks_per_tag * @author Hj. Malthaner + * + * number ticks per day in bits (Babelfish) */ uint32 ticks_bits_per_tag; /** * anzahl ticks pro MONTH! * @author Hj. Malthaner + * + * number ticks per MONTH! (Babelfish) */ uint32 ticks_per_tag; @@ -536,6 +558,9 @@ class karte_t /** * Zeit seit Kartenerzeugung/dem letzen laden in ms * @author Hj. Malthaner + * + * + * Time cards since creation / the last load in ms (Google) */ uint32 get_zeit_ms() const { return ticks; } @@ -552,30 +577,40 @@ class karte_t /** * Anzahl steps seit Kartenerzeugung * @author Hj. Malthaner + * + * Number of steps since map production (Babelfish) */ long get_steps() const { return steps; } /** * Idle time. Nur zur Anzeige verwenden! * @author Hj. Malthaner + * + * Idle time. Use only to the announcement! (Babelfish) */ uint32 get_schlaf_zeit() const { return next_wait_time; } /** * Anzahl frames in der letzten Sekunde Realzeit * @author prissi + * + * Number of frames in the last second of real time (Babelfish) */ uint32 get_realFPS() const { return realFPS; } /** * Anzahl Simulationsloops in der letzten Sekunde. Kann sehr ungenau sein! * @author Hj. Malthaner + * + * Number of simulation loops in the last second. Can be very inaccurate! (Babelfish) */ uint32 get_simloops() const { return simloops; } /** * Holt den Grundwasserlevel der Karte * @author Hj. Malthaner + * + * Gets the groundwater level of the map (Babelfish) */ sint8 get_grundwasser() const { return grundwasser; } @@ -604,7 +639,7 @@ class karte_t void set_werkzeug( werkzeug_t *w ); werkzeug_t *get_werkzeug() const { return werkzeug; } - // all stuf concerning map size + // all stuff concerning map size inline int get_groesse_x() const { return cached_groesse_gitter_x; } inline int get_groesse_y() const { return cached_groesse_gitter_y; } inline int get_groesse_max() const { return cached_groesse_max; } @@ -647,9 +682,10 @@ class karte_t * @return Planquadrat an koordinate pos * @author Hj. Malthaner */ - inline const planquadrat_t * lookup(const koord k) const + inline const planquadrat_t * lookup(const koord k) const //planquadrat = "grid square" (Babelfish) { return ist_in_kartengrenzen(k.x, k.y) ? &plan[k.x+k.y*cached_groesse_gitter_x] : 0; + //ist in kartengrenzen = "is in map-border". (Babelfish) } /** @@ -661,6 +697,7 @@ class karte_t { const planquadrat_t *plan = lookup(pos.get_2d()); return plan ? plan->get_boden_in_hoehe(pos.z) : NULL; + //"boden in hoehe" = floor in height (Google) } /** @@ -672,6 +709,7 @@ class karte_t { const planquadrat_t *plan = lookup(pos); return plan ? plan->get_kartenboden() : NULL; + //kartenboden = map ground (Babelfish) } /** @@ -810,6 +848,7 @@ class karte_t */ const weighted_vector_tpl& get_staedte() const { return stadt; } const stadt_t *get_random_stadt() const; + stadt_t *get_random_town(); void add_stadt(stadt_t *s); bool rem_stadt(stadt_t *s); @@ -863,6 +902,7 @@ class karte_t /** * @return Hoehe am Gitterpunkt i,j + * "Height at the grid point" (Google) * @author Hj. Malthaner */ inline sint16 lookup_hgt(koord k) const { diff --git a/utils/dr_rdpng.c b/utils/dr_rdpng.c index c0f2bda89d7..0e0707ea219 100644 --- a/utils/dr_rdpng.c +++ b/utils/dr_rdpng.c @@ -1,6 +1,7 @@ -#include +//#include #include #include "dr_rdpng.h" +#include "openttd/png.h" static int bit_depth, color_type, interlace_type; @@ -24,6 +25,7 @@ static void read_png(unsigned char** block, unsigned* width, unsigned* height, F exit(1); } + info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { printf("read_png: Could not create info struct.\n"); diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 3e718b00d0d..c13da33618d 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -90,6 +90,22 @@ uint8 vehikel_basis_t::old_diagonal_length = 127; uint8 vehikel_basis_t::diagonal_length = 180; uint16 vehikel_basis_t::diagonal_multiplier = 724; +//@author: jamespetts +uint16 local_bonus_supplement = 0; +//A supplementary bonus for local transportation, +//if needed, to compensate for not having the effect +//of the long-distance speed bonus. + +//@author: jamespetts +// Cornering settings. + +fixed_list_tpl curve_history; +fixed_list_tpl pre_corner_direction; + +sint16 direction_steps = 4; + +bool hill[2]; +bool is_overweight = false; // set only once, before loading! void vehikel_basis_t::set_diagonal_multiplier( uint32 multiplier, uint32 old_diagonal_multiplier ) @@ -100,14 +116,12 @@ void vehikel_basis_t::set_diagonal_multiplier( uint32 multiplier, uint32 old_dia } - // if true, convoi, must restart! bool vehikel_basis_t::need_realignment() { return old_diagonal_length!=diagonal_length && (fahrtrichtung&0x0A)!=0; } - // [0]=xoff [1]=yoff sint8 vehikel_basis_t::overtaking_base_offsets[8][2]; @@ -139,7 +153,6 @@ void vehikel_basis_t::set_overtaking_offsets( bool driving_on_the_left ) } - /** * Checks if this vehicle must change the square upon next move * @author Hj. Malthaner @@ -370,7 +383,7 @@ void vehikel_basis_t::get_screen_offset( int &xoff, int &yoff ) const ribi_t::ribi vehikel_basis_t::calc_set_richtung(koord start, koord ende) { - ribi_t::ribi richtung = ribi_t::keine; + ribi_t::ribi richtung = ribi_t::keine; //"richtung" = direction (Google); "keine" = none (Google) const sint8 di = ende.x - start.x; const sint8 dj = ende.y - start.y; @@ -420,7 +433,34 @@ vehikel_basis_t::calc_set_richtung(koord start, koord ende) return richtung; } +ribi_t::ribi +vehikel_basis_t::calc_check_richtung(koord start, koord ende) +//Dry run version of calc_set_richtung. +{ + ribi_t::ribi richtung = ribi_t::keine; //"richtung" = direction (Google); "keine" = none (Google) + + const sint8 di = ende.x - start.x; + const sint8 dj = ende.y - start.y; + if(dj < 0 && di == 0) { + richtung = ribi_t::nord; + } else if(dj > 0 && di == 0) { + richtung = ribi_t::sued; + } else if(di < 0 && dj == 0) { + richtung = ribi_t::west; + } else if(di >0 && dj == 0) { + richtung = ribi_t::ost; + } else if(di > 0 && dj > 0) { + richtung = ribi_t::suedost; + } else if(di < 0 && dj < 0) { + richtung = ribi_t::nordwest; + } else if(di > 0 && dj < 0) { + richtung = ribi_t::nordost; + } else { + richtung = ribi_t::suedwest; + } + return richtung; +} ribi_t::ribi @@ -565,7 +605,35 @@ vehikel_basis_t *vehikel_basis_t::no_cars_blocking( const grund_t *gr, const con } - +sint16 +vehikel_t::compare_directions(sint16 first_direction, sint16 second_direction) +{ + //Returns difference between two directions in degrees + sint16 difference = 0; + if(first_direction > 360 || second_direction > 360 || first_direction < 0 || second_direction < 0) return 0; + //If directions > 360, this means that they are not supposed to be checked. + if(first_direction > 180 && second_direction < 180) + { + sint16 tmp = first_direction - second_direction; + if(tmp > 180) difference = 360 - tmp; + else difference = tmp; + } + else if(first_direction < 180 && second_direction > 180) + { + sint16 tmp = second_direction - first_direction; + if(tmp > 180) difference = 360 - tmp; + else difference = tmp; + } + else if(first_direction > second_direction) + { + difference = first_direction - second_direction; + } + else + { + difference = second_direction - first_direction; + } + return difference; +} void vehikel_t::rotate90() @@ -607,7 +675,7 @@ void vehikel_t::set_convoi(convoi_t *c) // some convois were saved with broken coordinates if(!welt->lookup(pos_prev)) { dbg->error("vehikel_t::set_convoi()","pos_prev is illegal of convoi %i at %s", cnv->self.get_id(), get_pos().get_str() ); - if(welt->lookup_kartenboden(pos_prev.get_2d())) { + if(welt->lookup_kartenboden(pos_prev.get_2d())) { //"Kartenboden" = "map ground" (Babelfish) pos_prev = welt->lookup_kartenboden(pos_prev.get_2d())->get_pos(); } else { @@ -709,6 +777,7 @@ bool vehikel_t::load_freight(halthandle_t halt) const uint16 hinein = besch->get_zuladung() - total_freight; ware_t ware = halt->hole_ab(besch->get_ware(), hinein, fpl); + //hinein = inside (Google) if(ware.menge==0) { // now empty, but usually, we can get it here ... return ok; @@ -753,7 +822,7 @@ vehikel_t::set_offsets(int x, int y) /** - * Remove freight that no longer can reach it's destination + * Remove freight that no longer can reach its destination * i.e. becuase of a changed schedule * @author Hj. Malthaner */ @@ -806,7 +875,7 @@ void vehikel_t::remove_stale_freight() void vehikel_t::play_sound() const { - if(besch->get_sound() >= 0) { + if(besch->get_sound() >= 0 && !(welt->is_fast_forward())) { struct sound_info info; info.index = besch->get_sound(); info.volume = 255; @@ -819,6 +888,9 @@ vehikel_t::play_sound() const /** * Bereitet Fahrzeiug auf neue Fahrt vor - wird aufgerufen wenn * der Convoi eine neue Route ermittelt + * + * Fahrzeiug prepares for new journey before - will be called + * if the Convoi a new route determined * @author Hj. Malthaner */ void vehikel_t::neue_fahrt(uint16 start_route_index, bool recalc) @@ -827,7 +899,7 @@ void vehikel_t::neue_fahrt(uint16 start_route_index, bool recalc) check_for_finish = false; use_calc_height = true; - if(welt->ist_in_kartengrenzen(get_pos().get_2d())) { + if(welt->ist_in_kartengrenzen(get_pos().get_2d())) { //"Is in map border" (Babelfish) // mark the region after the image as dirty // better not try to twist your brain to follow the retransformation ... mark_image_dirty( get_bild(), hoff ); @@ -846,7 +918,7 @@ void vehikel_t::neue_fahrt(uint16 start_route_index, bool recalc) pos_prev = get_pos(); set_pos( cnv->get_route()->position_bei(start_route_index) ); - alte_fahrtrichtung = fahrtrichtung; + alte_fahrtrichtung = fahrtrichtung; //1 fahrtrichtung = calc_set_richtung( get_pos().get_2d(), pos_next.get_2d() ); hoff = 0; steps = 0; @@ -855,7 +927,14 @@ void vehikel_t::neue_fahrt(uint16 start_route_index, bool recalc) set_yoff( (dy<0) ? TILE_STEPS/2 : -TILE_STEPS/2 ); calc_bild(); + + if(alte_fahrtrichtung != fahrtrichtung) + { + pre_corner_direction.clear(); + curve_history.clear(); + } } + steps_next = ribi_t::ist_einfach(fahrtrichtung) ? 255 : diagonal_length; } @@ -883,7 +962,7 @@ vehikel_t::vehikel_t(koord3d pos, const vehikel_besch_t* besch, spieler_t* sp) : ist_erstes = ist_letztes = false; check_for_finish = false; use_calc_height = true; - alte_fahrtrichtung = fahrtrichtung = ribi_t::keine; + alte_fahrtrichtung = fahrtrichtung = ribi_t::keine; //I target_halt = halthandle_t(); } @@ -904,7 +983,7 @@ vehikel_t::vehikel_t(karte_t *welt) : ist_erstes = ist_letztes = false; check_for_finish = false; use_calc_height = true; - alte_fahrtrichtung = fahrtrichtung = ribi_t::keine; + alte_fahrtrichtung = fahrtrichtung = ribi_t::keine; //II } @@ -999,12 +1078,13 @@ void vehikel_t::hop() { // Fahrtkosten - cnv->add_running_cost(-besch->get_betriebskosten()); - - verlasse_feld(); + // "Travel costs" (Babelfish) + cnv->add_running_cost(-besch->get_betriebskosten(welt)); + + verlasse_feld(); //"Verlasse" = "leave" (Babelfish) pos_prev = get_pos(); - set_pos( pos_next ); // naechstes Feld + set_pos( pos_next ); // naechstes Feld ("next field" - Babelfish) if(route_indexget_route()->get_max_n()) { route_index ++; pos_next = cnv->get_route()->position_bei(route_index); @@ -1012,9 +1092,9 @@ vehikel_t::hop() else { check_for_finish = true; } - alte_fahrtrichtung = fahrtrichtung; + alte_fahrtrichtung = fahrtrichtung; //2 - // this is a required hack for aircrafts! Aircrafts can turn on a single square, and this confuses the previous calculation! + // this is a required hack for aircraft: aircraft can turn on a single square, and this confuses the previous calculation. // author: hsiegeln if(!check_for_finish && pos_prev.get_2d()==pos_next.get_2d()) { fahrtrichtung = calc_set_richtung( get_pos().get_2d(), pos_next.get_2d() ); @@ -1031,59 +1111,301 @@ vehikel_t::hop() } calc_bild(); - betrete_feld(); - grund_t *gr = welt->lookup(get_pos()); + betrete_feld(); //"Enter field" (Google) + grund_t *gr; + gr = welt->lookup(pos_next); + const weg_t * weg = gr->get_weg(get_waytype()); if(weg) { speed_limit = kmh_to_speed( weg->get_max_speed() ); + // Weight limit needed for GUI flag + uint32 weight_limit = (weg->get_max_weight()); + // Necessary to prevent division by zero exceptions if + // weight limit is set to 0 in the file. + if(weight_limit < 1) + { + weight_limit = 1; + } + is_overweight = (sum_weight > weight_limit); + + curve_history.add_to_tail(alte_fahrtrichtung != fahrtrichtung); + if(alte_fahrtrichtung != fahrtrichtung) + { + pre_corner_direction.add_to_tail(get_direction_degrees(ribi_t::get_dir(alte_fahrtrichtung))); + } + else + { + pre_corner_direction.add_to_tail(999); + } + + speed_limit = calc_modified_speed_limit(&(cnv->get_route()->position_bei(route_index)), fahrtrichtung, (alte_fahrtrichtung != fahrtrichtung)); if(weg->is_crossing()) { gr->find(2)->add_to_crossing(this); - } + } } else { speed_limit = SPEED_UNLIMITED; } + if(check_for_finish & ist_erstes) { if( fahrtrichtung==ribi_t::nord || fahrtrichtung==ribi_t::west ) { steps_next = (steps_next/2)+1; } } - + calc_akt_speed(gr); + + sint8 trim_size = curve_history.get_size() - direction_steps; + curve_history.trim_from_head((trim_size >= 0) ? trim_size : 0); + pre_corner_direction.trim_from_head((trim_size >= 0) ? trim_size : 0); + } +/* Calculates the modified speed limit of the current way, + * taking into account the curve and weight limit. + * @author: jamespetts + */ +uint32 +vehikel_t::calc_modified_speed_limit(const koord3d *position, ribi_t::ribi current_direction, bool is_corner) +{ + grund_t *g; + g = welt->lookup(*position); + waytype_t waytype = get_waytype(); + const weg_t *w = g->get_weg(waytype); + uint32 base_limit; + uint16 weight_limit; + static bool is_tilting = besch->get_tilting(); + if(w != NULL) + { + base_limit = kmh_to_speed(w->get_max_speed()); + weight_limit = w->get_max_weight(); + } + else + { + //Necessary to prevent access violations in some cases of loading saved games. + base_limit = kmh_to_speed(200); + weight_limit = 999; + } + uint32 overweight_speed_limit = base_limit; + uint32 corner_speed_limit = base_limit; + uint32 new_limit = base_limit; + + //Reduce speed for overweight vehicles + + if(sum_weight > weight_limit) + { + if(sum_weight / weight_limit <= 1.1) + { + //Overweight by up to 10% - reduce speed limit to a third. + overweight_speed_limit = base_limit / 3; + } + else if(sum_weight / weight_limit > 1.1) + { + //Overweight by more than 10% - reduce speed limit by a factor of 10. + overweight_speed_limit = base_limit / 10; + } + } + + // Cornering settings. Vehicles must slow to take corners. + static uint32 max_corner_limit = welt->get_einstellungen()->get_max_corner_limit(waytype); + static uint32 min_corner_limit = welt->get_einstellungen()->get_min_corner_limit(waytype); + static float max_corner_adjustment_factor = welt->get_einstellungen()->get_max_corner_adjustment_factor(waytype); + static float min_corner_adjustment_factor = welt->get_einstellungen()->get_min_corner_adjustment_factor(waytype); + static uint8 min_direction_steps = welt->get_einstellungen()->get_min_direction_steps(waytype); + static uint8 max_direction_steps = welt->get_einstellungen()->get_max_direction_steps(waytype); + + if(is_corner) + { + sint16 direction_difference = 0; + sint16 direction = get_direction_degrees(ribi_t::get_dir(current_direction)); + const koord3d *current_tile = position; + const koord3d *previous_tile = &cnv->get_route()->position_bei(route_index - 1); + ribi_t::ribi old_direction = current_direction; + if(previous_tile != NULL) + { + old_direction = calc_check_richtung(previous_tile->get_2d(), position->get_2d()); + } + + float limit_adjustment_factor = 1; + + if(base_limit > max_corner_limit) + { + limit_adjustment_factor = max_corner_adjustment_factor; + direction_steps = max_direction_steps; + } + else if(base_limit < min_corner_limit) + { + limit_adjustment_factor = min_corner_adjustment_factor; + direction_steps = min_direction_steps; + } + else + { + //Smooth the difference + float tmp1 = base_limit - min_corner_limit; + float tmp2 = max_corner_limit - min_corner_limit; + float proportion = tmp1 / tmp2; + limit_adjustment_factor = ((max_corner_adjustment_factor - min_corner_adjustment_factor) * proportion) + min_corner_adjustment_factor; + direction_steps = ((max_direction_steps - min_direction_steps) * proportion) + min_direction_steps; + } + + uint16 tmp; + + for(int i = (curve_history.get_size() >= direction_steps) ? direction_steps - 1 : curve_history.get_size() - 1; i > 0; i --) + { + tmp = vehikel_t::compare_directions(direction, pre_corner_direction.get_element(i)); + if(tmp > direction_difference) + { + direction_difference = tmp; + } + } + + if(direction_difference == 0 && current_direction != old_direction) + { + //Fallback code in case the checking the histories did not work properly (for example, if the histories were cleared recently) + direction_difference = compare_directions(get_direction_degrees(ribi_t::get_dir(current_direction)), get_direction_degrees(ribi_t::get_dir(old_direction))); + } + + //Smoothing code: slightly smoothed corners benefit. + if(direction_difference > compare_directions(direction, get_direction_degrees(ribi_t::get_dir(old_direction)) && limit_adjustment_factor < 0.8)) + { + limit_adjustment_factor += 0.15; + if(limit_adjustment_factor >= 1) + { + //But there is a limit to the benefit of smoothness. + limit_adjustment_factor = 0.97; + } + } + + //Tilting only makes a difference on faster track and on smoothed corners. + if(is_tilting && base_limit > kmh_to_speed(160) && compare_directions(direction, get_direction_degrees(ribi_t::get_dir(old_direction)) <= 45)) + { + // Tilting trains can take corners faster + limit_adjustment_factor += 0.30; + if(limit_adjustment_factor > 1) + { + //But cannot go faster on a corner than on the straight! + limit_adjustment_factor = 1; + } + } + + switch(direction_difference) + { + case 0 : + + //If we are here, there *must* be a curve, since we have already checked that. + //If this is 0, this is an error, and we will assume a 45 degree bend. + corner_speed_limit = (base_limit * limit_adjustment_factor); + break; + + case 45 : + + corner_speed_limit = (base_limit * limit_adjustment_factor); + break; + + case 90 : + corner_speed_limit = (base_limit * (limit_adjustment_factor * 0.5)); + break; + + case 135 : + + corner_speed_limit = (base_limit * (limit_adjustment_factor * 0.35)); + break; + + case 180 : + + corner_speed_limit = (base_limit * (limit_adjustment_factor * 0.25)); + break; + + default : + //treat as 45 degree bend if something has gone wrong in the calculations. + //There *must* be a curve here, as the original bool flag was triggered. + corner_speed_limit = (base_limit * limit_adjustment_factor); + } + + } + + //Overweight penalty not to be made cumulative to cornering penalty + + if(corner_speed_limit < overweight_speed_limit) + { + new_limit = corner_speed_limit; + } + else + { + new_limit = overweight_speed_limit; + } + + //Speed limit must never be 0. + if(new_limit > 0) + { + return new_limit; + } + else + { + return kmh_to_speed(10); + } +} /* calculates the current friction coefficient based on the curent track - * falt, slope, curve ... + * flat, slope, (curve)... * @author prissi, HJ */ void vehikel_t::calc_akt_speed(const grund_t *gr) //,const int h_alt, const int h_neu) { - // assume straigth flat track + // assume straight flat track current_friction = 1; + + //The level (if any) of additional friction to apply around corners. + waytype_t waytype = get_waytype(); + static uint8 curve_friction_factor = welt->get_einstellungen()->get_curve_friction_factor(waytype); + // Old method - not realistic. Now uses modified speed limit. Preserved optionally. // curve: higher friction - if(alte_fahrtrichtung != fahrtrichtung) { - current_friction = 8; + if(alte_fahrtrichtung != fahrtrichtung) { //"Old direction != direction" + current_friction += curve_friction_factor; } // or a hill? + // Cumulative drag for hills: @author: jamespetts const hang_t::typ hang = gr->get_weg_hang(); + hill[2] = hill[1]; + hill[1] = hill[0]; if(hang!=hang_t::flach) { - if(ribi_typ(hang)==fahrtrichtung) { + hill[0] = (ribi_typ(hang)==fahrtrichtung); + if(hill[0]) + { // hill up, since height offsets are negative: heavy deccelerate - current_friction += 23; + + if(!hill[1]) + { + //No hill last tile, minimal friction increase. + current_friction += 18; + } + else if(hill[1] && !hill[2]) + { + //Hill last tile, but not the tile before. Moderate friction increase. + current_friction += 25; + } + else if(hill[1] && hill[2]) + { + //Hill last two tiles. Maximum friction increase. + current_friction += 32; + } } else { // hill down: accelrate current_friction += -13; } } + else + { + hill[0] = false; + } - if(ist_erstes) { + if(ist_erstes) { //"Is the first" (Google) uint32 akt_speed = speed_limit; uint32 tiles_left = cnv->get_next_stop_index()+1-route_index; @@ -1113,7 +1435,29 @@ vehikel_t::calc_akt_speed(const grund_t *gr) //,const int h_alt, const int h_neu } } - +vehikel_t::direction_degrees vehikel_t::get_direction_degrees(ribi_t::dir direction) +{ + switch(direction) + { + case ribi_t::dir_nord : + return vehikel_t::North; + case ribi_t::dir_nordost : + return vehikel_t::Northeast; + case ribi_t::dir_ost : + return vehikel_t::East; + case ribi_t::dir_suedost : + return vehikel_t::Southeast; + case ribi_t::dir_sued : + return vehikel_t::South; + case ribi_t::dir_suedwest : + return vehikel_t::Southwest; + case ribi_t::dir_west : + return vehikel_t::West; + case ribi_t::dir_nordwest : + return vehikel_t::Northwest; + }; + return vehikel_t::North; +} void vehikel_t::rauche() @@ -1159,8 +1503,16 @@ vehikel_t::rauche() * @return income total for last hop * @author Hj. Malthaner */ -sint64 vehikel_t::calc_gewinn(koord start, koord end) const +sint64 vehikel_t::calc_gewinn(koord start, koord end, convoi_t *cnv) const { + //According to Google translations: + //Calculate profit ("gewinn") + //"Menge" = "volume" + //"zwischenziel" = "Between target" + //"Fracht" = "Freight" + //"Grundwert" = "Fundamental value" + //"Preis" = "Price" + // may happen when waiting in station if(start==end || fracht.count()==0) { return 0; @@ -1174,69 +1526,71 @@ sint64 vehikel_t::calc_gewinn(koord start, koord end) const slist_tpl kill_queue; slist_iterator_tpl iter (fracht); - if( welt->get_einstellungen()->get_pay_for_total_distance_mode()==einstellungen_t::TO_DESTINATION ) { - // pay only the distance, we get closer to our destination - while( iter.next() ) { - - const ware_t & ware = iter.get_current(); - - if( ware.menge==0 ) { - continue; - } - - // now only use the real gain in difference for the revenue (may as well be negative!) - const koord &zwpos = ware.get_zielpos(); - const long dist = abs(zwpos.x - start.x) + abs(zwpos.y - start.y) - (abs(end.x - zwpos.x) + abs(end.y - zwpos.y)); + while( iter.next() ) { - const sint32 grundwert128 = ware.get_besch()->get_preis()<<7; // bonus price will be always at least 0.128 of the real price - const sint32 grundwert_bonus = (ware.get_besch()->get_preis()*(1000+speed_base*ware.get_besch()->get_speed_bonus())); - const sint64 price = (sint64)(grundwert128>grundwert_bonus ? grundwert128 : grundwert_bonus) * (sint64)dist * (sint64)ware.menge; + const ware_t &ware = iter.get_current(); - // sum up new price - value += price; + if(ware.menge==0 || !ware.get_zwischenziel().is_bound()) { + continue; } - } - else if( welt->get_einstellungen()->get_pay_for_total_distance_mode()==einstellungen_t::TO_TRANSFER ) { - // pay distance traveled to next trasnfer stop - while( iter.next() ) { - const ware_t & ware = iter.get_current(); + // now only use the real gain in difference for the revenue (may as well be negative!) + const koord zwpos = ware.get_zwischenziel()->get_basis_pos(); + const long dist = abs(zwpos.x - start.x) + abs(zwpos.y - start.y) - (abs(end.x - zwpos.x) + abs(end.y - zwpos.y)); - if(ware.menge==0 || !ware.get_zwischenziel().is_bound()) { - continue; - } + const ware_besch_t* goods = ware.get_besch(); + const sint32 grundwert128 = goods->get_preis()<<7; - // now only use the real gain in difference for the revenue (may as well be negative!) - const koord zwpos = ware.get_zwischenziel()->get_basis_pos(); - const long dist = abs(zwpos.x - start.x) + abs(zwpos.y - start.y) - (abs(end.x - zwpos.x) + abs(end.y - zwpos.y)); + + /* Calculates the speed bonus, taking into account: ( + * (1) the local bonus; and + * (2) the speed bonus distance settings. + * @author: jamespetts + */ - const sint32 grundwert128 = ware.get_besch()->get_preis()<<7; // bonus price will be always at least 0.128 of the real price - const sint32 grundwert_bonus = (ware.get_besch()->get_preis()*(1000+speed_base*ware.get_besch()->get_speed_bonus())); - const sint64 price = (sint64)(grundwert128>grundwert_bonus ? grundwert128 : grundwert_bonus) * (sint64)dist * (sint64)ware.menge; + const uint16 base_bonus = goods->get_speed_bonus(); + uint16 adjusted_bonus = 0; + local_bonus_supplement = (welt->get_einstellungen()->get_local_bonus_multiplier() / 100) * base_bonus; + + if(dist <= welt->get_einstellungen()->get_min_bonus_max_distance()) + { + //If distance of journey too low, disapply speed bonus entirely, but apply local bonus supplement instead. + adjusted_bonus = local_bonus_supplement; + } + + else if(dist > welt->get_einstellungen()->get_min_bonus_max_distance() && dist < welt->get_einstellungen()->get_max_bonus_min_distance()) + { + //Apply proportionate mix of local bonus supplement and conventional speed bonus. + //The effect of this code is that, if the local supplement is set to 1, a 100% speed bonus is applied until max_bonus_min_distance is reached. + //For that reason, it is better not to set local supplement to 1. + float tmp = (welt->get_einstellungen()->get_max_bonus_min_distance() - welt->get_einstellungen()->get_min_bonus_max_distance()); + float proportion_distance = dist / tmp; + uint16 intermediate_bonus = base_bonus * proportion_distance; + uint16 intermediate_local_supplement = local_bonus_supplement * (1 / proportion_distance); + adjusted_bonus = intermediate_bonus + intermediate_local_supplement; + } - // sum up new price - value += price; + else if(dist >= welt->get_einstellungen()->get_max_bonus_min_distance()) + { + //Apply full speed bonus in conventional way. + adjusted_bonus = base_bonus; } - } - else { - // pay distance traveled - const long dist = abs_distance( start, end ); - while( iter.next() ) { - const ware_t & ware = iter.get_current(); + //const sint32 grundwert128 = ware.get_besch()->get_preis()<<7; // bonus price will be always at least 0.128 of the real price + const sint32 grundwert_bonus = (ware.get_besch()->get_preis()*(1000 + speed_base * adjusted_bonus)); + sint64 price = (sint64)(grundwert128>grundwert_bonus ? grundwert128 : grundwert_bonus) * (sint64)dist * (sint64)ware.menge; - if(ware.menge==0 || !ware.get_zwischenziel().is_bound()) { - continue; - } + //Apply the catering bonus, if applicable. + if(cnv->get_catering_level(ware.get_besch()->get_catg_index()) > 0) + { + float catering_bonus = 1; + //TODO: Add code for calculating catering bonus + value *= catering_bonus; + } - // now only use the real gain in difference for the revenue (may as well be negative!) - const sint32 grundwert128 = ware.get_besch()->get_preis()<<7; // bonus price will be always at least 0.128 of the real price - const sint32 grundwert_bonus = (ware.get_besch()->get_preis()*(1000+speed_base*ware.get_besch()->get_speed_bonus())); - const sint64 price = (sint64)(grundwert128>grundwert_bonus ? grundwert128 : grundwert_bonus) * (sint64)dist * (sint64)ware.menge; - // sum up new price - value += price; - } + // sum up new price + value += price; } // Hajo: Rounded value, in cents @@ -1253,6 +1607,7 @@ const char *vehikel_t::get_fracht_mass() const /** * Berechnet Gesamtgewicht der transportierten Fracht in KG + * "Calculated total weight of cargo transported in KG" (Translated by Google) * @author Hj. Malthaner */ uint32 vehikel_t::get_fracht_gewicht() const @@ -1329,6 +1684,7 @@ vehikel_t::beladen(koord , halthandle_t halt) /** * fahrzeug an haltestelle entladen + * "Vehicle to stop discharged" (translated by Google) * @author Hj. Malthaner */ bool vehikel_t::entladen(koord, halthandle_t halt) @@ -1348,6 +1704,7 @@ bool vehikel_t::entladen(koord, halthandle_t halt) /** * Ermittelt fahrtrichtung + * "Determined Direction" (translated by Google) * @author Hj. Malthaner */ ribi_t::ribi vehikel_t::richtung() @@ -1359,7 +1716,7 @@ ribi_t::ribi vehikel_t::richtung() void -vehikel_t::calc_bild() +vehikel_t::calc_bild() //"Bild" = "picture" (Google) { image_id old_bild=get_bild(); if (fracht.empty()) { @@ -1409,6 +1766,7 @@ void vehikel_t::rdwr_from_convoi(loadsave_t *file) if(file->get_version()<86006) { // parameter werden in der deklarierten reihenfolge gespeichert + // "Parameters are declared in the order saved" (Translated by Google) sint32 l; file->rdwr_long(insta_zeit, "\n"); file->rdwr_long(l, " "); @@ -1608,7 +1966,22 @@ void vehikel_t::info(cbuffer_t & buf) const const char * vehikel_t::ist_entfernbar(const spieler_t *) { - return "Fahrzeuge koennen so nicht entfernt werden"; + return "Vehicles cannot be removed"; +} + +bool vehikel_t::check_way_constraints(const weg_t *way) const +{ + // Permissive way constraints + // If vehicle has it, way must have it. + uint8 or = besch->get_permissive_constraints() | way->get_way_constraints_permissive(); + bool permissive = way->get_way_constraints_permissive() ^ or; + + // Prohibitive way constraints + // If way has it, vehicle must have it. + or = besch->get_prohibitive_constraints() | way->get_way_constraints_prohibitive(); + bool prohibitive = besch->get_prohibitive_constraints() ^ or; + + return (!permissive) && (!prohibitive); } @@ -1644,6 +2017,12 @@ vehikel_t::display_after(int xpos, int ypos, bool is_gobal) const color = COL_RED; break; } + if(is_overweight) + { + sprintf(tooltip_text, translator::translate("Vehicle %s is too heavy for this route: speed limited."), cnv->get_name()); + color = COL_YELLOW; + } + // something to show? if(tooltip_text[0]) { @@ -1661,6 +2040,7 @@ vehikel_t::display_after(int xpos, int ypos, bool is_gobal) const /*--------------------------- Fahrdings ------------------------------*/ +//(Translated by Babelfish as "driving thing") automobil_t::automobil_t(koord3d pos, const vehikel_besch_t* besch, spieler_t* sp, convoi_t* cn) : @@ -1711,7 +2091,7 @@ bool automobil_t::calc_route(koord3d start, koord3d ziel, uint32 max_speed, rout // free target reservation if(ist_erstes && alte_fahrtrichtung!=ribi_t::keine && cnv && target_halt.is_bound() ) { route_t *rt=cnv->get_route(); - grund_t *target=welt->lookup(rt->position_bei(rt->get_max_n())); + grund_t *target=welt->lookup(rt->position_bei(rt->get_max_n())); //"bei" = "at" (Google) if(target) { target_halt->unreserve_position(target,cnv->self); } @@ -1745,7 +2125,8 @@ bool automobil_t::ist_befahrbar(const grund_t *bd) const } } } - return true; + const strasse_t* way = str; + return check_way_constraints(way); } @@ -1776,6 +2157,15 @@ automobil_t::get_kosten(const grund_t *gr,const uint32 max_speed) const // thus just add whenever there is a slope ... (counts as nearly 2 standard tiles) costs += 15; } + + //@author: jamespetts + // Strongly prefer routes for which the vehicle is not overweight. + uint16 weight_limit = w->get_max_weight(); + if(vehikel_t::get_gesamtgewicht() > weight_limit) + { + costs += 40; + } + return costs; } @@ -2051,7 +2441,7 @@ waggon_t::waggon_t(karte_t *welt, loadsave_t *file, bool is_first, bool is_last) if(is_first) { last_besch = NULL; } - // try to find a matching vehivle + // try to find a matching vehicle if(besch==NULL) { int power = (is_first || fracht.empty() || fracht.front() == warenbauer_t::nichts) ? 500 : 0; const ware_besch_t* w = fracht.empty() ? warenbauer_t::nichts : fracht.front().get_besch(); @@ -2200,7 +2590,7 @@ waggon_t::ist_befahrbar(const grund_t *bd) const const bool needs_no_electric = !(cnv!=NULL ? cnv->needs_electrification() : besch->get_engine_type()==vehikel_besch_t::electric); bool ok = (sch!=0) && (needs_no_electric || sch->is_electrified()); - if(!ok || !target_halt.is_bound() || !cnv->is_waiting()) { + if(!ok || !target_halt.is_bound() || !cnv->is_waiting() || !check_way_constraints(sch)) { return ok; } else { @@ -2242,6 +2632,14 @@ waggon_t::get_kosten(const grund_t *gr,const uint32 max_speed) const costs += 25; } + //@author: jamespetts + // Strongly prefer routes for which the vehicle is not overweight. + uint16 weight_limit = w->get_max_weight(); + if(vehikel_t::get_gesamtgewicht() > weight_limit) + { + costs += 40; + } + return costs; } @@ -2742,7 +3140,11 @@ schiff_t::schiff_t(karte_t *welt, loadsave_t *file, bool is_first, bool is_last) bool schiff_t::ist_befahrbar(const grund_t *bd) const { - return bd->ist_wasser() || bd->hat_weg(water_wt); + if( bd->ist_wasser() ) { + return true; + } + const weg_t *w = bd->get_weg(water_wt); + return (w && w->get_max_speed()>0); } diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index ddd0163af37..115f6e0010c 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -16,6 +16,7 @@ #define _simvehikel_h #include "../simtypes.h" +#include "../simworld.h" #include "../simdings.h" #include "../halthandle_t.h" #include "../convoihandle_t.h" @@ -26,6 +27,8 @@ #include "../vehicle/overtaker.h" #include "../tpl/slist_tpl.h" +#include "../tpl/fixed_list_tpl.h" + class convoi_t; class schedule_t; class signal_t; @@ -98,6 +101,7 @@ class vehikel_basis_t : public ding_t // only needed for old way of moving vehicles to determine position at loading time bool is_about_to_hop( const sint8 neu_xoff, const sint8 neu_yoff ) const; + public: // only called during load time: set some offsets static void set_diagonal_multiplier( uint32 multiplier, uint32 old_multiplier ); @@ -120,6 +124,7 @@ class vehikel_basis_t : public ding_t ribi_t::ribi calc_richtung(koord start, koord ende) const; ribi_t::ribi calc_set_richtung(koord start, koord ende); + ribi_t::ribi calc_check_richtung(koord start, koord ende); ribi_t::ribi get_fahrtrichtung() const {return fahrtrichtung;} @@ -172,6 +177,10 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t */ virtual void calc_akt_speed(const grund_t *gr); + uint32 calc_modified_speed_limit(const koord3d *position, ribi_t::ribi current_direction, bool is_corner); + + uint32 smooth_speed(uint32 current_limit); + /** * Unload freight to halt * @return sum of unloaded goods @@ -191,9 +200,16 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t // current limit (due to track etc.) uint32 speed_limit; + //uint32 weight_limit; ribi_t::ribi alte_fahrtrichtung; + //sint16 pre_corner_direction[16]; + + //uint16 target_speed[16]; + + //const koord3d *lookahead[16]; + // for target reservation and search halthandle_t target_halt; @@ -209,7 +225,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t uint16 route_index; uint16 total_freight; // since the sum is needed quite often, it is chached - slist_tpl fracht; // liste der gerade transportierten güter + slist_tpl fracht; // liste der gerade transportierten güter ("list of goods being transported" - Google) const vehikel_besch_t *besch; @@ -230,6 +246,8 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t virtual bool ist_befahrbar(const grund_t* ) const {return false;} + bool vehikel_t::check_way_constraints(const weg_t *way) const; + public: // the coordinates, where the vehicle was loaded the last time koord last_stop_pos; @@ -283,6 +301,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t * @author Hj. Malthaner */ int get_betriebskosten() const { return besch->get_betriebskosten(); } + int get_betriebskosten(static karte_t* welt) const { return besch->get_betriebskosten(welt); } /** * spielt den Sound, wenn das Vehikel sichtbar ist @@ -366,6 +385,24 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t */ void get_fracht_info(cbuffer_t & buf); + // Check for straightness of way. + //@author jamespetts + + static enum direction_degrees { + North = 360, + Northeast = 45, + East = 90, + Southeast = 135, + South = 180, + Southwest = 225, + West = 270, + Northwest = 315, + }; + + direction_degrees get_direction_degrees(ribi_t::ribi); + + sint16 vehikel_t::compare_directions(sint16 first_direction, sint16 second_direction); + /** * loescht alle fracht aus dem Fahrzeug * @author Hj. Malthaner @@ -379,7 +416,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t * @return income total for last hop * @author Hj. Malthaner */ - sint64 calc_gewinn(koord start, koord end) const; + sint64 calc_gewinn(koord start, koord end, convoi_t* cnv) const; /** * fahrzeug an haltestelle entladen @@ -426,6 +463,8 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t // this draws a tooltips for things stucked on depot order or lost virtual void display_after(int xpos, int ypos, bool dirty) const; + + }; @@ -602,6 +641,8 @@ class schiff_t : public vehikel_t void calc_akt_speed(const grund_t *gr); + //uint32 calc_modified_speed_limit(const weg_t *w, uint8 s, ribi_t::ribi current_direction) { return base_limit; } //Ships do not modify speed limits. + bool ist_befahrbar(const grund_t *bd) const; public: @@ -618,6 +659,7 @@ class schiff_t : public vehikel_t ding_t::typ get_typ() const { return schiff; } schedule_t * erzeuge_neuen_fahrplan() const; + }; @@ -711,6 +753,8 @@ class aircraft_t : public vehikel_t // the speed calculation happens it calc_height void calc_akt_speed(const grund_t*) {} + + //uint32 calc_modified_speed_limit(const weg_t *w, uint32 base_limit, uint8 s, ribi_t::ribi current_direction) { return base_limit; } }; #endif diff --git a/vehicle/simverkehr.cc b/vehicle/simverkehr.cc index da554ff15b3..57a9cdb995f 100644 --- a/vehicle/simverkehr.cc +++ b/vehicle/simverkehr.cc @@ -3,6 +3,11 @@ * Transportfahrzeuge sind in simvehikel.h definiert, da sie sich * stark von den hier definierten Fahrzeugen fuer den Individualverkehr * unterscheiden. + * + * Mobile objects for Simutrans. + * Transport vehicles are defined in simvehikel.h, since they differ + * strongly from the vehicles defined here more for the individual traffic. + * (Babelfish) * * Hj. Malthaner * @@ -21,7 +26,7 @@ #include "simverkehr.h" #ifdef DESTINATION_CITYCARS -// for final citcar destinations +// for final citycar destinations #include "simpeople.h" #endif @@ -34,6 +39,7 @@ #include "../boden/grund.h" #include "../boden/wege/weg.h" +#include "../boden/wege/strasse.h" #include "../besch/stadtauto_besch.h" #include "../besch/roadsign_besch.h" @@ -370,7 +376,21 @@ bool stadtauto_t::list_empty() stadtauto_t::~stadtauto_t() { + if(!welt->get_is_shutting_down() && current_list != NULL && current_list->count() > 0) + { + stadtauto_t *tmp = this; + if(!current_list->remove(tmp)) + { + DBG_MESSAGE("stadtauto_t", "Failure to remove city car from list!"); + } + else + { + DBG_MESSAGE("stadtauto_t", "Succeeded in removing city car from list."); + } + + } welt->buche( -1, karte_t::WORLD_CITYCARS ); + //"Buche" = "Books" (Babelfish) } @@ -378,6 +398,13 @@ stadtauto_t::stadtauto_t(karte_t *welt, loadsave_t *file) : verkehrsteilnehmer_t(welt) { rdwr(file); + + //No provision for saving the destinations yet. + target = koord::invalid; + + current_list = &welt->unassigned_cars; + welt->add_unassigned_car(this); + ms_traffic_jam = 0; if(besch) { welt->sync_add(this); @@ -387,7 +414,7 @@ stadtauto_t::stadtauto_t(karte_t *welt, loadsave_t *file) #ifdef DESTINATION_CITYCARS -stadtauto_t::stadtauto_t(karte_t *welt, koord3d pos, koord target) +stadtauto_t::stadtauto_t(karte_t *welt, koord3d pos, koord target, slist_tpl* car_list) #else stadtauto_t::stadtauto_t(karte_t *welt, koord3d pos, koord ) #endif @@ -406,6 +433,7 @@ stadtauto_t::stadtauto_t(karte_t *welt, koord3d pos, koord ) #endif calc_bild(); welt->buche( +1, karte_t::WORLD_CITYCARS ); + current_list = car_list; } @@ -434,7 +462,7 @@ stadtauto_t::sync_step(long delta_t) else { if(ms_traffic_jam>welt->ticks_per_tag && old_ms_traffic_jam<=welt->ticks_per_tag) { // message after two month, reset waiting timer - welt->get_message()->add_message( translator::translate("To heavy traffic\nresults in traffic jam.\n"), get_pos().get_2d(), message_t::warnings, COL_ORANGE ); + welt->get_message()->add_message( translator::translate("Excess traffic \nresults in traffic jams.\n"), get_pos().get_2d(), message_t::warnings, COL_ORANGE ); } } } @@ -484,6 +512,7 @@ void stadtauto_t::rdwr(loadsave_t *file) if(file->get_version() <= 86001) { time_to_life = simrand(1000000)+10000; + } else if(file->get_version() <= 89004) { file->rdwr_long(time_to_life, "\n"); @@ -520,11 +549,12 @@ void stadtauto_t::rdwr(loadsave_t *file) // do not start with zero speed! current_speed ++; + } -bool stadtauto_t::ist_weg_frei(grund_t *gr) +bool stadtauto_t::ist_weg_frei(const grund_t *gr) //Frie = "freely" (Babelfish) { if(gr->get_top()>200) { // already too many things here @@ -659,10 +689,13 @@ void stadtauto_t::betrete_feld() { #ifdef DESTINATION_CITYCARS + // Destination city car code revived from an older version of Simutrans. + // (Thanks to Prissi for finding this older code). if(target!=koord::invalid && abs_distance(pos_next.get_2d(),target)<10) { // delete it ... time_to_life = 0; + //"fussgaenger" = pedestrian (Babelfish) fussgaenger_t *fg = new fussgaenger_t(welt, pos_next); bool ok = welt->lookup(pos_next)->obj_add(fg) != 0; for(int i=0; i<(fussgaenger_t::count & 3); i++) { @@ -676,10 +709,17 @@ stadtauto_t::betrete_feld() } +void +stadtauto_t::kill() +{ + time_to_life = 0; +} + bool stadtauto_t::hop_check() { + // V.Meyer: weg_position_t changed to grund_t::get_neighbour() grund_t *from = welt->lookup(pos_next); if(from==NULL) { @@ -770,8 +810,9 @@ stadtauto_t::hop_check() } return true; } + else { - pos_next_next == koord3d::invalid; + pos_next_next = koord3d::invalid; } #endif } @@ -873,7 +914,15 @@ void stadtauto_t::calc_current_speed() { const weg_t * weg = welt->lookup(get_pos())->get_weg(road_wt); - const uint16 max_speed = besch->get_geschw(); + uint16 max_speed; + if(besch != NULL) + { + max_speed = besch->get_geschw(); + } + else + { + max_speed = kmh_to_speed(90); + } const uint16 speed_limit = weg ? kmh_to_speed(weg->get_max_speed()) : max_speed; current_speed += max_speed>>2; if(current_speed > max_speed) { @@ -912,8 +961,6 @@ void stadtauto_t::get_screen_offset( int &xoff, int &yoff ) const } } - - /** * conditions for a city car to overtake another overtaker. * The city car is not overtaking/being overtaken. diff --git a/vehicle/simverkehr.h b/vehicle/simverkehr.h index d19799d2c21..39488d717cf 100644 --- a/vehicle/simverkehr.h +++ b/vehicle/simverkehr.h @@ -15,8 +15,12 @@ #include "simvehikel.h" #include "overtaker.h" +#include "../tpl/slist_tpl.h" #include "../tpl/stringhashtable_tpl.h" #include "../ifc/sync_steppable.h" +//#include "../slisthandle_t.h" + +#define DESTINATION_CITYCARS class stadtauto_besch_t; class karte_t; @@ -24,6 +28,7 @@ class karte_t; /** * Base class for traffic participants with random movement * @author Hj. Malthaner + * "verkehrsteilnehmer" = road user (Babelfish) */ class verkehrsteilnehmer_t : public vehikel_basis_t, public sync_steppable { @@ -66,16 +71,23 @@ class verkehrsteilnehmer_t : public vehikel_basis_t, public sync_steppable // we allow to remove all cars etc. const char *ist_entfernbar(const spieler_t *) { return NULL; } + }; class stadtauto_t : public verkehrsteilnehmer_t, public overtaker_t { private: + + slist_tpl * current_list; + static stringhashtable_tpl table; const stadtauto_besch_t *besch; + route_t route; + uint16 route_index; + // prissi: time to life in blocks #ifdef DESTINATION_CITYCARS koord target; @@ -91,7 +103,8 @@ class stadtauto_t : public verkehrsteilnehmer_t, public overtaker_t uint32 ms_traffic_jam; bool hop_check(); - bool ist_weg_frei(grund_t *gr); + bool ist_weg_frei(const grund_t *gr); + bool calc_route(const koord3d ziel, const koord3d start); protected: void rdwr(loadsave_t *file); @@ -100,7 +113,7 @@ class stadtauto_t : public verkehrsteilnehmer_t, public overtaker_t public: stadtauto_t(karte_t *welt, loadsave_t *file); - stadtauto_t(karte_t *welt, koord3d pos, koord target); + stadtauto_t(karte_t *welt, koord3d pos, koord target, slist_tpl* car_list); virtual ~stadtauto_t(); @@ -110,6 +123,9 @@ class stadtauto_t : public verkehrsteilnehmer_t, public overtaker_t void hop(); + //Gets rid of the car by setting its life to 0. + void kill(); + void betrete_feld(); void calc_current_speed(); @@ -145,6 +161,10 @@ class stadtauto_t : public verkehrsteilnehmer_t, public overtaker_t // Overtaking for city cars virtual bool can_overtake(overtaker_t *other_overtaker, int other_speed, int steps_other, int diagonal_length); + + // Sets the list in which the vehicle is referenced, so that + // it can be removed from the list when it is deleted. + void set_list(slist_tpl *this_list) { current_list = this_list; } }; #endif From ef799f5093f670037123919a0bb6af45ddfe6377 Mon Sep 17 00:00:00 2001 From: "James E. Petts" Date: Sat, 31 Jan 2009 00:46:01 +0000 Subject: [PATCH 02/61] Additional files not automatically included in the first simutrans-experimental release --- Simutrans-Experimental.vcproj | 1110 +++++ besch/vehikel_besch.cc | 27 + makeobj/Makeobj.sln | 20 + makeobj/Makeobj.vcproj | 506 ++ tpl/fixed_list_tpl.h | 431 ++ utils/openttd/freetype/config/ftconfig.h | 415 ++ utils/openttd/freetype/config/ftheader.h | 768 +++ utils/openttd/freetype/config/ftmodule.h | 32 + utils/openttd/freetype/config/ftoption.h | 671 +++ utils/openttd/freetype/config/ftstdlib.h | 180 + utils/openttd/freetype/freetype.h | 3716 +++++++++++++++ utils/openttd/freetype/ftbbox.h | 94 + utils/openttd/freetype/ftbdf.h | 201 + utils/openttd/freetype/ftbitmap.h | 206 + utils/openttd/freetype/ftcache.h | 1121 +++++ utils/openttd/freetype/ftchapters.h | 102 + utils/openttd/freetype/ftcid.h | 98 + utils/openttd/freetype/fterrdef.h | 239 + utils/openttd/freetype/fterrors.h | 206 + utils/openttd/freetype/ftgasp.h | 113 + utils/openttd/freetype/ftglyph.h | 575 +++ utils/openttd/freetype/ftgxval.h | 358 ++ utils/openttd/freetype/ftgzip.h | 102 + utils/openttd/freetype/ftimage.h | 1253 +++++ utils/openttd/freetype/ftincrem.h | 349 ++ utils/openttd/freetype/ftlcdfil.h | 166 + utils/openttd/freetype/ftlist.h | 273 ++ utils/openttd/freetype/ftlzw.h | 99 + utils/openttd/freetype/ftmac.h | 274 ++ utils/openttd/freetype/ftmm.h | 378 ++ utils/openttd/freetype/ftmodapi.h | 441 ++ utils/openttd/freetype/ftmoderr.h | 155 + utils/openttd/freetype/ftotval.h | 203 + utils/openttd/freetype/ftoutln.h | 536 +++ utils/openttd/freetype/ftpfr.h | 172 + utils/openttd/freetype/ftrender.h | 234 + utils/openttd/freetype/ftsizes.h | 159 + utils/openttd/freetype/ftsnames.h | 170 + utils/openttd/freetype/ftstroke.h | 716 +++ utils/openttd/freetype/ftsynth.h | 73 + utils/openttd/freetype/ftsystem.h | 346 ++ utils/openttd/freetype/fttrigon.h | 350 ++ utils/openttd/freetype/fttypes.h | 587 +++ utils/openttd/freetype/ftwinfnt.h | 274 ++ utils/openttd/freetype/ftxf86.h | 80 + utils/openttd/freetype/internal/autohint.h | 205 + utils/openttd/freetype/internal/ftcalc.h | 178 + utils/openttd/freetype/internal/ftdebug.h | 250 + utils/openttd/freetype/internal/ftdriver.h | 248 + utils/openttd/freetype/internal/ftgloadr.h | 168 + utils/openttd/freetype/internal/ftmemory.h | 368 ++ utils/openttd/freetype/internal/ftobjs.h | 875 ++++ utils/openttd/freetype/internal/ftrfork.h | 196 + utils/openttd/freetype/internal/ftserv.h | 328 ++ utils/openttd/freetype/internal/ftstream.h | 539 +++ utils/openttd/freetype/internal/fttrace.h | 134 + utils/openttd/freetype/internal/ftvalid.h | 150 + utils/openttd/freetype/internal/internal.h | 50 + utils/openttd/freetype/internal/pcftypes.h | 56 + utils/openttd/freetype/internal/psaux.h | 871 ++++ utils/openttd/freetype/internal/pshints.h | 687 +++ .../freetype/internal/services/svbdf.h | 57 + .../freetype/internal/services/svcid.h | 49 + .../freetype/internal/services/svgldict.h | 60 + .../freetype/internal/services/svgxval.h | 72 + .../freetype/internal/services/svkern.h | 51 + .../openttd/freetype/internal/services/svmm.h | 79 + .../freetype/internal/services/svotval.h | 55 + .../freetype/internal/services/svpfr.h | 66 + .../freetype/internal/services/svpostnm.h | 58 + .../freetype/internal/services/svpscmap.h | 129 + .../freetype/internal/services/svpsinfo.h | 60 + .../freetype/internal/services/svsfnt.h | 80 + .../freetype/internal/services/svttcmap.h | 78 + .../freetype/internal/services/svtteng.h | 53 + .../freetype/internal/services/svttglyf.h | 48 + .../freetype/internal/services/svwinfnt.h | 50 + .../freetype/internal/services/svxf86nm.h | 55 + utils/openttd/freetype/internal/sfnt.h | 762 +++ utils/openttd/freetype/internal/t1types.h | 252 + utils/openttd/freetype/internal/tttypes.h | 1543 ++++++ utils/openttd/freetype/t1tables.h | 504 ++ utils/openttd/freetype/ttnameid.h | 1146 +++++ utils/openttd/freetype/tttables.h | 756 +++ utils/openttd/freetype/tttags.h | 100 + utils/openttd/freetype/ttunpat.h | 59 + utils/openttd/ft2build.h | 39 + utils/openttd/png.h | 3592 ++++++++++++++ utils/openttd/pngconf.h | 1481 ++++++ utils/openttd/unicode/brkiter.h | 557 +++ utils/openttd/unicode/caniter.h | 201 + utils/openttd/unicode/chariter.h | 716 +++ utils/openttd/unicode/dbbi.h | 41 + utils/openttd/unicode/docmain.h | 202 + utils/openttd/unicode/locid.h | 765 +++ utils/openttd/unicode/normlzr.h | 823 ++++ utils/openttd/unicode/parseerr.h | 92 + utils/openttd/unicode/parsepos.h | 230 + utils/openttd/unicode/putil.h | 184 + utils/openttd/unicode/pwin32.h | 311 ++ utils/openttd/unicode/rbbi.h | 700 +++ utils/openttd/unicode/rep.h | 259 + utils/openttd/unicode/resbund.h | 485 ++ utils/openttd/unicode/schriter.h | 187 + utils/openttd/unicode/strenum.h | 271 ++ utils/openttd/unicode/symtable.h | 112 + utils/openttd/unicode/ubidi.h | 2013 ++++++++ utils/openttd/unicode/ubrk.h | 482 ++ utils/openttd/unicode/ucasemap.h | 395 ++ utils/openttd/unicode/ucat.h | 158 + utils/openttd/unicode/uchar.h | 3062 ++++++++++++ utils/openttd/unicode/uchriter.h | 381 ++ utils/openttd/unicode/uclean.h | 267 ++ utils/openttd/unicode/ucnv.h | 1967 ++++++++ utils/openttd/unicode/ucnv_cb.h | 162 + utils/openttd/unicode/ucnv_err.h | 463 ++ utils/openttd/unicode/uconfig.h | 228 + utils/openttd/unicode/udata.h | 389 ++ utils/openttd/unicode/udeprctd.h | 50 + utils/openttd/unicode/udraft.h | 166 + utils/openttd/unicode/uenum.h | 134 + utils/openttd/unicode/uidna.h | 312 ++ utils/openttd/unicode/uintrnal.h | 180 + utils/openttd/unicode/uiter.h | 707 +++ utils/openttd/unicode/uloc.h | 1046 ++++ utils/openttd/unicode/umachine.h | 338 ++ utils/openttd/unicode/umisc.h | 60 + utils/openttd/unicode/unifilt.h | 127 + utils/openttd/unicode/unifunct.h | 125 + utils/openttd/unicode/unimatch.h | 163 + utils/openttd/unicode/uniset.h | 1566 ++++++ utils/openttd/unicode/unistr.h | 4230 +++++++++++++++++ utils/openttd/unicode/unorm.h | 576 +++ utils/openttd/unicode/uobject.h | 308 ++ utils/openttd/unicode/uobslete.h | 32 + utils/openttd/unicode/urename.h | 1775 +++++++ utils/openttd/unicode/urep.h | 155 + utils/openttd/unicode/ures.h | 871 ++++ utils/openttd/unicode/uscript.h | 254 + utils/openttd/unicode/uset.h | 1056 ++++ utils/openttd/unicode/usetiter.h | 318 ++ utils/openttd/unicode/ushape.h | 263 + utils/openttd/unicode/usprep.h | 156 + utils/openttd/unicode/ustring.h | 1479 ++++++ utils/openttd/unicode/usystem.h | 46 + utils/openttd/unicode/utext.h | 1562 ++++++ utils/openttd/unicode/utf.h | 227 + utils/openttd/unicode/utf16.h | 605 +++ utils/openttd/unicode/utf32.h | 23 + utils/openttd/unicode/utf8.h | 652 +++ utils/openttd/unicode/utf_old.h | 1171 +++++ utils/openttd/unicode/utrace.h | 358 ++ utils/openttd/unicode/utypes.h | 801 ++++ utils/openttd/unicode/uversion.h | 275 ++ utils/openttd/zconf.h | 332 ++ utils/openttd/zlib.h | 1357 ++++++ 156 files changed, 75175 insertions(+) create mode 100644 Simutrans-Experimental.vcproj create mode 100644 besch/vehikel_besch.cc create mode 100644 makeobj/Makeobj.sln create mode 100644 makeobj/Makeobj.vcproj create mode 100644 tpl/fixed_list_tpl.h create mode 100644 utils/openttd/freetype/config/ftconfig.h create mode 100644 utils/openttd/freetype/config/ftheader.h create mode 100644 utils/openttd/freetype/config/ftmodule.h create mode 100644 utils/openttd/freetype/config/ftoption.h create mode 100644 utils/openttd/freetype/config/ftstdlib.h create mode 100644 utils/openttd/freetype/freetype.h create mode 100644 utils/openttd/freetype/ftbbox.h create mode 100644 utils/openttd/freetype/ftbdf.h create mode 100644 utils/openttd/freetype/ftbitmap.h create mode 100644 utils/openttd/freetype/ftcache.h create mode 100644 utils/openttd/freetype/ftchapters.h create mode 100644 utils/openttd/freetype/ftcid.h create mode 100644 utils/openttd/freetype/fterrdef.h create mode 100644 utils/openttd/freetype/fterrors.h create mode 100644 utils/openttd/freetype/ftgasp.h create mode 100644 utils/openttd/freetype/ftglyph.h create mode 100644 utils/openttd/freetype/ftgxval.h create mode 100644 utils/openttd/freetype/ftgzip.h create mode 100644 utils/openttd/freetype/ftimage.h create mode 100644 utils/openttd/freetype/ftincrem.h create mode 100644 utils/openttd/freetype/ftlcdfil.h create mode 100644 utils/openttd/freetype/ftlist.h create mode 100644 utils/openttd/freetype/ftlzw.h create mode 100644 utils/openttd/freetype/ftmac.h create mode 100644 utils/openttd/freetype/ftmm.h create mode 100644 utils/openttd/freetype/ftmodapi.h create mode 100644 utils/openttd/freetype/ftmoderr.h create mode 100644 utils/openttd/freetype/ftotval.h create mode 100644 utils/openttd/freetype/ftoutln.h create mode 100644 utils/openttd/freetype/ftpfr.h create mode 100644 utils/openttd/freetype/ftrender.h create mode 100644 utils/openttd/freetype/ftsizes.h create mode 100644 utils/openttd/freetype/ftsnames.h create mode 100644 utils/openttd/freetype/ftstroke.h create mode 100644 utils/openttd/freetype/ftsynth.h create mode 100644 utils/openttd/freetype/ftsystem.h create mode 100644 utils/openttd/freetype/fttrigon.h create mode 100644 utils/openttd/freetype/fttypes.h create mode 100644 utils/openttd/freetype/ftwinfnt.h create mode 100644 utils/openttd/freetype/ftxf86.h create mode 100644 utils/openttd/freetype/internal/autohint.h create mode 100644 utils/openttd/freetype/internal/ftcalc.h create mode 100644 utils/openttd/freetype/internal/ftdebug.h create mode 100644 utils/openttd/freetype/internal/ftdriver.h create mode 100644 utils/openttd/freetype/internal/ftgloadr.h create mode 100644 utils/openttd/freetype/internal/ftmemory.h create mode 100644 utils/openttd/freetype/internal/ftobjs.h create mode 100644 utils/openttd/freetype/internal/ftrfork.h create mode 100644 utils/openttd/freetype/internal/ftserv.h create mode 100644 utils/openttd/freetype/internal/ftstream.h create mode 100644 utils/openttd/freetype/internal/fttrace.h create mode 100644 utils/openttd/freetype/internal/ftvalid.h create mode 100644 utils/openttd/freetype/internal/internal.h create mode 100644 utils/openttd/freetype/internal/pcftypes.h create mode 100644 utils/openttd/freetype/internal/psaux.h create mode 100644 utils/openttd/freetype/internal/pshints.h create mode 100644 utils/openttd/freetype/internal/services/svbdf.h create mode 100644 utils/openttd/freetype/internal/services/svcid.h create mode 100644 utils/openttd/freetype/internal/services/svgldict.h create mode 100644 utils/openttd/freetype/internal/services/svgxval.h create mode 100644 utils/openttd/freetype/internal/services/svkern.h create mode 100644 utils/openttd/freetype/internal/services/svmm.h create mode 100644 utils/openttd/freetype/internal/services/svotval.h create mode 100644 utils/openttd/freetype/internal/services/svpfr.h create mode 100644 utils/openttd/freetype/internal/services/svpostnm.h create mode 100644 utils/openttd/freetype/internal/services/svpscmap.h create mode 100644 utils/openttd/freetype/internal/services/svpsinfo.h create mode 100644 utils/openttd/freetype/internal/services/svsfnt.h create mode 100644 utils/openttd/freetype/internal/services/svttcmap.h create mode 100644 utils/openttd/freetype/internal/services/svtteng.h create mode 100644 utils/openttd/freetype/internal/services/svttglyf.h create mode 100644 utils/openttd/freetype/internal/services/svwinfnt.h create mode 100644 utils/openttd/freetype/internal/services/svxf86nm.h create mode 100644 utils/openttd/freetype/internal/sfnt.h create mode 100644 utils/openttd/freetype/internal/t1types.h create mode 100644 utils/openttd/freetype/internal/tttypes.h create mode 100644 utils/openttd/freetype/t1tables.h create mode 100644 utils/openttd/freetype/ttnameid.h create mode 100644 utils/openttd/freetype/tttables.h create mode 100644 utils/openttd/freetype/tttags.h create mode 100644 utils/openttd/freetype/ttunpat.h create mode 100644 utils/openttd/ft2build.h create mode 100644 utils/openttd/png.h create mode 100644 utils/openttd/pngconf.h create mode 100644 utils/openttd/unicode/brkiter.h create mode 100644 utils/openttd/unicode/caniter.h create mode 100644 utils/openttd/unicode/chariter.h create mode 100644 utils/openttd/unicode/dbbi.h create mode 100644 utils/openttd/unicode/docmain.h create mode 100644 utils/openttd/unicode/locid.h create mode 100644 utils/openttd/unicode/normlzr.h create mode 100644 utils/openttd/unicode/parseerr.h create mode 100644 utils/openttd/unicode/parsepos.h create mode 100644 utils/openttd/unicode/putil.h create mode 100644 utils/openttd/unicode/pwin32.h create mode 100644 utils/openttd/unicode/rbbi.h create mode 100644 utils/openttd/unicode/rep.h create mode 100644 utils/openttd/unicode/resbund.h create mode 100644 utils/openttd/unicode/schriter.h create mode 100644 utils/openttd/unicode/strenum.h create mode 100644 utils/openttd/unicode/symtable.h create mode 100644 utils/openttd/unicode/ubidi.h create mode 100644 utils/openttd/unicode/ubrk.h create mode 100644 utils/openttd/unicode/ucasemap.h create mode 100644 utils/openttd/unicode/ucat.h create mode 100644 utils/openttd/unicode/uchar.h create mode 100644 utils/openttd/unicode/uchriter.h create mode 100644 utils/openttd/unicode/uclean.h create mode 100644 utils/openttd/unicode/ucnv.h create mode 100644 utils/openttd/unicode/ucnv_cb.h create mode 100644 utils/openttd/unicode/ucnv_err.h create mode 100644 utils/openttd/unicode/uconfig.h create mode 100644 utils/openttd/unicode/udata.h create mode 100644 utils/openttd/unicode/udeprctd.h create mode 100644 utils/openttd/unicode/udraft.h create mode 100644 utils/openttd/unicode/uenum.h create mode 100644 utils/openttd/unicode/uidna.h create mode 100644 utils/openttd/unicode/uintrnal.h create mode 100644 utils/openttd/unicode/uiter.h create mode 100644 utils/openttd/unicode/uloc.h create mode 100644 utils/openttd/unicode/umachine.h create mode 100644 utils/openttd/unicode/umisc.h create mode 100644 utils/openttd/unicode/unifilt.h create mode 100644 utils/openttd/unicode/unifunct.h create mode 100644 utils/openttd/unicode/unimatch.h create mode 100644 utils/openttd/unicode/uniset.h create mode 100644 utils/openttd/unicode/unistr.h create mode 100644 utils/openttd/unicode/unorm.h create mode 100644 utils/openttd/unicode/uobject.h create mode 100644 utils/openttd/unicode/uobslete.h create mode 100644 utils/openttd/unicode/urename.h create mode 100644 utils/openttd/unicode/urep.h create mode 100644 utils/openttd/unicode/ures.h create mode 100644 utils/openttd/unicode/uscript.h create mode 100644 utils/openttd/unicode/uset.h create mode 100644 utils/openttd/unicode/usetiter.h create mode 100644 utils/openttd/unicode/ushape.h create mode 100644 utils/openttd/unicode/usprep.h create mode 100644 utils/openttd/unicode/ustring.h create mode 100644 utils/openttd/unicode/usystem.h create mode 100644 utils/openttd/unicode/utext.h create mode 100644 utils/openttd/unicode/utf.h create mode 100644 utils/openttd/unicode/utf16.h create mode 100644 utils/openttd/unicode/utf32.h create mode 100644 utils/openttd/unicode/utf8.h create mode 100644 utils/openttd/unicode/utf_old.h create mode 100644 utils/openttd/unicode/utrace.h create mode 100644 utils/openttd/unicode/utypes.h create mode 100644 utils/openttd/unicode/uversion.h create mode 100644 utils/openttd/zconf.h create mode 100644 utils/openttd/zlib.h diff --git a/Simutrans-Experimental.vcproj b/Simutrans-Experimental.vcproj new file mode 100644 index 00000000000..eacb3754c0f --- /dev/null +++ b/Simutrans-Experimental.vcproj @@ -0,0 +1,1110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/besch/vehikel_besch.cc b/besch/vehikel_besch.cc new file mode 100644 index 00000000000..4485616bf5b --- /dev/null +++ b/besch/vehikel_besch.cc @@ -0,0 +1,27 @@ +#include "vehikel_besch.h" + +// Get running costs. Running costs increased if the vehicle is obsolete. +// @author: jamespetts +uint16 +vehikel_besch_t::get_betriebskosten(static karte_t* welt) const +{ + uint16 month_now = welt->get_current_month(); + int normal_running_costs = get_betriebskosten(); + if(!welt->use_timeline() || !is_retired(month_now)) + { + return normal_running_costs; + } + //Else + uint16 base_obsolete_running_costs = normal_running_costs * (welt->get_einstellungen()->get_obsolete_running_cost_increase_percent() / 100); + uint16 obsolete_date = get_retire_year_month(); + if((month_now - obsolete_date) >= (welt->get_einstellungen()->get_obsolete_running_cost_increase_phase_years() * 12)) + { + return base_obsolete_running_costs; + } + //Else + //If not at end of phasing period, apply only a proportion of the obsolescence cost increase. + float tmp1 = base_obsolete_running_costs - normal_running_costs; + float tmp2 = month_now - obsolete_date; + float proportion = tmp2 / (welt->get_einstellungen()->get_obsolete_running_cost_increase_phase_years() * 12); + return (tmp1 * proportion) + normal_running_costs; +} \ No newline at end of file diff --git a/makeobj/Makeobj.sln b/makeobj/Makeobj.sln new file mode 100644 index 00000000000..e3447a94956 --- /dev/null +++ b/makeobj/Makeobj.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Makeobj", "Makeobj.vcproj", "{24CE8A5F-8B92-40EE-9491-31E2DFF019F9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {24CE8A5F-8B92-40EE-9491-31E2DFF019F9}.Debug|Win32.ActiveCfg = Debug|Win32 + {24CE8A5F-8B92-40EE-9491-31E2DFF019F9}.Debug|Win32.Build.0 = Debug|Win32 + {24CE8A5F-8B92-40EE-9491-31E2DFF019F9}.Release|Win32.ActiveCfg = Release|Win32 + {24CE8A5F-8B92-40EE-9491-31E2DFF019F9}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/makeobj/Makeobj.vcproj b/makeobj/Makeobj.vcproj new file mode 100644 index 00000000000..ddffb9357d9 --- /dev/null +++ b/makeobj/Makeobj.vcproj @@ -0,0 +1,506 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tpl/fixed_list_tpl.h b/tpl/fixed_list_tpl.h new file mode 100644 index 00000000000..fbe5b5be43e --- /dev/null +++ b/tpl/fixed_list_tpl.h @@ -0,0 +1,431 @@ +/* A very light 32 or less element list + * using a fixed sized array with a + * head and tail node. Template type. + * + * Author: jamespetts. Released under the terms + * of the Artistic Licence (for use with Simutrans), + * and also the GPL (v 2.0). + * + * (To use other than in simutrans, remove the + * include files and replace Simutrans specific + * types (such as uint8) with standard types + * (such as char). + */ + +#include +#include "../simtypes.h" +#include "../simdebug.h" + +template class fixed_list_tpl +{ + +public: + + fixed_list_tpl() : size(0), head(0), tail(0), placeholder(0), placeholder_set(false) { } + + T get_element(uint8 e) + { + if(e > size) + { + return NULL; + } + else + { + uint8 i = add_index(head, e, N); + return data[i]; + } + } + + void clear() + { + size = 0; + head = 0; + tail = 0; + placeholder = 0; + placeholder_set = false; + } + + void trim_from_head(uint8 trim_by) + { + if(trim_by < 1) + { + return; + } + if(size <= trim_by) + { + //If trimming by more than the size, + //this is equivalent to clearing. + clear(); + } + else + { + if(size > 1) + { + head = add_index(head, trim_by, N); + size -= trim_by; + if(!index_is_in_range(placeholder)) + { + //Placeholder has been trimmed + placeholder_set = false; + placeholder = 0; + } + } + else + { + clear(); + } + } + return; + } + + T remove_first() + { + T tmp = get_element(0); + trim_from_head(1); + return tmp; + } + + void trim_from_tail(uint8 trim_by) + { + if(trim_by < 1) + { + return; + } + if(size <= trim_by) + { + clear(); + } + else + { + if(size > 1) + { + tail = subtract_index(tail, trim_by, N); + size -= trim_by; + if(!index_is_in_range(placeholder)) + { + //Placeholder has been trimmed + placeholder_set = false; + placeholder = 0; + } + } + else + { + clear(); + } + } + return; + } + + uint8 get_size() + { + return size; + } + + void add_to_head(T datum) + { + uint8 i; + if(size > 0) + { + i = subtract_index(head, 1, N); + } + else + { + i = 0; + } + data[i] = datum; + head = i; + if(tail == head && size > 0) + { + tail = subtract_index(head, 1, N); + } + else + { + size ++; + } + if(placeholder_set && placeholder == i) + { + //Placeholder is overwritten + placeholder_set = false; + placeholder = 0; + } + } + + void add_to_tail(T datum) + { + uint8 i; + + if(size == 0) + { + i = 0; + } + else + { + i = add_index(tail, 1, N); + } + data[i] = datum; + tail = i; + if(head == tail && size > 0) + { + head = add_index(tail, 1, N); + if(placeholder_set && placeholder == i) + { + //Placeholder is overwritten + placeholder_set = false; + placeholder = 0; + } + } + else + { + size ++; + } + } + + bool add_to_head_no_overwite(T datum) + { + if(size < N) + { + add_to_head(datum); + return true; + } + else + { + return false; + } + } + + bool add_to_tail_no_overwrite(T datum) + { + if(size < N) + { + add_to_tail(datum); + return true; + } + else + { + return false; + } + } + + uint8 get_index_of(T datum) + { + uint8 tmp = 255; + + for(uint8 i = 0; i < N; i++) + { + if(data[i] == datum && index_is_in_range(i)) + { + tmp = i; + break; + } + } + + if(tmp > (N - 1)) + { + return 255; + } + else + { + uint8 index = subtract_index(tmp, head, N); + return index; + } + } + + bool set_placeholder(uint8 p) + { + if(p >= N) + { + return false; + } + uint8 position; + if(tail >= head) + { + position = add_index(p, head, N); + if(!index_is_in_range(position)) + { + return false; + } + } + else + { + position = add_index(p, tail, N); + if (!index_is_in_range(position)) + { + return false; + } + } + placeholder = position; + placeholder_set = true; + return true; + } + + uint8 get_placeholder() + { + if(placeholder_set && index_is_in_range(placeholder)) + { + uint8 position; + if(tail >=head) + { + position = subtract_index(placeholder, head, N); + } + else + { + position = subtract_index(placeholder, tail, N); + } + return position; + } + + else + { + return NULL; + } + } + + bool is_placeholder() + { + if(index_is_in_range(placeholder)) + { + // Safeguarding against corruption of placeholder data. + return placeholder_set; + } + else + { + return false; + } + } + + void clear_placeholder() + { + placeholder_set = false; + placeholder = 0; + } + + void placeholder_increment() + { + if(placeholder_set) + { + uint8 position = add_index(placeholder, 1, N); + if(!index_is_in_range(position)) + { + //Placeholder has fallen off the end. + placeholder_set = false; + placeholder = 0; + return; + } + placeholder = position; + } + } + + void placeholder_decrement() + { + if(placeholder_set) + { + uint8 position = subtract_index(placeholder, 1, N); + if(!index_is_in_range(position)) + { + //Placeholder has fallen off the end. + placeholder_set = false; + placeholder = 0; + return; + } + placeholder = position; + } + } + + T get_placeholder_element() + { + if(placeholder_set) + { + return data[placeholder]; + } + else + { + return NULL; + } + } + +private: + + T data[N]; + + uint8 size; + + uint8 head; + + uint8 tail; + + uint8 placeholder; + + bool placeholder_set; + + //These methods are used for automating looping arithmetic + uint8 add_index(uint8 base, uint8 addition, int index) + { + uint8 tmp; + + if((base + addition) < index) + { + return base + addition; + } + else + { + tmp = (base + addition) - index; + } + + if(tmp < index) + { + return tmp; + } + else + { + //There could be a sophisticated system of trimming here, + //but it would take extra work/memory/processing power, and + //is only used internally, so not worth it. This code should + //never be reached. + return index - 1; + } + } + + uint8 subtract_index(uint8 base, uint8 subtraction, int index) + { + uint8 tmp; + + if((base - subtraction) < index && (base - subtraction) > 0) + { + return base - subtraction; + } + else + { + tmp = (base - subtraction) + index; //Should re-set the overflow + } + + if(tmp < index) + { + return tmp; + } + else + { + //There could be a sophisticated system of trimming here, + //but it would take extra work/memory/processing power, and + //is only used internally, so not worth it. This code should + //never be reached. + return index - 1; + } + } + + bool index_is_in_range(uint8 index) + { + //Checks whether a possible data[index] value is within the current active range + if(tail >= head && index >= head && index <= tail) + { + return true; + } + else if(tail < head && (index >= head || index <= tail)) + { + return true; + } + else + { + return false; + } + } +}; \ No newline at end of file diff --git a/utils/openttd/freetype/config/ftconfig.h b/utils/openttd/freetype/config/ftconfig.h new file mode 100644 index 00000000000..09b2cf951c1 --- /dev/null +++ b/utils/openttd/freetype/config/ftconfig.h @@ -0,0 +1,415 @@ +/***************************************************************************/ +/* */ +/* ftconfig.h */ +/* */ +/* ANSI-specific configuration file (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This header file contains a number of macro definitions that are used */ + /* by the rest of the engine. Most of the macros here are automatically */ + /* determined at compile time, and you should not need to change it to */ + /* port FreeType, except to compile the library with a non-ANSI */ + /* compiler. */ + /* */ + /* Note however that if some specific modifications are needed, we */ + /* advise you to place a modified copy in your build directory. */ + /* */ + /* The build directory is usually `freetype/builds/', and */ + /* contains system-specific files that are always included first when */ + /* building the library. */ + /* */ + /* This ANSI version should stay in `include/freetype/config'. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTCONFIG_H__ +#define __FTCONFIG_H__ + +#include +#include FT_CONFIG_OPTIONS_H +#include FT_CONFIG_STANDARD_LIBRARY_H + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* PLATFORM-SPECIFIC CONFIGURATION MACROS */ + /* */ + /* These macros can be toggled to suit a specific system. The current */ + /* ones are defaults used to compile FreeType in an ANSI C environment */ + /* (16bit compilers are also supported). Copy this file to your own */ + /* `freetype/builds/' directory, and edit it to port the engine. */ + /* */ + /*************************************************************************/ + + + /* There are systems (like the Texas Instruments 'C54x) where a `char' */ + /* has 16 bits. ANSI C says that sizeof(char) is always 1. Since an */ + /* `int' has 16 bits also for this system, sizeof(int) gives 1 which */ + /* is probably unexpected. */ + /* */ + /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a */ + /* `char' type. */ + +#ifndef FT_CHAR_BIT +#define FT_CHAR_BIT CHAR_BIT +#endif + + + /* The size of an `int' type. */ +#if FT_UINT_MAX == 0xFFFFUL +#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) +#elif FT_UINT_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) +#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `int' type!" +#endif + + /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ + /* DM642) is recognized but avoided. */ +#if FT_ULONG_MAX == 0xFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL +#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL +#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) +#else +#error "Unsupported size of `long' type!" +#endif + + + /* Preferred alignment of data */ +#define FT_ALIGNMENT 8 + + + /* FT_UNUSED is a macro used to indicate that a given parameter is not */ + /* used -- this is only used to get rid of unpleasant compiler warnings */ +#ifndef FT_UNUSED +#define FT_UNUSED( arg ) ( (arg) = (arg) ) +#endif + + + /*************************************************************************/ + /* */ + /* AUTOMATIC CONFIGURATION MACROS */ + /* */ + /* These macros are computed from the ones defined above. Don't touch */ + /* their definition, unless you know precisely what you are doing. No */ + /* porter should need to mess with them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Mac support */ + /* */ + /* This is the only necessary change, so it is defined here instead */ + /* providing a new configuration file. */ + /* */ +#if ( defined( __APPLE__ ) && !defined( DARWIN_NO_CARBON ) ) || \ + ( defined( __MWERKS__ ) && defined( macintosh ) ) + /* no Carbon frameworks for 64bit 10.4.x */ +#include "AvailabilityMacros.h" +#if defined( __LP64__ ) && \ + ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 ) +#define DARWIN_NO_CARBON 1 +#else +#define FT_MACINTOSH 1 +#endif +#endif + + + /*************************************************************************/ + /* */ + /*
*/ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int16 */ + /* */ + /* */ + /* A typedef for a 16bit signed integer type. */ + /* */ + typedef signed short FT_Int16; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt16 */ + /* */ + /* */ + /* A typedef for a 16bit unsigned integer type. */ + /* */ + typedef unsigned short FT_UInt16; + + /* */ + + + /* this #if 0 ... #endif clause is for documentation purposes */ +#if 0 + + /*************************************************************************/ + /* */ + /* */ + /* FT_Int32 */ + /* */ + /* */ + /* A typedef for a 32bit signed integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef signed XXX FT_Int32; + + + /*************************************************************************/ + /* */ + /* */ + /* FT_UInt32 */ + /* */ + /* A typedef for a 32bit unsigned integer type. The size depends on */ + /* the configuration. */ + /* */ + typedef unsigned XXX FT_UInt32; + + /* */ + +#endif + +#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) + + typedef signed int FT_Int32; + typedef unsigned int FT_UInt32; + +#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) + + typedef signed long FT_Int32; + typedef unsigned long FT_UInt32; + +#else +#error "no 32bit type found -- please check your configuration files" +#endif + + /* look up an integer type that is at least 32 bits */ +#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) + + typedef int FT_Fast; + typedef unsigned int FT_UFast; + +#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) + + typedef long FT_Fast; + typedef unsigned long FT_UFast; + +#endif + + + /* determine whether we have a 64-bit int type for platforms without */ + /* Autoconf */ +#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) + + /* FT_LONG64 must be defined if a 64-bit type is available */ +#define FT_LONG64 +#define FT_INT64 long + +#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 + +#elif defined( __BORLANDC__ ) /* Borland C++ */ + + /* XXXX: We should probably check the value of __BORLANDC__ in order */ + /* to test the compiler version. */ + + /* this compiler provides the __int64 type */ +#define FT_LONG64 +#define FT_INT64 __int64 + +#elif defined( __WATCOMC__ ) /* Watcom C++ */ + + /* Watcom doesn't provide 64-bit data types */ + +#elif defined( __MWERKS__ ) /* Metrowerks CodeWarrior */ + +#define FT_LONG64 +#define FT_INT64 long long int + +#elif defined( __GNUC__ ) + + /* GCC provides the `long long' type */ +#define FT_LONG64 +#define FT_INT64 long long int + +#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ + + +#define FT_BEGIN_STMNT do { +#define FT_END_STMNT } while ( 0 ) +#define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT + + + /*************************************************************************/ + /* */ + /* A 64-bit data type will create compilation problems if you compile */ + /* in strict ANSI mode. To avoid them, we disable their use if */ + /* __STDC__ is defined. You can however ignore this rule by */ + /* defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro. */ + /* */ +#if defined( FT_LONG64 ) && !defined( FT_CONFIG_OPTION_FORCE_INT64 ) + +#ifdef __STDC__ + + /* undefine the 64-bit macros in strict ANSI compilation mode */ +#undef FT_LONG64 +#undef FT_INT64 + +#endif /* __STDC__ */ + +#endif /* FT_LONG64 && !FT_CONFIG_OPTION_FORCE_INT64 */ + + +#ifdef FT_MAKE_OPTION_SINGLE_OBJECT + +#define FT_LOCAL( x ) static x +#define FT_LOCAL_DEF( x ) static x + +#else + +#ifdef __cplusplus +#define FT_LOCAL( x ) extern "C" x +#define FT_LOCAL_DEF( x ) extern "C" x +#else +#define FT_LOCAL( x ) extern x +#define FT_LOCAL_DEF( x ) x +#endif + +#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ + + +#ifndef FT_BASE + +#ifdef __cplusplus +#define FT_BASE( x ) extern "C" x +#else +#define FT_BASE( x ) extern x +#endif + +#endif /* !FT_BASE */ + + +#ifndef FT_BASE_DEF + +#ifdef __cplusplus +#define FT_BASE_DEF( x ) x +#else +#define FT_BASE_DEF( x ) x +#endif + +#endif /* !FT_BASE_DEF */ + + +#ifndef FT_EXPORT + +#ifdef __cplusplus +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x +#endif + +#endif /* !FT_EXPORT */ + + +#ifndef FT_EXPORT_DEF + +#ifdef __cplusplus +#define FT_EXPORT_DEF( x ) extern "C" x +#else +#define FT_EXPORT_DEF( x ) extern x +#endif + +#endif /* !FT_EXPORT_DEF */ + + +#ifndef FT_EXPORT_VAR + +#ifdef __cplusplus +#define FT_EXPORT_VAR( x ) extern "C" x +#else +#define FT_EXPORT_VAR( x ) extern x +#endif + +#endif /* !FT_EXPORT_VAR */ + + /* The following macros are needed to compile the library with a */ + /* C++ compiler and with 16bit compilers. */ + /* */ + + /* This is special. Within C++, you must specify `extern "C"' for */ + /* functions which are used via function pointers, and you also */ + /* must do that for structures which contain function pointers to */ + /* assure C linkage -- it's not possible to have (local) anonymous */ + /* functions which are accessed by (global) function pointers. */ + /* */ + /* */ + /* FT_CALLBACK_DEF is used to _define_ a callback function. */ + /* */ + /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ + /* contains pointers to callback functions. */ + /* */ + /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ + /* that contains pointers to callback functions. */ + /* */ + /* */ + /* Some 16bit compilers have to redefine these macros to insert */ + /* the infamous `_cdecl' or `__fastcall' declarations. */ + /* */ +#ifndef FT_CALLBACK_DEF +#ifdef __cplusplus +#define FT_CALLBACK_DEF( x ) extern "C" x +#else +#define FT_CALLBACK_DEF( x ) static x +#endif +#endif /* FT_CALLBACK_DEF */ + +#ifndef FT_CALLBACK_TABLE +#ifdef __cplusplus +#define FT_CALLBACK_TABLE extern "C" +#define FT_CALLBACK_TABLE_DEF extern "C" +#else +#define FT_CALLBACK_TABLE extern +#define FT_CALLBACK_TABLE_DEF /* nothing */ +#endif +#endif /* FT_CALLBACK_TABLE */ + + +FT_END_HEADER + + +#endif /* __FTCONFIG_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/config/ftheader.h b/utils/openttd/freetype/config/ftheader.h new file mode 100644 index 00000000000..dc5ad3fde9a --- /dev/null +++ b/utils/openttd/freetype/config/ftheader.h @@ -0,0 +1,768 @@ +/***************************************************************************/ +/* */ +/* ftheader.h */ +/* */ +/* Build macros of the FreeType 2 library. */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#ifndef __FT_HEADER_H__ +#define __FT_HEADER_H__ + + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_BEGIN_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_END_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_BEGIN_HEADER extern "C" { +#else +#define FT_BEGIN_HEADER /* nothing */ +#endif + + + /*@***********************************************************************/ + /* */ + /* */ + /* FT_END_HEADER */ + /* */ + /* */ + /* This macro is used in association with @FT_BEGIN_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_END_HEADER } +#else +#define FT_END_HEADER /* nothing */ +#endif + + + /*************************************************************************/ + /* */ + /* Aliases for the FreeType 2 public and configuration files. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /*
*/ + /* header_file_macros */ + /* */ + /* */ + /* Header File Macros */ + /* */ + /* <Abstract> */ + /* Macro definitions used to #include specific header files. */ + /* */ + /* <Description> */ + /* The following macros are defined to the name of specific */ + /* FreeType~2 header files. They can be used directly in #include */ + /* statements as in: */ + /* */ + /* { */ + /* #include FT_FREETYPE_H */ + /* #include FT_MULTIPLE_MASTERS_H */ + /* #include FT_GLYPH_H */ + /* } */ + /* */ + /* There are several reasons why we are now using macros to name */ + /* public header files. The first one is that such macros are not */ + /* limited to the infamous 8.3~naming rule required by DOS (and */ + /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ + /* */ + /* The second reason is that it allows for more flexibility in the */ + /* way FreeType~2 is installed on a given system. */ + /* */ + /*************************************************************************/ + + + /* configuration files */ + + /************************************************************************* + * + * @macro: + * FT_CONFIG_CONFIG_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 configuration data. + * + */ +#ifndef FT_CONFIG_CONFIG_H +#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_STANDARD_LIBRARY_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 interface to the standard C library functions. + * + */ +#ifndef FT_CONFIG_STANDARD_LIBRARY_H +#define FT_CONFIG_STANDARD_LIBRARY_H <freetype/config/ftstdlib.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_OPTIONS_H + * + * @description: + * A macro used in #include statements to name the file containing + * FreeType~2 project-specific configuration options. + * + */ +#ifndef FT_CONFIG_OPTIONS_H +#define FT_CONFIG_OPTIONS_H <freetype/config/ftoption.h> +#endif + + + /************************************************************************* + * + * @macro: + * FT_CONFIG_MODULES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 modules that are statically linked to new library + * instances in @FT_Init_FreeType. + * + */ +#ifndef FT_CONFIG_MODULES_H +#define FT_CONFIG_MODULES_H <freetype/config/ftmodule.h> +#endif + + /* */ + + /* public headers */ + + /************************************************************************* + * + * @macro: + * FT_FREETYPE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * base FreeType~2 API. + * + */ +#define FT_FREETYPE_H <freetype/freetype.h> + + + /************************************************************************* + * + * @macro: + * FT_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 error codes (and messages). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_ERRORS_H <freetype/fterrors.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_ERRORS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list of FreeType~2 module error offsets (and messages). + * + */ +#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h> + + + /************************************************************************* + * + * @macro: + * FT_SYSTEM_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 interface to low-level operations (i.e., memory management + * and stream i/o). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_SYSTEM_H <freetype/ftsystem.h> + + + /************************************************************************* + * + * @macro: + * FT_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing type + * definitions related to glyph images (i.e., bitmaps, outlines, + * scan-converter parameters). + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_IMAGE_H <freetype/ftimage.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * basic data types defined by FreeType~2. + * + * It is included by @FT_FREETYPE_H. + * + */ +#define FT_TYPES_H <freetype/fttypes.h> + + + /************************************************************************* + * + * @macro: + * FT_LIST_H + * + * @description: + * A macro used in #include statements to name the file containing the + * list management API of FreeType~2. + * + * (Most applications will never need to include this file.) + * + */ +#define FT_LIST_H <freetype/ftlist.h> + + + /************************************************************************* + * + * @macro: + * FT_OUTLINE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * scalable outline management API of FreeType~2. + * + */ +#define FT_OUTLINE_H <freetype/ftoutln.h> + + + /************************************************************************* + * + * @macro: + * FT_SIZES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API which manages multiple @FT_Size objects per face. + * + */ +#define FT_SIZES_H <freetype/ftsizes.h> + + + /************************************************************************* + * + * @macro: + * FT_MODULE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * module management API of FreeType~2. + * + */ +#define FT_MODULE_H <freetype/ftmodapi.h> + + + /************************************************************************* + * + * @macro: + * FT_RENDER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * renderer module management API of FreeType~2. + * + */ +#define FT_RENDER_H <freetype/ftrender.h> + + + /************************************************************************* + * + * @macro: + * FT_TYPE1_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the Type~1 format. + * + */ +#define FT_TYPE1_TABLES_H <freetype/t1tables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_IDS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * enumeration values which identify name strings, languages, encodings, + * etc. This file really contains a _large_ set of constant macro + * definitions, taken from the TrueType and OpenType specifications. + * + */ +#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TABLES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * types and API specific to the TrueType (as well as OpenType) format. + * + */ +#define FT_TRUETYPE_TABLES_H <freetype/tttables.h> + + + /************************************************************************* + * + * @macro: + * FT_TRUETYPE_TAGS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of TrueType four-byte `tags' which identify blocks in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_TRUETYPE_TAGS_H <freetype/tttags.h> + + + /************************************************************************* + * + * @macro: + * FT_BDF_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which accesses BDF-specific strings from a + * face. + * + */ +#define FT_BDF_H <freetype/ftbdf.h> + + + /************************************************************************* + * + * @macro: + * FT_CID_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which access CID font information from a + * face. + * + */ +#define FT_CID_H <freetype/ftcid.h> + + + /************************************************************************* + * + * @macro: + * FT_GZIP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports gzip-compressed files. + * + */ +#define FT_GZIP_H <freetype/ftgzip.h> + + + /************************************************************************* + * + * @macro: + * FT_LZW_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports LZW-compressed files. + * + */ +#define FT_LZW_H <freetype/ftlzw.h> + + + /************************************************************************* + * + * @macro: + * FT_WINFONTS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * definitions of an API which supports Windows FNT files. + * + */ +#define FT_WINFONTS_H <freetype/ftwinfnt.h> + + + /************************************************************************* + * + * @macro: + * FT_GLYPH_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional glyph management component. + * + */ +#define FT_GLYPH_H <freetype/ftglyph.h> + + + /************************************************************************* + * + * @macro: + * FT_BITMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional bitmap conversion component. + * + */ +#define FT_BITMAP_H <freetype/ftbitmap.h> + + + /************************************************************************* + * + * @macro: + * FT_BBOX_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional exact bounding box computation routines. + * + */ +#define FT_BBOX_H <freetype/ftbbox.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * API of the optional FreeType~2 cache sub-system. + * + */ +#define FT_CACHE_H <freetype/ftcache.h> + + + /************************************************************************* + * + * @macro: + * FT_CACHE_IMAGE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `glyph image' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for @FT_Glyph elements. You can also + * use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to + * store small glyph bitmaps, as it will use less memory. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * glyph image-related cache declarations. + * + */ +#define FT_CACHE_IMAGE_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_SMALL_BITMAPS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `small bitmaps' API of the FreeType~2 cache sub-system. + * + * It is used to define a cache for small glyph bitmaps in a relatively + * memory-efficient way. You can also use the API defined in + * @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, + * including scalable outlines. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * small bitmaps-related cache declarations. + * + */ +#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_CACHE_CHARMAP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * `charmap' API of the FreeType~2 cache sub-system. + * + * This macro is deprecated. Simply include @FT_CACHE_H to have all + * charmap-based cache declarations. + * + */ +#define FT_CACHE_CHARMAP_H FT_CACHE_H + + + /************************************************************************* + * + * @macro: + * FT_MAC_H + * + * @description: + * A macro used in #include statements to name the file containing the + * Macintosh-specific FreeType~2 API. The latter is used to access + * fonts embedded in resource forks. + * + * This header file must be explicitly included by client applications + * compiled on the Mac (note that the base API still works though). + * + */ +#define FT_MAC_H <freetype/ftmac.h> + + + /************************************************************************* + * + * @macro: + * FT_MULTIPLE_MASTERS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional multiple-masters management API of FreeType~2. + * + */ +#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h> + + + /************************************************************************* + * + * @macro: + * FT_SFNT_NAMES_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which accesses embedded `name' strings in + * SFNT-based font formats (i.e., TrueType and OpenType). + * + */ +#define FT_SFNT_NAMES_H <freetype/ftsnames.h> + + + /************************************************************************* + * + * @macro: + * FT_OPENTYPE_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates OpenType tables (BASE, GDEF, + * GPOS, GSUB, JSTF). + * + */ +#define FT_OPENTYPE_VALIDATE_H <freetype/ftotval.h> + + + /************************************************************************* + * + * @macro: + * FT_GX_VALIDATE_H + * + * @description: + * A macro used in #include statements to name the file containing the + * optional FreeType~2 API which validates TrueTypeGX/AAT tables (feat, + * mort, morx, bsln, just, kern, opbd, trak, prop). + * + */ +#define FT_GX_VALIDATE_H <freetype/ftgxval.h> + + + /************************************************************************* + * + * @macro: + * FT_PFR_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which accesses PFR-specific data. + * + */ +#define FT_PFR_H <freetype/ftpfr.h> + + + /************************************************************************* + * + * @macro: + * FT_STROKER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions to stroke outline paths. + */ +#define FT_STROKER_H <freetype/ftstroke.h> + + + /************************************************************************* + * + * @macro: + * FT_SYNTHESIS_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs artificial obliquing and emboldening. + */ +#define FT_SYNTHESIS_H <freetype/ftsynth.h> + + + /************************************************************************* + * + * @macro: + * FT_XFREE86_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which provides functions specific to the XFree86 and + * X.Org X11 servers. + */ +#define FT_XFREE86_H <freetype/ftxf86.h> + + + /************************************************************************* + * + * @macro: + * FT_TRIGONOMETRY_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs trigonometric computations (e.g., + * cosines and arc tangents). + */ +#define FT_TRIGONOMETRY_H <freetype/fttrigon.h> + + + /************************************************************************* + * + * @macro: + * FT_LCD_FILTER_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_LCD_FILTER_H <freetype/ftlcdfil.h> + + + /************************************************************************* + * + * @macro: + * FT_UNPATENTED_HINTING_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_UNPATENTED_HINTING_H <freetype/ttunpat.h> + + + /************************************************************************* + * + * @macro: + * FT_INCREMENTAL_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which performs color filtering for subpixel rendering. + */ +#define FT_INCREMENTAL_H <freetype/ftincrem.h> + + + /************************************************************************* + * + * @macro: + * FT_GASP_H + * + * @description: + * A macro used in #include statements to name the file containing the + * FreeType~2 API which returns entries from the TrueType GASP table. + */ +#define FT_GASP_H <freetype/ftgasp.h> + + + /* */ + +#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h> + + + /* The internals of the cache sub-system are no longer exposed. We */ + /* default to FT_CACHE_H at the moment just in case, but we know of */ + /* no rogue client that uses them. */ + /* */ +#define FT_CACHE_MANAGER_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_MRU_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_MANAGER_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_CACHE_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_GLYPH_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_IMAGE_H <freetype/ftcache.h> +#define FT_CACHE_INTERNAL_SBITS_H <freetype/ftcache.h> + + +#define FT_INCREMENTAL_H <freetype/ftincrem.h> + +#define FT_TRUETYPE_UNPATENTED_H <freetype/ttunpat.h> + + + /* + * Include internal headers definitions from <freetype/internal/...> + * only when building the library. + */ +#ifdef FT2_BUILD_LIBRARY +#define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h> +#include FT_INTERNAL_INTERNAL_H +#endif /* FT2_BUILD_LIBRARY */ + + +#endif /* __FT2_BUILD_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/config/ftmodule.h b/utils/openttd/freetype/config/ftmodule.h new file mode 100644 index 00000000000..d92b0ee6a1a --- /dev/null +++ b/utils/openttd/freetype/config/ftmodule.h @@ -0,0 +1,32 @@ +/* + * This file registers the FreeType modules compiled into the library. + * + * If you use GNU make, this file IS NOT USED! Instead, it is created in + * the objects directory (normally `<topdir>/objs/') based on information + * from `<topdir>/modules.cfg'. + * + * Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile + * FreeType without GNU make. + * + */ + +FT_USE_MODULE(autofit_module_class) +FT_USE_MODULE(tt_driver_class) +FT_USE_MODULE(t1_driver_class) +FT_USE_MODULE(cff_driver_class) +FT_USE_MODULE(t1cid_driver_class) +FT_USE_MODULE(pfr_driver_class) +FT_USE_MODULE(t42_driver_class) +FT_USE_MODULE(winfnt_driver_class) +FT_USE_MODULE(pcf_driver_class) +FT_USE_MODULE(psaux_module_class) +FT_USE_MODULE(psnames_module_class) +FT_USE_MODULE(pshinter_module_class) +FT_USE_MODULE(ft_raster1_renderer_class) +FT_USE_MODULE(sfnt_module_class) +FT_USE_MODULE(ft_smooth_renderer_class) +FT_USE_MODULE(ft_smooth_lcd_renderer_class) +FT_USE_MODULE(ft_smooth_lcdv_renderer_class) +FT_USE_MODULE(bdf_driver_class) + +/* EOF */ diff --git a/utils/openttd/freetype/config/ftoption.h b/utils/openttd/freetype/config/ftoption.h new file mode 100644 index 00000000000..9b0f40043e6 --- /dev/null +++ b/utils/openttd/freetype/config/ftoption.h @@ -0,0 +1,671 @@ +/***************************************************************************/ +/* */ +/* ftoption.h */ +/* */ +/* User-selectable configuration macros (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOPTION_H__ +#define __FTOPTION_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* USER-SELECTABLE CONFIGURATION MACROS */ + /* */ + /* This file contains the default configuration macro definitions for */ + /* a standard build of the FreeType library. There are three ways to */ + /* use this file to build project-specific versions of the library: */ + /* */ + /* - You can modify this file by hand, but this is not recommended in */ + /* cases where you would like to build several versions of the */ + /* library from a single source directory. */ + /* */ + /* - You can put a copy of this file in your build directory, more */ + /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ + /* is the name of a directory that is included _before_ the FreeType */ + /* include path during compilation. */ + /* */ + /* The default FreeType Makefiles and Jamfiles use the build */ + /* directory `builds/<system>' by default, but you can easily change */ + /* that for your own projects. */ + /* */ + /* - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it */ + /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ + /* locate this file during the build. For example, */ + /* */ + /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ + /* #include <freetype/config/ftheader.h> */ + /* */ + /* will use `$BUILD/myftoptions.h' instead of this file for macro */ + /* definitions. */ + /* */ + /* Note also that you can similarly pre-define the macro */ + /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ + /* that are statically linked to the library at compile time. By */ + /* default, this file is <freetype/config/ftmodule.h>. */ + /* */ + /* We highly recommend using the third method whenever possible. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Uncomment the line below if you want to activate sub-pixel rendering */ + /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ + /* */ + /* Note that this feature is covered by several Microsoft patents */ + /* and should not be activated in any default build of the library. */ + /* */ + /* This macro has no impact on the FreeType API, only on its */ + /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ + /* FT_Render_Glyph still generates a bitmap that is 3 times larger than */ + /* the original size; the difference will be that each triplet of */ + /* subpixels has R=G=B. */ + /* */ + /* This is done to allow FreeType clients to run unmodified, forcing */ + /* them to display normal gray-level anti-aliased glyphs. */ + /* */ +/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + + + /*************************************************************************/ + /* */ + /* Many compilers provide a non-ANSI 64-bit data type that can be used */ + /* by FreeType to speed up some computations. However, this will create */ + /* some problems when compiling the library in strict ANSI mode. */ + /* */ + /* For this reason, the use of 64-bit integers is normally disabled when */ + /* the __STDC__ macro is defined. You can however disable this by */ + /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ + /* */ + /* For most compilers, this will only create compilation warnings when */ + /* building the library. */ + /* */ + /* ObNote: The compiler-specific 64-bit integers are detected in the */ + /* file `ftconfig.h' either statically or through the */ + /* `configure' script on supported platforms. */ + /* */ +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* LZW-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `compress' program. This is mostly used to parse many of the PCF */ + /* files that come with various X11 distributions. The implementation */ + /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ + /* (see src/lzw/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +#define FT_CONFIG_OPTION_USE_LZW + + + /*************************************************************************/ + /* */ + /* Gzip-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* `gzip' program. This is mostly used to parse many of the PCF files */ + /* that come with XFree86. The implementation uses `zlib' to */ + /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. See also */ + /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ + /* */ +#define FT_CONFIG_OPTION_USE_ZLIB + + + /*************************************************************************/ + /* */ + /* ZLib library selection */ + /* */ + /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ + /* It allows FreeType's `ftgzip' component to link to the system's */ + /* installation of the ZLib library. This is useful on systems like */ + /* Unix or VMS where it generally is already available. */ + /* */ + /* If you let it undefined, the component will use its own copy */ + /* of the zlib sources instead. These have been modified to be */ + /* included directly within the component and *not* export external */ + /* function names. This allows you to link any program with FreeType */ + /* _and_ ZLib without linking conflicts. */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ + + + /*************************************************************************/ + /* */ + /* DLL export compilation */ + /* */ + /* When compiling FreeType as a DLL, some systems/compilers need a */ + /* special keyword in front OR after the return type of function */ + /* declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ + /* */ + /* FT_EXPORT( return_type ) */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* */ + /* */ + /* FT_EXPORT_DEF( return_type ) */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* */ + /* You can provide your own implementation of FT_EXPORT and */ + /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ + /* will be later automatically defined as `extern return_type' to */ + /* allow normal compilation. */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +#define FT_EXPORT(x) extern x __stdcall +#define FT_EXPORT_DEF(x) x __stdcall + + + /*************************************************************************/ + /* */ + /* Glyph Postscript Names handling */ + /* */ + /* By default, FreeType 2 is compiled with the `PSNames' module. This */ + /* module is in charge of converting a glyph name string into a */ + /* Unicode value, or return a Macintosh standard glyph name for the */ + /* use with the TrueType `post' table. */ + /* */ + /* Undefine this macro if you do not want `PSNames' compiled in your */ + /* build of FreeType. This has the following effects: */ + /* */ + /* - The TrueType driver will provide its own set of glyph names, */ + /* if you build it to support postscript names in the TrueType */ + /* `post' table. */ + /* */ + /* - The Type 1 driver will not be able to synthetize a Unicode */ + /* charmap out of the glyphs found in the fonts. */ + /* */ + /* You would normally undefine this configuration macro when building */ + /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ + /* */ +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Postscript Names to Unicode Values support */ + /* */ + /* By default, FreeType 2 is built with the `PSNames' module compiled */ + /* in. Among other things, the module is used to convert a glyph name */ + /* into a Unicode value. This is especially useful in order to */ + /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* through a big table named the `Adobe Glyph List' (AGL). */ + /* */ + /* Undefine this macro if you do not want the Adobe Glyph List */ + /* compiled in your `PSNames' module. The Type 1 driver will not be */ + /* able to synthetize a Unicode charmap out of the glyphs found in the */ + /* fonts. */ + /* */ +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + + /*************************************************************************/ + /* */ + /* Support for Mac fonts */ + /* */ + /* Define this macro if you want support for outline fonts in Mac */ + /* format (mac dfont, mac resource, macbinary containing a mac */ + /* resource) on non-Mac platforms. */ + /* */ + /* Note that the `FOND' resource isn't checked. */ + /* */ +#define FT_CONFIG_OPTION_MAC_FONTS + + + /*************************************************************************/ + /* */ + /* Guessing methods to access embedded resource forks */ + /* */ + /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ + /* GNU/Linux). */ + /* */ + /* Resource forks which include fonts data are stored sometimes in */ + /* locations which users or developers don't expected. In some cases, */ + /* resource forks start with some offset from the head of a file. In */ + /* other cases, the actual resource fork is stored in file different */ + /* from what the user specifies. If this option is activated, */ + /* FreeType tries to guess whether such offsets or different file */ + /* names must be used. */ + /* */ + /* Note that normal, direct access of resource forks is controlled via */ + /* the FT_CONFIG_OPTION_MAC_FONTS option. */ + /* */ +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#endif + + + /*************************************************************************/ + /* */ + /* Allow the use of FT_Incremental_Interface to load typefaces that */ + /* contain no glyph data, but supply it via a callback function. */ + /* This allows FreeType to be used with the PostScript language, using */ + /* the GhostScript interpreter. */ + /* */ +/* #define FT_CONFIG_OPTION_INCREMENTAL */ + + + /*************************************************************************/ + /* */ + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ + /* */ + /* This must be greater than 4KByte if you use FreeType to rasterize */ + /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ + /* allocation of the render pool. */ + /* */ +#define FT_RENDER_POOL_SIZE 16384L + + + /*************************************************************************/ + /* */ + /* FT_MAX_MODULES */ + /* */ + /* The maximum number of modules that can be registered in a single */ + /* FreeType library object. 32 is the default. */ + /* */ +#define FT_MAX_MODULES 32 + + + /*************************************************************************/ + /* */ + /* Debug level */ + /* */ + /* FreeType can be compiled in debug or trace mode. In debug mode, */ + /* errors are reported through the `ftdebug' component. In trace */ + /* mode, additional messages are sent to the standard output during */ + /* execution. */ + /* */ + /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ + /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ + /* */ + /* Don't define any of these macros to compile in `release' mode! */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_LEVEL_ERROR */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Memory Debugging */ + /* */ + /* FreeType now comes with an integrated memory debugger that is */ + /* capable of detecting simple errors like memory leaks or double */ + /* deletes. To compile it within your build of the library, you */ + /* should define FT_DEBUG_MEMORY here. */ + /* */ + /* Note that the memory debugger is only activated at runtime when */ + /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_DEBUG_MEMORY */ + + + /*************************************************************************/ + /* */ + /* Module errors */ + /* */ + /* If this macro is set (which is _not_ the default), the higher byte */ + /* of an error code gives the module in which the error has occurred, */ + /* while the lower byte is the real error code. */ + /* */ + /* Setting this macro makes sense for debugging purposes only, since */ + /* it would break source compatibility of certain programs that use */ + /* FreeType 2. */ + /* */ + /* More details can be found in the files ftmoderr.h and fterrors.h. */ + /* */ +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ + /* embedded bitmaps in all formats using the SFNT module (namely */ + /* TrueType & OpenType). */ + /* */ +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ + /* load and enumerate the glyph Postscript names in a TrueType or */ + /* OpenType file. */ + /* */ + /* Note that when you do not compile the `PSNames' module by undefining */ + /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ + /* contain additional code used to read the PS Names table from a font. */ + /* */ + /* (By default, the module uses `PSNames' to extract glyph names.) */ + /* */ +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ + /* access the internal name table in a SFNT-based format like TrueType */ + /* or OpenType. The name table contains various strings used to */ + /* describe the font, like family name, copyright, version, etc. It */ + /* does not contain any glyph name though. */ + /* */ + /* Accessing SFNT names is done through the functions declared in */ + /* `freetype/ftnames.h'. */ + /* */ +#define TT_CONFIG_OPTION_SFNT_NAMES + + + /*************************************************************************/ + /* */ + /* TrueType CMap support */ + /* */ + /* Here you can fine-tune which TrueType CMap table format shall be */ + /* supported. */ +#define TT_CONFIG_CMAP_FORMAT_0 +#define TT_CONFIG_CMAP_FORMAT_2 +#define TT_CONFIG_CMAP_FORMAT_4 +#define TT_CONFIG_CMAP_FORMAT_6 +#define TT_CONFIG_CMAP_FORMAT_8 +#define TT_CONFIG_CMAP_FORMAT_10 +#define TT_CONFIG_CMAP_FORMAT_12 +#define TT_CONFIG_CMAP_FORMAT_14 + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ + /* a bytecode interpreter in the TrueType driver. Note that there are */ + /* important patent issues related to the use of the interpreter. */ + /* */ + /* By undefining this, you will only compile the code necessary to load */ + /* TrueType glyphs without hinting. */ + /* */ + /* Do not #undef this macro here, since the build system might */ + /* define it for certain configurations only. */ + /* */ +/* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ + /* of the TrueType bytecode interpreter is used that doesn't implement */ + /* any of the patented opcodes and algorithms. Note that the */ + /* the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* if you */ + /* define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; with other words, */ + /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ + /* */ + /* This macro is only useful for a small number of font files (mostly */ + /* for Asian scripts) that require bytecode interpretation to properly */ + /* load glyphs. For all other fonts, this produces unpleasant results, */ + /* thus the unpatented interpreter is never used to load glyphs from */ + /* TrueType fonts unless one of the following two options is used. */ + /* */ + /* - The unpatented interpreter is explicitly activated by the user */ + /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ + /* when opening the FT_Face. */ + /* */ + /* - FreeType detects that the FT_Face corresponds to one of the */ + /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ + /* contains a hard-coded list of font names and other matching */ + /* parameters (see function `tt_face_init' in file */ + /* `src/truetype/ttobjs.c'). */ + /* */ + /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ + /* */ + /* { */ + /* FT_Parameter parameter; */ + /* FT_Open_Args open_args; */ + /* */ + /* */ + /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ + /* */ + /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ + /* open_args.pathname = my_font_pathname; */ + /* open_args.num_params = 1; */ + /* open_args.params = ¶meter; */ + /* */ + /* error = FT_Open_Face( library, &open_args, index, &face ); */ + /* ... */ + /* } */ + /* */ +#define TT_CONFIG_OPTION_UNPATENTED_HINTING + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ + /* bytecode interpreter with a huge switch statement, rather than a call */ + /* table. This results in smaller and faster code for a number of */ + /* architectures. */ + /* */ + /* Note however that on some compiler/processor combinations, undefining */ + /* this macro will generate faster, though larger, code. */ + /* */ +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ + /* TrueType glyph loader to use Apple's definition of how to handle */ + /* component offsets in composite glyphs. */ + /* */ + /* Apple and MS disagree on the default behavior of component offsets */ + /* in composites. Apple says that they should be scaled by the scaling */ + /* factors in the transformation matrix (roughly, it's more complex) */ + /* while MS says they should not. OpenType defines two bits in the */ + /* composite flags array which can be used to disambiguate, but old */ + /* fonts will not have them. */ + /* */ + /* http://partners.adobe.com/asn/developer/opentype/glyf.html */ + /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ + /* */ +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ + /* support for Apple's distortable font technology (fvar, gvar, cvar, */ + /* and avar tables). This has many similarities to Type 1 Multiple */ + /* Masters support. */ + /* */ +#define TT_CONFIG_OPTION_GX_VAR_SUPPORT + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ + /* an embedded `BDF ' table within SFNT-based bitmap formats. */ + /* */ +#define TT_CONFIG_OPTION_BDF + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ + /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ + /* required. */ + /* */ +#define T1_MAX_DICT_DEPTH 5 + + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 16 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ + /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ + /* files into an existing face. Note that if set, the T1 driver will be */ + /* unable to produce kerning distances. */ + /* */ +#undef T1_CONFIG_OPTION_NO_AFM + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of the Multiple Masters font support in the Type 1 */ + /* driver. */ + /* */ +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ + /* support. */ + /* */ +#define AF_CONFIG_OPTION_CJK + + /*************************************************************************/ + /* */ + /* Compile autofit module with Indic script support. */ + /* */ +#define AF_CONFIG_OPTION_INDIC + + /* */ + + + /* + * Define this variable if you want to keep the layout of internal + * structures that was used prior to FreeType 2.2. This also compiles in + * a few obsolete functions to avoid linking problems on typical Unix + * distributions. + * + * For embedded systems or building a new distribution from scratch, it + * is recommended to disable the macro since it reduces the library's code + * size and activates a few memory-saving optimizations as well. + */ +#define FT_CONFIG_OPTION_OLD_INTERNALS + + + /* + * This variable is defined if either unpatented or native TrueType + * hinting is requested by the definitions above. + */ +#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#define TT_USE_BYTECODE_INTERPRETER +#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING +#define TT_USE_BYTECODE_INTERPRETER +#endif + +FT_END_HEADER + + +#endif /* __FTOPTION_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/config/ftstdlib.h b/utils/openttd/freetype/config/ftstdlib.h new file mode 100644 index 00000000000..f923f3e4cf8 --- /dev/null +++ b/utils/openttd/freetype/config/ftstdlib.h @@ -0,0 +1,180 @@ +/***************************************************************************/ +/* */ +/* ftstdlib.h */ +/* */ +/* ANSI-specific library and header configuration file (specification */ +/* only). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to group all #includes to the ANSI C library that */ + /* FreeType normally requires. It also defines macros to rename the */ + /* standard functions within the FreeType source code. */ + /* */ + /* Load a file which defines __FTSTDLIB_H__ before this one to override */ + /* it. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSTDLIB_H__ +#define __FTSTDLIB_H__ + + +#include <stddef.h> + +#define ft_ptrdiff_t ptrdiff_t + + + /**********************************************************************/ + /* */ + /* integer limits */ + /* */ + /* UINT_MAX and ULONG_MAX are used to automatically compute the size */ + /* of `int' and `long' in bytes at compile-time. So far, this works */ + /* for all platforms the library has been tested on. */ + /* */ + /* Note that on the extremely rare platforms that do not provide */ + /* integer types that are _exactly_ 16 and 32 bits wide (e.g. some */ + /* old Crays where `int' is 36 bits), we do not make any guarantee */ + /* about the correct behaviour of FT2 with all fonts. */ + /* */ + /* In these case, `ftconfig.h' will refuse to compile anyway with a */ + /* message like `couldn't find 32-bit type' or something similar. */ + /* */ + /* IMPORTANT NOTE: We do not define aliases for heap management and */ + /* i/o routines (i.e. malloc/free/fopen/fread/...) */ + /* since these functions should all be encapsulated */ + /* by platform-specific implementations of */ + /* `ftsystem.c'. */ + /* */ + /**********************************************************************/ + + +#include <limits.h> + +#define FT_CHAR_BIT CHAR_BIT +#define FT_INT_MAX INT_MAX +#define FT_UINT_MAX UINT_MAX +#define FT_ULONG_MAX ULONG_MAX + + + /**********************************************************************/ + /* */ + /* character and string processing */ + /* */ + /**********************************************************************/ + + +#include <string.h> + +#define ft_memchr memchr +#define ft_memcmp memcmp +#define ft_memcpy memcpy +#define ft_memmove memmove +#define ft_memset memset +#define ft_strcat strcat +#define ft_strcmp strcmp +#define ft_strcpy strcpy +#define ft_strlen strlen +#define ft_strncmp strncmp +#define ft_strncpy strncpy +#define ft_strrchr strrchr +#define ft_strstr strstr + + + /**********************************************************************/ + /* */ + /* file handling */ + /* */ + /**********************************************************************/ + + +#include <stdio.h> + +#define FT_FILE FILE +#define ft_fclose fclose +#define ft_fopen fopen +#define ft_fread fread +#define ft_fseek fseek +#define ft_ftell ftell +#define ft_sprintf sprintf + + + /**********************************************************************/ + /* */ + /* sorting */ + /* */ + /**********************************************************************/ + + +#include <stdlib.h> + +#define ft_qsort qsort + +#define ft_exit exit /* only used to exit from unhandled exceptions */ + + + /**********************************************************************/ + /* */ + /* memory allocation */ + /* */ + /**********************************************************************/ + + +#define ft_scalloc calloc +#define ft_sfree free +#define ft_smalloc malloc +#define ft_srealloc realloc + + + /**********************************************************************/ + /* */ + /* miscellaneous */ + /* */ + /**********************************************************************/ + + +#define ft_atol atol +#define ft_labs labs + + + /**********************************************************************/ + /* */ + /* execution control */ + /* */ + /**********************************************************************/ + + +#include <setjmp.h> + +#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ + /* jmp_buf is defined as a macro */ + /* on certain platforms */ + +#define ft_longjmp longjmp +#define ft_setjmp( b ) setjmp( *(jmp_buf*) &(b) ) /* same thing here */ + + + /* the following is only used for debugging purposes, i.e., if */ + /* FT_DEBUG_LEVEL_ERROR or FT_DEBUG_LEVEL_TRACE are defined */ + +#include <stdarg.h> + + +#endif /* __FTSTDLIB_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/freetype.h b/utils/openttd/freetype/freetype.h new file mode 100644 index 00000000000..68dd3ff395a --- /dev/null +++ b/utils/openttd/freetype/freetype.h @@ -0,0 +1,3716 @@ +/***************************************************************************/ +/* */ +/* freetype.h */ +/* */ +/* FreeType high-level API and common types (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef FT_FREETYPE_H +#error "`ft2build.h' hasn't been included yet!" +#error "Please always use macros to include FreeType header files." +#error "Example:" +#error " #include <ft2build.h>" +#error " #include FT_FREETYPE_H" +#endif + + + /*************************************************************************/ + /* */ + /* The `raster' component duplicates some of the declarations in */ + /* freetype.h for stand-alone use if _FREETYPE_ isn't defined. */ + /* */ + /*************************************************************************/ + + +#ifndef __FREETYPE_H__ +#define __FREETYPE_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_ERRORS_H +#include FT_TYPES_H + + +FT_BEGIN_HEADER + + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* user_allocation */ + /* */ + /* <Title> */ + /* User allocation */ + /* */ + /* <Abstract> */ + /* How client applications should allocate FreeType data structures. */ + /* */ + /* <Description> */ + /* FreeType assumes that structures allocated by the user and passed */ + /* as arguments are zeroed out except for the actual data. With */ + /* other words, it is recommended to use `calloc' (or variants of it) */ + /* instead of `malloc' for allocation. */ + /* */ + /*************************************************************************/ + + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S I C T Y P E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* base_interface */ + /* */ + /* <Title> */ + /* Base Interface */ + /* */ + /* <Abstract> */ + /* The FreeType~2 base font interface. */ + /* */ + /* <Description> */ + /* This section describes the public high-level API of FreeType~2. */ + /* */ + /* <Order> */ + /* FT_Library */ + /* FT_Face */ + /* FT_Size */ + /* FT_GlyphSlot */ + /* FT_CharMap */ + /* FT_Encoding */ + /* */ + /* FT_FaceRec */ + /* */ + /* FT_FACE_FLAG_SCALABLE */ + /* FT_FACE_FLAG_FIXED_SIZES */ + /* FT_FACE_FLAG_FIXED_WIDTH */ + /* FT_FACE_FLAG_HORIZONTAL */ + /* FT_FACE_FLAG_VERTICAL */ + /* FT_FACE_FLAG_SFNT */ + /* FT_FACE_FLAG_KERNING */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS */ + /* FT_FACE_FLAG_GLYPH_NAMES */ + /* FT_FACE_FLAG_EXTERNAL_STREAM */ + /* FT_FACE_FLAG_FAST_GLYPHS */ + /* FT_FACE_FLAG_HINTER */ + /* */ + /* FT_STYLE_FLAG_BOLD */ + /* FT_STYLE_FLAG_ITALIC */ + /* */ + /* FT_SizeRec */ + /* FT_Size_Metrics */ + /* */ + /* FT_GlyphSlotRec */ + /* FT_Glyph_Metrics */ + /* FT_SubGlyph */ + /* */ + /* FT_Bitmap_Size */ + /* */ + /* FT_Init_FreeType */ + /* FT_Done_FreeType */ + /* */ + /* FT_New_Face */ + /* FT_Done_Face */ + /* FT_New_Memory_Face */ + /* FT_Open_Face */ + /* FT_Open_Args */ + /* FT_Parameter */ + /* FT_Attach_File */ + /* FT_Attach_Stream */ + /* */ + /* FT_Set_Char_Size */ + /* FT_Set_Pixel_Sizes */ + /* FT_Request_Size */ + /* FT_Select_Size */ + /* FT_Size_Request_Type */ + /* FT_Size_Request */ + /* FT_Set_Transform */ + /* FT_Load_Glyph */ + /* FT_Get_Char_Index */ + /* FT_Get_Name_Index */ + /* FT_Load_Char */ + /* */ + /* FT_OPEN_MEMORY */ + /* FT_OPEN_STREAM */ + /* FT_OPEN_PATHNAME */ + /* FT_OPEN_DRIVER */ + /* FT_OPEN_PARAMS */ + /* */ + /* FT_LOAD_DEFAULT */ + /* FT_LOAD_RENDER */ + /* FT_LOAD_MONOCHROME */ + /* FT_LOAD_LINEAR_DESIGN */ + /* FT_LOAD_NO_SCALE */ + /* FT_LOAD_NO_HINTING */ + /* FT_LOAD_NO_BITMAP */ + /* FT_LOAD_CROP_BITMAP */ + /* */ + /* FT_LOAD_VERTICAL_LAYOUT */ + /* FT_LOAD_IGNORE_TRANSFORM */ + /* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */ + /* FT_LOAD_FORCE_AUTOHINT */ + /* FT_LOAD_NO_RECURSE */ + /* FT_LOAD_PEDANTIC */ + /* */ + /* FT_LOAD_TARGET_NORMAL */ + /* FT_LOAD_TARGET_LIGHT */ + /* FT_LOAD_TARGET_MONO */ + /* FT_LOAD_TARGET_LCD */ + /* FT_LOAD_TARGET_LCD_V */ + /* */ + /* FT_Render_Glyph */ + /* FT_Render_Mode */ + /* FT_Get_Kerning */ + /* FT_Kerning_Mode */ + /* FT_Get_Track_Kerning */ + /* FT_Get_Glyph_Name */ + /* FT_Get_Postscript_Name */ + /* */ + /* FT_CharMapRec */ + /* FT_Select_Charmap */ + /* FT_Set_Charmap */ + /* FT_Get_Charmap_Index */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Glyph_Metrics */ + /* */ + /* <Description> */ + /* A structure used to model the metrics of a single glyph. The */ + /* values are expressed in 26.6 fractional pixel format; if the flag */ + /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ + /* are expressed in font units instead. */ + /* */ + /* <Fields> */ + /* width :: */ + /* The glyph's width. */ + /* */ + /* height :: */ + /* The glyph's height. */ + /* */ + /* horiBearingX :: */ + /* Left side bearing for horizontal layout. */ + /* */ + /* horiBearingY :: */ + /* Top side bearing for horizontal layout. */ + /* */ + /* horiAdvance :: */ + /* Advance width for horizontal layout. */ + /* */ + /* vertBearingX :: */ + /* Left side bearing for vertical layout. */ + /* */ + /* vertBearingY :: */ + /* Top side bearing for vertical layout. */ + /* */ + /* vertAdvance :: */ + /* Advance height for vertical layout. */ + /* */ + typedef struct FT_Glyph_Metrics_ + { + FT_Pos width; + FT_Pos height; + + FT_Pos horiBearingX; + FT_Pos horiBearingY; + FT_Pos horiAdvance; + + FT_Pos vertBearingX; + FT_Pos vertBearingY; + FT_Pos vertAdvance; + + } FT_Glyph_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap_Size */ + /* */ + /* <Description> */ + /* This structure models the metrics of a bitmap strike (i.e., a set */ + /* of glyphs for a given point size and resolution) in a bitmap font. */ + /* It is used for the `available_sizes' field of @FT_Face. */ + /* */ + /* <Fields> */ + /* height :: The vertical distance, in pixels, between two */ + /* consecutive baselines. It is always positive. */ + /* */ + /* width :: The average width, in pixels, of all glyphs in the */ + /* strike. */ + /* */ + /* size :: The nominal size of the strike in 26.6 fractional */ + /* points. This field is not very useful. */ + /* */ + /* x_ppem :: The horizontal ppem (nominal width) in 26.6 fractional */ + /* pixels. */ + /* */ + /* y_ppem :: The vertical ppem (nominal height) in 26.6 fractional */ + /* pixels. */ + /* */ + /* <Note> */ + /* Windows FNT: */ + /* The nominal size given in a FNT font is not reliable. Thus when */ + /* the driver finds it incorrect, it sets `size' to some calculated */ + /* values and sets `x_ppem' and `y_ppem' to the pixel width and */ + /* height given in the font, respectively. */ + /* */ + /* TrueType embedded bitmaps: */ + /* `size', `width', and `height' values are not contained in the */ + /* bitmap strike itself. They are computed from the global font */ + /* parameters. */ + /* */ + typedef struct FT_Bitmap_Size_ + { + FT_Short height; + FT_Short width; + + FT_Pos size; + + FT_Pos x_ppem; + FT_Pos y_ppem; + + } FT_Bitmap_Size; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Library */ + /* */ + /* <Description> */ + /* A handle to a FreeType library instance. Each `library' is */ + /* completely independent from the others; it is the `root' of a set */ + /* of objects like fonts, faces, sizes, etc. */ + /* */ + /* It also embeds a memory manager (see @FT_Memory), as well as a */ + /* scan-line converter object (see @FT_Raster). */ + /* */ + /* For multi-threading applications each thread should have its own */ + /* FT_Library object. */ + /* */ + /* <Note> */ + /* Library objects are normally created by @FT_Init_FreeType, and */ + /* destroyed with @FT_Done_FreeType. */ + /* */ + typedef struct FT_LibraryRec_ *FT_Library; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Module */ + /* */ + /* <Description> */ + /* A handle to a given FreeType module object. Each module can be a */ + /* font driver, a renderer, or anything else that provides services */ + /* to the formers. */ + /* */ + typedef struct FT_ModuleRec_* FT_Module; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Driver */ + /* */ + /* <Description> */ + /* A handle to a given FreeType font driver object. Each font driver */ + /* is a special module capable of creating faces from font files. */ + /* */ + typedef struct FT_DriverRec_* FT_Driver; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Renderer */ + /* */ + /* <Description> */ + /* A handle to a given FreeType renderer. A renderer is a special */ + /* module in charge of converting a glyph image to a bitmap, when */ + /* necessary. Each renderer supports a given glyph image format, and */ + /* one or more target surface depths. */ + /* */ + typedef struct FT_RendererRec_* FT_Renderer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face */ + /* */ + /* <Description> */ + /* A handle to a given typographic face object. A face object models */ + /* a given typeface, in a given style. */ + /* */ + /* <Note> */ + /* Each face object also owns a single @FT_GlyphSlot object, as well */ + /* as one or more @FT_Size objects. */ + /* */ + /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ + /* a given filepathname or a custom input stream. */ + /* */ + /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ + /* */ + /* <Also> */ + /* The @FT_FaceRec details the publicly accessible fields of a given */ + /* face object. */ + /* */ + typedef struct FT_FaceRec_* FT_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size */ + /* */ + /* <Description> */ + /* A handle to an object used to model a face scaled to a given */ + /* character size. */ + /* */ + /* <Note> */ + /* Each @FT_Face has an _active_ @FT_Size object that is used by */ + /* functions like @FT_Load_Glyph to determine the scaling */ + /* transformation which is used to load and hint glyphs and metrics. */ + /* */ + /* You can use @FT_Set_Char_Size, @FT_Set_Pixel_Sizes, */ + /* @FT_Request_Size or even @FT_Select_Size to change the content */ + /* (i.e., the scaling values) of the active @FT_Size. */ + /* */ + /* You can use @FT_New_Size to create additional size objects for a */ + /* given @FT_Face, but they won't be used by other functions until */ + /* you activate it through @FT_Activate_Size. Only one size can be */ + /* activated at any given time per face. */ + /* */ + /* <Also> */ + /* The @FT_SizeRec structure details the publicly accessible fields */ + /* of a given size object. */ + /* */ + typedef struct FT_SizeRec_* FT_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to a given `glyph slot'. A slot is a container where it */ + /* is possible to load any one of the glyphs contained in its parent */ + /* face. */ + /* */ + /* In other words, each time you call @FT_Load_Glyph or */ + /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ + /* i.e., the glyph's metrics, its image (bitmap or outline), and */ + /* other control information. */ + /* */ + /* <Also> */ + /* @FT_GlyphSlotRec details the publicly accessible glyph fields. */ + /* */ + typedef struct FT_GlyphSlotRec_* FT_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_CharMap */ + /* */ + /* <Description> */ + /* A handle to a given character map. A charmap is used to translate */ + /* character codes in a given encoding into glyph indexes for its */ + /* parent's face. Some font formats may provide several charmaps per */ + /* font. */ + /* */ + /* Each face object owns zero or more charmaps, but only one of them */ + /* can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char. */ + /* */ + /* The list of available charmaps in a face is available through the */ + /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ + /* */ + /* The currently active charmap is available as `face->charmap'. */ + /* You should call @FT_Set_Charmap to change it. */ + /* */ + /* <Note> */ + /* When a new face is created (either through @FT_New_Face or */ + /* @FT_Open_Face), the library looks for a Unicode charmap within */ + /* the list and automatically activates it. */ + /* */ + /* <Also> */ + /* The @FT_CharMapRec details the publicly accessible fields of a */ + /* given character map. */ + /* */ + typedef struct FT_CharMapRec_* FT_CharMap; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_ENC_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags into an unsigned long. It is */ + /* used to define `encoding' identifiers (see @FT_Encoding). */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_ENC_TAG( value, a, b, c, d ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ + +#ifndef FT_ENC_TAG +#define FT_ENC_TAG( value, a, b, c, d ) \ + value = ( ( (FT_UInt32)(a) << 24 ) | \ + ( (FT_UInt32)(b) << 16 ) | \ + ( (FT_UInt32)(c) << 8 ) | \ + (FT_UInt32)(d) ) + +#endif /* FT_ENC_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Encoding */ + /* */ + /* <Description> */ + /* An enumeration used to specify character sets supported by */ + /* charmaps. Used in the @FT_Select_Charmap API function. */ + /* */ + /* <Note> */ + /* Despite the name, this enumeration lists specific character */ + /* repertories (i.e., charsets), and not text encoding methods (e.g., */ + /* UTF-8, UTF-16, GB2312_EUC, etc.). */ + /* */ + /* Because of 32-bit charcodes defined in Unicode (i.e., surrogates), */ + /* all character codes must be expressed as FT_Longs. */ + /* */ + /* Other encodings might be defined in the future. */ + /* */ + /* <Values> */ + /* FT_ENCODING_NONE :: */ + /* The encoding value~0 is reserved. */ + /* */ + /* FT_ENCODING_UNICODE :: */ + /* Corresponds to the Unicode character set. This value covers */ + /* all versions of the Unicode repertoire, including ASCII and */ + /* Latin-1. Most fonts include a Unicode charmap, but not all */ + /* of them. */ + /* */ + /* FT_ENCODING_MS_SYMBOL :: */ + /* Corresponds to the Microsoft Symbol encoding, used to encode */ + /* mathematical symbols in the 32..255 character code range. For */ + /* more information, see `http://www.ceviz.net/symbol.htm'. */ + /* */ + /* FT_ENCODING_SJIS :: */ + /* Corresponds to Japanese SJIS encoding. More info at */ + /* at `http://langsupport.japanreference.com/encoding.shtml'. */ + /* See note on multi-byte encodings below. */ + /* */ + /* FT_ENCODING_GB2312 :: */ + /* Corresponds to an encoding system for Simplified Chinese as used */ + /* used in mainland China. */ + /* */ + /* FT_ENCODING_BIG5 :: */ + /* Corresponds to an encoding system for Traditional Chinese as used */ + /* in Taiwan and Hong Kong. */ + /* */ + /* FT_ENCODING_WANSUNG :: */ + /* Corresponds to the Korean encoding system known as Wansung. */ + /* For more information see */ + /* `http://www.microsoft.com/typography/unicode/949.txt'. */ + /* */ + /* FT_ENCODING_JOHAB :: */ + /* The Korean standard character set (KS~C 5601-1992), which */ + /* corresponds to MS Windows code page 1361. This character set */ + /* includes all possible Hangeul character combinations. */ + /* */ + /* FT_ENCODING_ADOBE_LATIN_1 :: */ + /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ + /* PostScript font. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_ADOBE_STANDARD :: */ + /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_EXPERT :: */ + /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ + /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ + /* codes. */ + /* */ + /* FT_ENCODING_ADOBE_CUSTOM :: */ + /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ + /* */ + /* FT_ENCODING_APPLE_ROMAN :: */ + /* Corresponds to the 8-bit Apple roman encoding. Many TrueType and */ + /* OpenType fonts contain a charmap for this encoding, since older */ + /* versions of Mac OS are able to use it. */ + /* */ + /* FT_ENCODING_OLD_LATIN_2 :: */ + /* This value is deprecated and was never used nor reported by */ + /* FreeType. Don't use or test for it. */ + /* */ + /* FT_ENCODING_MS_SJIS :: */ + /* Same as FT_ENCODING_SJIS. Deprecated. */ + /* */ + /* FT_ENCODING_MS_GB2312 :: */ + /* Same as FT_ENCODING_GB2312. Deprecated. */ + /* */ + /* FT_ENCODING_MS_BIG5 :: */ + /* Same as FT_ENCODING_BIG5. Deprecated. */ + /* */ + /* FT_ENCODING_MS_WANSUNG :: */ + /* Same as FT_ENCODING_WANSUNG. Deprecated. */ + /* */ + /* FT_ENCODING_MS_JOHAB :: */ + /* Same as FT_ENCODING_JOHAB. Deprecated. */ + /* */ + /* <Note> */ + /* By default, FreeType automatically synthetizes a Unicode charmap */ + /* for PostScript fonts, using their glyph names dictionaries. */ + /* However, it also reports the encodings defined explicitly in the */ + /* font file, for the cases when they are needed, with the Adobe */ + /* values as well. */ + /* */ + /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ + /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ + /* FT_ENCODING_UNICODE). Use @FT_Get_BDF_Charset_ID to find out which */ + /* encoding is really present. If, for example, the `cs_registry' */ + /* field is `KOI8' and the `cs_encoding' field is `R', the font is */ + /* encoded in KOI8-R. */ + /* */ + /* FT_ENCODING_NONE is always set (with a single exception) by the */ + /* winfonts driver. Use @FT_Get_WinFNT_Header and examine the */ + /* `charset' field of the @FT_WinFNT_HeaderRec structure to find out */ + /* which encoding is really present. For example, */ + /* @FT_WinFNT_ID_CP1251 (204) means Windows code page 1251 (for */ + /* Russian). */ + /* */ + /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ + /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ + /* FT_ENCODING_APPLE_ROMAN). */ + /* */ + /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ + /* @FT_Get_CMap_Language_ID to query the Mac language ID which may be */ + /* needed to be able to distinguish Apple encoding variants. See */ + /* */ + /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/README.TXT */ + /* */ + /* to get an idea how to do that. Basically, if the language ID is~0, */ + /* don't use it, otherwise subtract 1 from the language ID. Then */ + /* examine `encoding_id'. If, for example, `encoding_id' is */ + /* @TT_MAC_ID_ROMAN and the language ID (minus~1) is */ + /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ + /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ + /* variant the Arabic encoding. */ + /* */ + typedef enum FT_Encoding_ + { + FT_ENC_TAG( FT_ENCODING_NONE, 0, 0, 0, 0 ), + + FT_ENC_TAG( FT_ENCODING_MS_SYMBOL, 's', 'y', 'm', 'b' ), + FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), + + FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ), + FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ), + FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ), + FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ), + FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ), + + /* for backwards compatibility */ + FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS, + FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312, + FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5, + FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG, + FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB, + + FT_ENC_TAG( FT_ENCODING_ADOBE_STANDARD, 'A', 'D', 'O', 'B' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_EXPERT, 'A', 'D', 'B', 'E' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_CUSTOM, 'A', 'D', 'B', 'C' ), + FT_ENC_TAG( FT_ENCODING_ADOBE_LATIN_1, 'l', 'a', 't', '1' ), + + FT_ENC_TAG( FT_ENCODING_OLD_LATIN_2, 'l', 'a', 't', '2' ), + + FT_ENC_TAG( FT_ENCODING_APPLE_ROMAN, 'a', 'r', 'm', 'n' ) + + } FT_Encoding; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_encoding_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated; use the corresponding @FT_Encoding */ + /* values instead. */ + /* */ +#define ft_encoding_none FT_ENCODING_NONE +#define ft_encoding_unicode FT_ENCODING_UNICODE +#define ft_encoding_symbol FT_ENCODING_MS_SYMBOL +#define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 +#define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 +#define ft_encoding_sjis FT_ENCODING_SJIS +#define ft_encoding_gb2312 FT_ENCODING_GB2312 +#define ft_encoding_big5 FT_ENCODING_BIG5 +#define ft_encoding_wansung FT_ENCODING_WANSUNG +#define ft_encoding_johab FT_ENCODING_JOHAB + +#define ft_encoding_adobe_standard FT_ENCODING_ADOBE_STANDARD +#define ft_encoding_adobe_expert FT_ENCODING_ADOBE_EXPERT +#define ft_encoding_adobe_custom FT_ENCODING_ADOBE_CUSTOM +#define ft_encoding_apple_roman FT_ENCODING_APPLE_ROMAN + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_CharMapRec */ + /* */ + /* <Description> */ + /* The base charmap structure. */ + /* */ + /* <Fields> */ + /* face :: A handle to the parent face object. */ + /* */ + /* encoding :: An @FT_Encoding tag identifying the charmap. Use */ + /* this with @FT_Select_Charmap. */ + /* */ + /* platform_id :: An ID number describing the platform for the */ + /* following encoding ID. This comes directly from */ + /* the TrueType specification and should be emulated */ + /* for other formats. */ + /* */ + /* encoding_id :: A platform specific encoding number. This also */ + /* comes from the TrueType specification and should be */ + /* emulated similarly. */ + /* */ + typedef struct FT_CharMapRec_ + { + FT_Face face; + FT_Encoding encoding; + FT_UShort platform_id; + FT_UShort encoding_id; + + } FT_CharMapRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* B A S E O B J E C T C L A S S E S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Face_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ + /* model private data of a given @FT_Face object. */ + /* */ + /* This structure might change between releases of FreeType~2 and is */ + /* not generally available to client applications. */ + /* */ + typedef struct FT_Face_InternalRec_* FT_Face_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_FaceRec */ + /* */ + /* <Description> */ + /* FreeType root face class structure. A face object models a */ + /* typeface in a font file. */ + /* */ + /* <Fields> */ + /* num_faces :: The number of faces in the font file. Some */ + /* font formats can have multiple faces in */ + /* a font file. */ + /* */ + /* face_index :: The index of the face in the font file. It */ + /* is set to~0 if there is only one face in */ + /* the font file. */ + /* */ + /* face_flags :: A set of bit flags that give important */ + /* information about the face; see */ + /* @FT_FACE_FLAG_XXX for the details. */ + /* */ + /* style_flags :: A set of bit flags indicating the style of */ + /* the face; see @FT_STYLE_FLAG_XXX for the */ + /* details. */ + /* */ + /* num_glyphs :: The number of glyphs in the face. If the */ + /* face is scalable and has sbits (see */ + /* `num_fixed_sizes'), it is set to the number */ + /* of outline glyphs. */ + /* */ + /* For CID-keyed fonts, this value gives the */ + /* highest CID used in the font. */ + /* */ + /* family_name :: The face's family name. This is an ASCII */ + /* string, usually in English, which describes */ + /* the typeface's family (like `Times New */ + /* Roman', `Bodoni', `Garamond', etc). This */ + /* is a least common denominator used to list */ + /* fonts. Some formats (TrueType & OpenType) */ + /* provide localized and Unicode versions of */ + /* this string. Applications should use the */ + /* format specific interface to access them. */ + /* Can be NULL (e.g., in fonts embedded in a */ + /* PDF file). */ + /* */ + /* style_name :: The face's style name. This is an ASCII */ + /* string, usually in English, which describes */ + /* the typeface's style (like `Italic', */ + /* `Bold', `Condensed', etc). Not all font */ + /* formats provide a style name, so this field */ + /* is optional, and can be set to NULL. As */ + /* for `family_name', some formats provide */ + /* localized and Unicode versions of this */ + /* string. Applications should use the format */ + /* specific interface to access them. */ + /* */ + /* num_fixed_sizes :: The number of bitmap strikes in the face. */ + /* Even if the face is scalable, there might */ + /* still be bitmap strikes, which are called */ + /* `sbits' in that case. */ + /* */ + /* available_sizes :: An array of @FT_Bitmap_Size for all bitmap */ + /* strikes in the face. It is set to NULL if */ + /* there is no bitmap strike. */ + /* */ + /* num_charmaps :: The number of charmaps in the face. */ + /* */ + /* charmaps :: An array of the charmaps of the face. */ + /* */ + /* generic :: A field reserved for client uses. See the */ + /* @FT_Generic type description. */ + /* */ + /* bbox :: The font bounding box. Coordinates are */ + /* expressed in font units (see */ + /* `units_per_EM'). The box is large enough */ + /* to contain any glyph from the font. Thus, */ + /* `bbox.yMax' can be seen as the `maximal */ + /* ascender', and `bbox.yMin' as the `minimal */ + /* descender'. Only relevant for scalable */ + /* formats. */ + /* */ + /* Note that the bounding box might be off by */ + /* (at least) one pixel for hinted fonts. See */ + /* @FT_Size_Metrics for further discussion. */ + /* */ + /* units_per_EM :: The number of font units per EM square for */ + /* this face. This is typically 2048 for */ + /* TrueType fonts, and 1000 for Type~1 fonts. */ + /* Only relevant for scalable formats. */ + /* */ + /* ascender :: The typographic ascender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMax'. Only relevant for scalable */ + /* formats. */ + /* */ + /* descender :: The typographic descender of the face, */ + /* expressed in font units. For font formats */ + /* not having this information, it is set to */ + /* `bbox.yMin'. Note that this field is */ + /* usually negative. Only relevant for */ + /* scalable formats. */ + /* */ + /* height :: The height is the vertical distance */ + /* between two consecutive baselines, */ + /* expressed in font units. It is always */ + /* positive. Only relevant for scalable */ + /* formats. */ + /* */ + /* max_advance_width :: The maximal advance width, in font units, */ + /* for all glyphs in this face. This can be */ + /* used to make word wrapping computations */ + /* faster. Only relevant for scalable */ + /* formats. */ + /* */ + /* max_advance_height :: The maximal advance height, in font units, */ + /* for all glyphs in this face. This is only */ + /* relevant for vertical layouts, and is set */ + /* to `height' for fonts that do not provide */ + /* vertical metrics. Only relevant for */ + /* scalable formats. */ + /* */ + /* underline_position :: The position, in font units, of the */ + /* underline line for this face. It's the */ + /* center of the underlining stem. Only */ + /* relevant for scalable formats. */ + /* */ + /* underline_thickness :: The thickness, in font units, of the */ + /* underline for this face. Only relevant for */ + /* scalable formats. */ + /* */ + /* glyph :: The face's associated glyph slot(s). */ + /* */ + /* size :: The current active size for this face. */ + /* */ + /* charmap :: The current active charmap for this face. */ + /* */ + /* <Note> */ + /* Fields may be changed after a call to @FT_Attach_File or */ + /* @FT_Attach_Stream. */ + /* */ + typedef struct FT_FaceRec_ + { + FT_Long num_faces; + FT_Long face_index; + + FT_Long face_flags; + FT_Long style_flags; + + FT_Long num_glyphs; + + FT_String* family_name; + FT_String* style_name; + + FT_Int num_fixed_sizes; + FT_Bitmap_Size* available_sizes; + + FT_Int num_charmaps; + FT_CharMap* charmaps; + + FT_Generic generic; + + /*# The following member variables (down to `underline_thickness') */ + /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */ + /*# for bitmap fonts. */ + FT_BBox bbox; + + FT_UShort units_per_EM; + FT_Short ascender; + FT_Short descender; + FT_Short height; + + FT_Short max_advance_width; + FT_Short max_advance_height; + + FT_Short underline_position; + FT_Short underline_thickness; + + FT_GlyphSlot glyph; + FT_Size size; + FT_CharMap charmap; + + /*@private begin */ + + FT_Driver driver; + FT_Memory memory; + FT_Stream stream; + + FT_ListRec sizes_list; + + FT_Generic autohint; + void* extensions; + + FT_Face_Internal internal; + + /*@private end */ + + } FT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_FACE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the `face_flags' field of the */ + /* @FT_FaceRec structure. They inform client applications of */ + /* properties of the corresponding face. */ + /* */ + /* <Values> */ + /* FT_FACE_FLAG_SCALABLE :: */ + /* Indicates that the face contains outline glyphs. This doesn't */ + /* prevent bitmap strikes, i.e., a face can have both this and */ + /* and @FT_FACE_FLAG_FIXED_SIZES set. */ + /* */ + /* FT_FACE_FLAG_FIXED_SIZES :: */ + /* Indicates that the face contains bitmap strikes. See also the */ + /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ + /* */ + /* FT_FACE_FLAG_FIXED_WIDTH :: */ + /* Indicates that the face contains fixed-width characters (like */ + /* Courier, Lucido, MonoType, etc.). */ + /* */ + /* FT_FACE_FLAG_SFNT :: */ + /* Indicates that the face uses the `sfnt' storage scheme. For */ + /* now, this means TrueType and OpenType. */ + /* */ + /* FT_FACE_FLAG_HORIZONTAL :: */ + /* Indicates that the face contains horizontal glyph metrics. This */ + /* should be set for all common formats. */ + /* */ + /* FT_FACE_FLAG_VERTICAL :: */ + /* Indicates that the face contains vertical glyph metrics. This */ + /* is only available in some formats, not all of them. */ + /* */ + /* FT_FACE_FLAG_KERNING :: */ + /* Indicates that the face contains kerning information. If set, */ + /* the kerning distance can be retrieved through the function */ + /* @FT_Get_Kerning. Otherwise the function always return the */ + /* vector (0,0). Note that FreeType doesn't handle kerning data */ + /* from the `GPOS' table (as present in some OpenType fonts). */ + /* */ + /* FT_FACE_FLAG_FAST_GLYPHS :: */ + /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ + /* */ + /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ + /* Indicates that the font contains multiple masters and is capable */ + /* of interpolating between them. See the multiple-masters */ + /* specific API for details. */ + /* */ + /* FT_FACE_FLAG_GLYPH_NAMES :: */ + /* Indicates that the font contains glyph names that can be */ + /* retrieved through @FT_Get_Glyph_Name. Note that some TrueType */ + /* fonts contain broken glyph name tables. Use the function */ + /* @FT_Has_PS_Glyph_Names when needed. */ + /* */ + /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ + /* Used internally by FreeType to indicate that a face's stream was */ + /* provided by the client application and should not be destroyed */ + /* when @FT_Done_Face is called. Don't read or test this flag. */ + /* */ + /* FT_FACE_FLAG_HINTER :: */ + /* Set if the font driver has a hinting machine of its own. For */ + /* example, with TrueType fonts, it makes sense to use data from */ + /* the SFNT `gasp' table only if the native TrueType hinting engine */ + /* (with the bytecode interpreter) is available and active. */ + /* */ + /* FT_FACE_FLAG_CID_KEYED :: */ + /* Set if the font is CID-keyed. In that case, the font is not */ + /* accessed by glyph indices but by CID values. For subsetted */ + /* CID-keyed fonts this has the consequence that not all index */ + /* values are a valid argument to FT_Load_Glyph. Only the CID */ + /* values for which corresponding glyphs in the subsetted font */ + /* exist make FT_Load_Glyph return successfully; in all other cases */ + /* you get an `FT_Err_Invalid_Argument' error. */ + /* */ +#define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) +#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) +#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 ) +#define FT_FACE_FLAG_SFNT ( 1L << 3 ) +#define FT_FACE_FLAG_HORIZONTAL ( 1L << 4 ) +#define FT_FACE_FLAG_VERTICAL ( 1L << 5 ) +#define FT_FACE_FLAG_KERNING ( 1L << 6 ) +#define FT_FACE_FLAG_FAST_GLYPHS ( 1L << 7 ) +#define FT_FACE_FLAG_MULTIPLE_MASTERS ( 1L << 8 ) +#define FT_FACE_FLAG_GLYPH_NAMES ( 1L << 9 ) +#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 ) +#define FT_FACE_FLAG_HINTER ( 1L << 11 ) +#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) + + /* */ + + + /************************************************************************* + * + * @macro: + * FT_HAS_HORIZONTAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains + * horizontal metrics (this is true for all font formats though). + * + * @also: + * @FT_HAS_VERTICAL can be used to check for vertical metrics. + * + */ +#define FT_HAS_HORIZONTAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_VERTICAL( face ) + * + * @description: + * A macro that returns true whenever a face object contains vertical + * metrics. + * + */ +#define FT_HAS_VERTICAL( face ) \ + ( face->face_flags & FT_FACE_FLAG_VERTICAL ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_KERNING( face ) + * + * @description: + * A macro that returns true whenever a face object contains kerning + * data that can be accessed with @FT_Get_Kerning. + * + */ +#define FT_HAS_KERNING( face ) \ + ( face->face_flags & FT_FACE_FLAG_KERNING ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SCALABLE( face ) + * + * @description: + * A macro that returns true whenever a face object contains a scalable + * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, + * and PFR font formats. + * + */ +#define FT_IS_SCALABLE( face ) \ + ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + + + /************************************************************************* + * + * @macro: + * FT_IS_SFNT( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font + * whose format is based on the SFNT storage scheme. This usually + * means: TrueType fonts, OpenType fonts, as well as SFNT-based embedded + * bitmap fonts. + * + * If this macro is true, all functions defined in @FT_SFNT_NAMES_H and + * @FT_TRUETYPE_TABLES_H are available. + * + */ +#define FT_IS_SFNT( face ) \ + ( face->face_flags & FT_FACE_FLAG_SFNT ) + + + /************************************************************************* + * + * @macro: + * FT_IS_FIXED_WIDTH( face ) + * + * @description: + * A macro that returns true whenever a face object contains a font face + * that contains fixed-width (or `monospace', `fixed-pitch', etc.) + * glyphs. + * + */ +#define FT_IS_FIXED_WIDTH( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_FIXED_SIZES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * embedded bitmaps. See the `available_sizes' field of the + * @FT_FaceRec structure. + * + */ +#define FT_HAS_FIXED_SIZES( face ) \ + ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + + /* */ + + + /************************************************************************* + * + * @macro: + * FT_HAS_FAST_GLYPHS( face ) + * + * @description: + * Deprecated. + * + */ +#define FT_HAS_FAST_GLYPHS( face ) 0 + + + /************************************************************************* + * + * @macro: + * FT_HAS_GLYPH_NAMES( face ) + * + * @description: + * A macro that returns true whenever a face object contains some glyph + * names that can be accessed through @FT_Get_Glyph_Name. + * + */ +#define FT_HAS_GLYPH_NAMES( face ) \ + ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + + + /************************************************************************* + * + * @macro: + * FT_HAS_MULTIPLE_MASTERS( face ) + * + * @description: + * A macro that returns true whenever a face object contains some + * multiple masters. The functions provided by @FT_MULTIPLE_MASTERS_H + * are then available to choose the exact design you want. + * + */ +#define FT_HAS_MULTIPLE_MASTERS( face ) \ + ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + + + /************************************************************************* + * + * @macro: + * FT_IS_CID_KEYED( face ) + * + * @description: + * A macro that returns true whenever a face object contains a CID-keyed + * font. See the discussion of @FT_FACE_FLAG_CID_KEYED for more + * details. + * + * If this macro is true, all functions defined in @FT_CID_H are + * available. + * + */ +#define FT_IS_CID_KEYED( face ) \ + ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + + + /*************************************************************************/ + /* */ + /* <Constant> */ + /* FT_STYLE_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit-flags used to indicate the style of a given face. */ + /* These are used in the `style_flags' field of @FT_FaceRec. */ + /* */ + /* <Values> */ + /* FT_STYLE_FLAG_ITALIC :: */ + /* Indicates that a given face style is italic or oblique. */ + /* */ + /* FT_STYLE_FLAG_BOLD :: */ + /* Indicates that a given face is bold. */ + /* */ + /* <Note> */ + /* The style information as provided by FreeType is very basic. More */ + /* details are beyond the scope and should be done on a higher level */ + /* (for example, by analyzing various fields of the `OS/2' table in */ + /* SFNT based fonts). */ + /* */ +#define FT_STYLE_FLAG_ITALIC ( 1 << 0 ) +#define FT_STYLE_FLAG_BOLD ( 1 << 1 ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Size_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Size_InternalRec' structure, used to */ + /* model private data of a given @FT_Size object. */ + /* */ + typedef struct FT_Size_InternalRec_* FT_Size_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Metrics */ + /* */ + /* <Description> */ + /* The size metrics structure gives the metrics of a size object. */ + /* */ + /* <Fields> */ + /* x_ppem :: The width of the scaled EM square in pixels, hence */ + /* the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal width'. */ + /* */ + /* y_ppem :: The height of the scaled EM square in pixels, */ + /* hence the term `ppem' (pixels per EM). It is also */ + /* referred to as `nominal height'. */ + /* */ + /* x_scale :: A 16.16 fractional scaling value used to convert */ + /* horizontal metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* y_scale :: A 16.16 fractional scaling value used to convert */ + /* vertical metrics from font units to 26.6 */ + /* fractional pixels. Only relevant for scalable */ + /* font formats. */ + /* */ + /* ascender :: The ascender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* descender :: The descender in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* height :: The height in 26.6 fractional pixels. See */ + /* @FT_FaceRec for the details. */ + /* */ + /* max_advance :: The maximal advance width in 26.6 fractional */ + /* pixels. See @FT_FaceRec for the details. */ + /* */ + /* <Note> */ + /* The scaling values, if relevant, are determined first during a */ + /* size changing operation. The remaining fields are then set by the */ + /* driver. For scalable formats, they are usually set to scaled */ + /* values of the corresponding fields in @FT_FaceRec. */ + /* */ + /* Note that due to glyph hinting, these values might not be exact */ + /* for certain fonts. Thus they must be treated as unreliable */ + /* with an error margin of at least one pixel! */ + /* */ + /* Indeed, the only way to get the exact metrics is to render _all_ */ + /* glyphs. As this would be a definite performance hit, it is up to */ + /* client applications to perform such computations. */ + /* */ + /* The FT_Size_Metrics structure is valid for bitmap fonts also. */ + /* */ + typedef struct FT_Size_Metrics_ + { + FT_UShort x_ppem; /* horizontal pixels per EM */ + FT_UShort y_ppem; /* vertical pixels per EM */ + + FT_Fixed x_scale; /* scaling values used to convert font */ + FT_Fixed y_scale; /* units to 26.6 fractional pixels */ + + FT_Pos ascender; /* ascender in 26.6 frac. pixels */ + FT_Pos descender; /* descender in 26.6 frac. pixels */ + FT_Pos height; /* text height in 26.6 frac. pixels */ + FT_Pos max_advance; /* max horizontal advance, in 26.6 pixels */ + + } FT_Size_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SizeRec */ + /* */ + /* <Description> */ + /* FreeType root size class structure. A size object models a face */ + /* object at a given size. */ + /* */ + /* <Fields> */ + /* face :: Handle to the parent face object. */ + /* */ + /* generic :: A typeless pointer, which is unused by the FreeType */ + /* library or any of its drivers. It can be used by */ + /* client applications to link their own data to each size */ + /* object. */ + /* */ + /* metrics :: Metrics for this size object. This field is read-only. */ + /* */ + typedef struct FT_SizeRec_ + { + FT_Face face; /* parent face object */ + FT_Generic generic; /* generic pointer for client uses */ + FT_Size_Metrics metrics; /* size metrics */ + FT_Size_Internal internal; + + } FT_SizeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SubGlyph */ + /* */ + /* <Description> */ + /* The subglyph structure is an internal object used to describe */ + /* subglyphs (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The subglyph implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + /* You can however retrieve subglyph information with */ + /* @FT_Get_SubGlyph_Info. */ + /* */ + typedef struct FT_SubGlyphRec_* FT_SubGlyph; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Slot_Internal */ + /* */ + /* <Description> */ + /* An opaque handle to an `FT_Slot_InternalRec' structure, used to */ + /* model private data of a given @FT_GlyphSlot object. */ + /* */ + typedef struct FT_Slot_InternalRec_* FT_Slot_Internal; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphSlotRec */ + /* */ + /* <Description> */ + /* FreeType root glyph slot class structure. A glyph slot is a */ + /* container where individual glyphs can be loaded, be they in */ + /* outline or bitmap format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library instance */ + /* this slot belongs to. */ + /* */ + /* face :: A handle to the parent face object. */ + /* */ + /* next :: In some cases (like some font tools), several */ + /* glyph slots per face object can be a good */ + /* thing. As this is rare, the glyph slots are */ + /* listed through a direct, single-linked list */ + /* using its `next' field. */ + /* */ + /* generic :: A typeless pointer which is unused by the */ + /* FreeType library or any of its drivers. It */ + /* can be used by client applications to link */ + /* their own data to each glyph slot object. */ + /* */ + /* metrics :: The metrics of the last loaded glyph in the */ + /* slot. The returned values depend on the last */ + /* load flags (see the @FT_Load_Glyph API */ + /* function) and can be expressed either in 26.6 */ + /* fractional pixels or font units. */ + /* */ + /* Note that even when the glyph image is */ + /* transformed, the metrics are not. */ + /* */ + /* linearHoriAdvance :: The advance width of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* linearVertAdvance :: The advance height of the unhinted glyph. */ + /* Its value is expressed in 16.16 fractional */ + /* pixels, unless @FT_LOAD_LINEAR_DESIGN is set */ + /* when loading the glyph. This field can be */ + /* important to perform correct WYSIWYG layout. */ + /* Only relevant for outline glyphs. */ + /* */ + /* advance :: This is the transformed advance width for the */ + /* glyph. */ + /* */ + /* format :: This field indicates the format of the image */ + /* contained in the glyph slot. Typically */ + /* @FT_GLYPH_FORMAT_BITMAP, */ + /* @FT_GLYPH_FORMAT_OUTLINE, or */ + /* @FT_GLYPH_FORMAT_COMPOSITE, but others are */ + /* possible. */ + /* */ + /* bitmap :: This field is used as a bitmap descriptor */ + /* when the slot format is */ + /* @FT_GLYPH_FORMAT_BITMAP. Note that the */ + /* address and content of the bitmap buffer can */ + /* change between calls of @FT_Load_Glyph and a */ + /* few other functions. */ + /* */ + /* bitmap_left :: This is the bitmap's left bearing expressed */ + /* in integer pixels. Of course, this is only */ + /* valid if the format is */ + /* @FT_GLYPH_FORMAT_BITMAP. */ + /* */ + /* bitmap_top :: This is the bitmap's top bearing expressed in */ + /* integer pixels. Remember that this is the */ + /* distance from the baseline to the top-most */ + /* glyph scanline, upwards y~coordinates being */ + /* *positive*. */ + /* */ + /* outline :: The outline descriptor for the current glyph */ + /* image if its format is */ + /* @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is */ + /* loaded, `outline' can be transformed, */ + /* distorted, embolded, etc. However, it must */ + /* not be freed. */ + /* */ + /* num_subglyphs :: The number of subglyphs in a composite glyph. */ + /* This field is only valid for the composite */ + /* glyph format that should normally only be */ + /* loaded with the @FT_LOAD_NO_RECURSE flag. */ + /* For now this is internal to FreeType. */ + /* */ + /* subglyphs :: An array of subglyph descriptors for */ + /* composite glyphs. There are `num_subglyphs' */ + /* elements in there. Currently internal to */ + /* FreeType. */ + /* */ + /* control_data :: Certain font drivers can also return the */ + /* control data for a given glyph image (e.g. */ + /* TrueType bytecode, Type~1 charstrings, etc.). */ + /* This field is a pointer to such data. */ + /* */ + /* control_len :: This is the length in bytes of the control */ + /* data. */ + /* */ + /* other :: Really wicked formats can use this pointer to */ + /* present their own glyph image to client */ + /* applications. Note that the application */ + /* needs to know about the image format. */ + /* */ + /* lsb_delta :: The difference between hinted and unhinted */ + /* left side bearing while autohinting is */ + /* active. Zero otherwise. */ + /* */ + /* rsb_delta :: The difference between hinted and unhinted */ + /* right side bearing while autohinting is */ + /* active. Zero otherwise. */ + /* */ + /* <Note> */ + /* If @FT_Load_Glyph is called with default flags (see */ + /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ + /* its native format (e.g., an outline glyph for TrueType and Type~1 */ + /* formats). */ + /* */ + /* This image can later be converted into a bitmap by calling */ + /* @FT_Render_Glyph. This function finds the current renderer for */ + /* the native image's format then invokes it. */ + /* */ + /* The renderer is in charge of transforming the native image through */ + /* the slot's face transformation fields, then convert it into a */ + /* bitmap that is returned in `slot->bitmap'. */ + /* */ + /* Note that `slot->bitmap_left' and `slot->bitmap_top' are also used */ + /* to specify the position of the bitmap relative to the current pen */ + /* position (e.g., coordinates (0,0) on the baseline). Of course, */ + /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ + /* */ + /* <Note> */ + /* Here a small pseudo code fragment which shows how to use */ + /* `lsb_delta' and `rsb_delta': */ + /* */ + /* { */ + /* FT_Pos origin_x = 0; */ + /* FT_Pos prev_rsb_delta = 0; */ + /* */ + /* */ + /* for all glyphs do */ + /* <compute kern between current and previous glyph and add it to */ + /* `origin_x'> */ + /* */ + /* <load glyph with `FT_Load_Glyph'> */ + /* */ + /* if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 ) */ + /* origin_x -= 64; */ + /* else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 ) */ + /* origin_x += 64; */ + /* */ + /* prev_rsb_delta = face->glyph->rsb_delta; */ + /* */ + /* <save glyph image, or render glyph, or ...> */ + /* */ + /* origin_x += face->glyph->advance.x; */ + /* endfor */ + /* } */ + /* */ + typedef struct FT_GlyphSlotRec_ + { + FT_Library library; + FT_Face face; + FT_GlyphSlot next; + FT_UInt reserved; /* retained for binary compatibility */ + FT_Generic generic; + + FT_Glyph_Metrics metrics; + FT_Fixed linearHoriAdvance; + FT_Fixed linearVertAdvance; + FT_Vector advance; + + FT_Glyph_Format format; + + FT_Bitmap bitmap; + FT_Int bitmap_left; + FT_Int bitmap_top; + + FT_Outline outline; + + FT_UInt num_subglyphs; + FT_SubGlyph subglyphs; + + void* control_data; + long control_len; + + FT_Pos lsb_delta; + FT_Pos rsb_delta; + + void* other; + + FT_Slot_Internal internal; + + } FT_GlyphSlotRec; + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* F U N C T I O N S */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Init_FreeType */ + /* */ + /* <Description> */ + /* Initialize a new FreeType library object. The set of modules */ + /* that are registered by this function is determined at build time. */ + /* */ + /* <Output> */ + /* alibrary :: A handle to a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Init_FreeType( FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_FreeType */ + /* */ + /* <Description> */ + /* Destroy a given FreeType library object and all of its children, */ + /* including resources, drivers, faces, sizes, etc. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_FreeType( FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OPEN_XXX */ + /* */ + /* <Description> */ + /* A list of bit-field constants used within the `flags' field of the */ + /* @FT_Open_Args structure. */ + /* */ + /* <Values> */ + /* FT_OPEN_MEMORY :: This is a memory-based stream. */ + /* */ + /* FT_OPEN_STREAM :: Copy the stream from the `stream' field. */ + /* */ + /* FT_OPEN_PATHNAME :: Create a new input stream from a C~path */ + /* name. */ + /* */ + /* FT_OPEN_DRIVER :: Use the `driver' field. */ + /* */ + /* FT_OPEN_PARAMS :: Use the `num_params' and `params' fields. */ + /* */ + /* ft_open_memory :: Deprecated; use @FT_OPEN_MEMORY instead. */ + /* */ + /* ft_open_stream :: Deprecated; use @FT_OPEN_STREAM instead. */ + /* */ + /* ft_open_pathname :: Deprecated; use @FT_OPEN_PATHNAME instead. */ + /* */ + /* ft_open_driver :: Deprecated; use @FT_OPEN_DRIVER instead. */ + /* */ + /* ft_open_params :: Deprecated; use @FT_OPEN_PARAMS instead. */ + /* */ + /* <Note> */ + /* The `FT_OPEN_MEMORY', `FT_OPEN_STREAM', and `FT_OPEN_PATHNAME' */ + /* flags are mutually exclusive. */ + /* */ +#define FT_OPEN_MEMORY 0x1 +#define FT_OPEN_STREAM 0x2 +#define FT_OPEN_PATHNAME 0x4 +#define FT_OPEN_DRIVER 0x8 +#define FT_OPEN_PARAMS 0x10 + +#define ft_open_memory FT_OPEN_MEMORY /* deprecated */ +#define ft_open_stream FT_OPEN_STREAM /* deprecated */ +#define ft_open_pathname FT_OPEN_PATHNAME /* deprecated */ +#define ft_open_driver FT_OPEN_DRIVER /* deprecated */ +#define ft_open_params FT_OPEN_PARAMS /* deprecated */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Parameter */ + /* */ + /* <Description> */ + /* A simple structure used to pass more or less generic parameters */ + /* to @FT_Open_Face. */ + /* */ + /* <Fields> */ + /* tag :: A four-byte identification tag. */ + /* */ + /* data :: A pointer to the parameter data. */ + /* */ + /* <Note> */ + /* The ID and function of parameters are driver-specific. */ + /* */ + typedef struct FT_Parameter_ + { + FT_ULong tag; + FT_Pointer data; + + } FT_Parameter; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Open_Args */ + /* */ + /* <Description> */ + /* A structure used to indicate how to open a new font file or */ + /* stream. A pointer to such a structure can be used as a parameter */ + /* for the functions @FT_Open_Face and @FT_Attach_Stream. */ + /* */ + /* <Fields> */ + /* flags :: A set of bit flags indicating how to use the */ + /* structure. */ + /* */ + /* memory_base :: The first byte of the file in memory. */ + /* */ + /* memory_size :: The size in bytes of the file in memory. */ + /* */ + /* pathname :: A pointer to an 8-bit file pathname. */ + /* */ + /* stream :: A handle to a source stream object. */ + /* */ + /* driver :: This field is exclusively used by @FT_Open_Face; */ + /* it simply specifies the font driver to use to open */ + /* the face. If set to~0, FreeType tries to load the */ + /* face with each one of the drivers in its list. */ + /* */ + /* num_params :: The number of extra parameters. */ + /* */ + /* params :: Extra parameters passed to the font driver when */ + /* opening a new face. */ + /* */ + /* <Note> */ + /* The stream type is determined by the contents of `flags' which */ + /* are tested in the following order by @FT_Open_Face: */ + /* */ + /* If the `FT_OPEN_MEMORY' bit is set, assume that this is a */ + /* memory file of `memory_size' bytes, located at `memory_address'. */ + /* The data are are not copied, and the client is responsible for */ + /* releasing and destroying them _after_ the corresponding call to */ + /* @FT_Done_Face. */ + /* */ + /* Otherwise, if the `FT_OPEN_STREAM' bit is set, assume that a */ + /* custom input stream `stream' is used. */ + /* */ + /* Otherwise, if the `FT_OPEN_PATHNAME' bit is set, assume that this */ + /* is a normal file and use `pathname' to open it. */ + /* */ + /* If the `FT_OPEN_DRIVER' bit is set, @FT_Open_Face only tries to */ + /* open the file with the driver whose handler is in `driver'. */ + /* */ + /* If the `FT_OPEN_PARAMS' bit is set, the parameters given by */ + /* `num_params' and `params' is used. They are ignored otherwise. */ + /* */ + /* Ideally, both the `pathname' and `params' fields should be tagged */ + /* as `const'; this is missing for API backwards compatibility. With */ + /* other words, applications should treat them as read-only. */ + /* */ + typedef struct FT_Open_Args_ + { + FT_UInt flags; + const FT_Byte* memory_base; + FT_Long memory_size; + FT_String* pathname; + FT_Stream stream; + FT_Module driver; + FT_Int num_params; + FT_Parameter* params; + + } FT_Open_Args; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font by its pathname. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* pathname :: A path to the font file. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See @FT_Open_Face for more details. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face( FT_Library library, + const char* filepathname, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory_Face */ + /* */ + /* <Description> */ + /* This function calls @FT_Open_Face to open a font which has been */ + /* loaded into memory. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* file_base :: A pointer to the beginning of the font data. */ + /* */ + /* file_size :: The size of the memory chunk used by the font data. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See @FT_Open_Face for more details. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You must not deallocate the memory before calling @FT_Done_Face. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Memory_Face( FT_Library library, + const FT_Byte* file_base, + FT_Long file_size, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Open_Face */ + /* */ + /* <Description> */ + /* Create a face object from a given resource described by */ + /* @FT_Open_Args. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* args :: A pointer to an `FT_Open_Args' structure which must */ + /* be filled by the caller. */ + /* */ + /* face_index :: The index of the face within the font. The first */ + /* face has index~0. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. If `face_index' is */ + /* greater than or equal to zero, it must be non-NULL. */ + /* See note below. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Unlike FreeType 1.x, this function automatically creates a glyph */ + /* slot for the face object which can be accessed directly through */ + /* `face->glyph'. */ + /* */ + /* FT_Open_Face can be used to quickly check whether the font */ + /* format of a given font resource is supported by FreeType. If the */ + /* `face_index' field is negative, the function's return value is~0 */ + /* if the font format is recognized, or non-zero otherwise; */ + /* the function returns a more or less empty face handle in `*aface' */ + /* (if `aface' isn't NULL). The only useful field in this special */ + /* case is `face->num_faces' which gives the number of faces within */ + /* the font file. After examination, the returned @FT_Face structure */ + /* should be deallocated with a call to @FT_Done_Face. */ + /* */ + /* Each new face object created with this function also owns a */ + /* default @FT_Size object, accessible as `face->size'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Open_Face( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_File */ + /* */ + /* <Description> */ + /* This function calls @FT_Attach_Stream to attach a file. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* filepathname :: The pathname. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_File( FT_Face face, + const char* filepathname ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Attach_Stream */ + /* */ + /* <Description> */ + /* `Attach' data to a face object. Normally, this is used to read */ + /* additional information for the face object. For example, you can */ + /* attach an AFM file that comes with a Type~1 font to get the */ + /* kerning values and other metrics. */ + /* */ + /* <InOut> */ + /* face :: The target face object. */ + /* */ + /* <Input> */ + /* parameters :: A pointer to @FT_Open_Args which must be filled by */ + /* the caller. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The meaning of the `attach' (i.e., what really happens when the */ + /* new file is read) is not fixed by FreeType itself. It really */ + /* depends on the font format (and thus the font driver). */ + /* */ + /* Client applications are expected to know what they are doing */ + /* when invoking this function. Most drivers simply do not implement */ + /* file attachments. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Attach_Stream( FT_Face face, + FT_Open_Args* parameters ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Face */ + /* */ + /* <Description> */ + /* Discard a given face object, as well as all of its child slots and */ + /* sizes. */ + /* */ + /* <Input> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Face( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Size */ + /* */ + /* <Description> */ + /* Select a bitmap strike. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* strike_index :: The index of the bitmap strike in the */ + /* `available_sizes' field of @FT_FaceRec structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Size( FT_Face face, + FT_Int strike_index ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Size_Request_Type */ + /* */ + /* <Description> */ + /* An enumeration type that lists the supported size request types. */ + /* */ + /* <Values> */ + /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ + /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ + /* used to determine both scaling values. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ + /* The real dimension. The sum of the the `Ascender' and (minus */ + /* of) the `Descender' fields of @FT_FaceRec are used to determine */ + /* both scaling values. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_BBOX :: */ + /* The font bounding box. The width and height of the `bbox' field */ + /* of @FT_FaceRec are used to determine the horizontal and vertical */ + /* scaling value, respectively. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_CELL :: */ + /* The `max_advance_width' field of @FT_FaceRec is used to */ + /* determine the horizontal scaling value; the vertical scaling */ + /* value is determined the same way as */ + /* @FT_SIZE_REQUEST_TYPE_REAL_DIM does. Finally, both scaling */ + /* values are set to the smaller one. This type is useful if you */ + /* want to specify the font size for, say, a window of a given */ + /* dimension and 80x24 cells. */ + /* */ + /* FT_SIZE_REQUEST_TYPE_SCALES :: */ + /* Specify the scaling values directly. */ + /* */ + /* <Note> */ + /* The above descriptions only apply to scalable formats. For bitmap */ + /* formats, the behaviour is up to the driver. */ + /* */ + /* See the note section of @FT_Size_Metrics if you wonder how size */ + /* requesting relates to scaling values. */ + /* */ + typedef enum FT_Size_Request_Type_ + { + FT_SIZE_REQUEST_TYPE_NOMINAL, + FT_SIZE_REQUEST_TYPE_REAL_DIM, + FT_SIZE_REQUEST_TYPE_BBOX, + FT_SIZE_REQUEST_TYPE_CELL, + FT_SIZE_REQUEST_TYPE_SCALES, + + FT_SIZE_REQUEST_TYPE_MAX + + } FT_Size_Request_Type; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_RequestRec */ + /* */ + /* <Description> */ + /* A structure used to model a size request. */ + /* */ + /* <Fields> */ + /* type :: See @FT_Size_Request_Type. */ + /* */ + /* width :: The desired width. */ + /* */ + /* height :: The desired height. */ + /* */ + /* horiResolution :: The horizontal resolution. If set to zero, */ + /* `width' is treated as a 26.6 fractional pixel */ + /* value. */ + /* */ + /* vertResolution :: The vertical resolution. If set to zero, */ + /* `height' is treated as a 26.6 fractional pixel */ + /* value. */ + /* */ + /* <Note> */ + /* If `width' is zero, then the horizontal scaling value is set */ + /* equal to the vertical scaling value, and vice versa. */ + /* */ + typedef struct FT_Size_RequestRec_ + { + FT_Size_Request_Type type; + FT_Long width; + FT_Long height; + FT_UInt horiResolution; + FT_UInt vertResolution; + + } FT_Size_RequestRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_Request */ + /* */ + /* <Description> */ + /* A handle to a size request structure. */ + /* */ + typedef struct FT_Size_RequestRec_ *FT_Size_Request; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Request_Size */ + /* */ + /* <Description> */ + /* Resize the scale of the active @FT_Size object in a face. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* req :: A pointer to a @FT_Size_RequestRec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Although drivers may select the bitmap strike matching the */ + /* request, you should not rely on this if you intend to select a */ + /* particular bitmap strike. Use @FT_Select_Size instead in that */ + /* case. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Request_Size( FT_Face face, + FT_Size_Request req ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Char_Size */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in points). */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object. */ + /* */ + /* <Input> */ + /* char_width :: The nominal width, in 26.6 fractional points. */ + /* */ + /* char_height :: The nominal height, in 26.6 fractional points. */ + /* */ + /* horz_resolution :: The horizontal resolution in dpi. */ + /* */ + /* vert_resolution :: The vertical resolution in dpi. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If either the character width or height is zero, it is set equal */ + /* to the other value. */ + /* */ + /* If either the horizontal or vertical resolution is zero, it is set */ + /* equal to the other value. */ + /* */ + /* A character width or height smaller than 1pt is set to 1pt; if */ + /* both resolution values are zero, they are set to 72dpi. */ + /* */ + + FT_EXPORT( FT_Error ) + FT_Set_Char_Size( FT_Face face, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Pixel_Sizes */ + /* */ + /* <Description> */ + /* This function calls @FT_Request_Size to request the nominal size */ + /* (in pixels). */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Input> */ + /* pixel_width :: The nominal width, in pixels. */ + /* */ + /* pixel_height :: The nominal height, in pixels. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Pixel_Sizes( FT_Face face, + FT_UInt pixel_width, + FT_UInt pixel_height ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Glyph */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object. */ + /* */ + /* <InOut> */ + /* face :: A handle to the target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* glyph_index :: The index of the glyph in the font file. For */ + /* CID-keyed fonts (either in PS or in CFF format) */ + /* this argument specifies the CID value. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The loaded glyph may be transformed. See @FT_Set_Transform for */ + /* the details. */ + /* */ + /* For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument' is */ + /* returned for invalid CID values (this is, for CID values which */ + /* don't have a corresponding glyph in the font). See the discussion */ + /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Glyph( FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Load_Char */ + /* */ + /* <Description> */ + /* A function used to load a single glyph into the glyph slot of a */ + /* face object, according to its character code. */ + /* */ + /* <InOut> */ + /* face :: A handle to a target face object where the glyph */ + /* is loaded. */ + /* */ + /* <Input> */ + /* char_code :: The glyph's character code, according to the */ + /* current charmap used in the face. */ + /* */ + /* load_flags :: A flag indicating what to load for this glyph. The */ + /* @FT_LOAD_XXX constants can be used to control the */ + /* glyph loading process (e.g., whether the outline */ + /* should be scaled, whether to load bitmaps or not, */ + /* whether to hint the outline, etc). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Load_Char( FT_Face face, + FT_ULong char_code, + FT_Int32 load_flags ); + + + /************************************************************************* + * + * @enum: + * FT_LOAD_XXX + * + * @description: + * A list of bit-field constants used with @FT_Load_Glyph to indicate + * what kind of operations to perform during glyph loading. + * + * @values: + * FT_LOAD_DEFAULT :: + * Corresponding to~0, this value is used as the default glyph load + * operation. In this case, the following happens: + * + * 1. FreeType looks for a bitmap for the glyph corresponding to the + * face's current size. If one is found, the function returns. + * The bitmap data can be accessed from the glyph slot (see note + * below). + * + * 2. If no embedded bitmap is searched or found, FreeType looks for a + * scalable outline. If one is found, it is loaded from the font + * file, scaled to device pixels, then `hinted' to the pixel grid + * in order to optimize it. The outline data can be accessed from + * the glyph slot (see note below). + * + * Note that by default, the glyph loader doesn't render outlines into + * bitmaps. The following flags are used to modify this default + * behaviour to more specific and useful cases. + * + * FT_LOAD_NO_SCALE :: + * Don't scale the outline glyph loaded, but keep it in font units. + * + * This flag implies @FT_LOAD_NO_HINTING and @FT_LOAD_NO_BITMAP, and + * unsets @FT_LOAD_RENDER. + * + * FT_LOAD_NO_HINTING :: + * Disable hinting. This generally generates `blurrier' bitmap glyph + * when the glyph is rendered in any of the anti-aliased modes. See + * also the note below. + * + * This flag is implied by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_RENDER :: + * Call @FT_Render_Glyph after the glyph is loaded. By default, the + * glyph is rendered in @FT_RENDER_MODE_NORMAL mode. This can be + * overridden by @FT_LOAD_TARGET_XXX or @FT_LOAD_MONOCHROME. + * + * This flag is unset by @FT_LOAD_NO_SCALE. + * + * FT_LOAD_NO_BITMAP :: + * Ignore bitmap strikes when loading. Bitmap-only fonts ignore this + * flag. + * + * @FT_LOAD_NO_SCALE always sets this flag. + * + * FT_LOAD_VERTICAL_LAYOUT :: + * Load the glyph for vertical text layout. _Don't_ use it as it is + * problematic currently. + * + * FT_LOAD_FORCE_AUTOHINT :: + * Indicates that the auto-hinter is preferred over the font's native + * hinter. See also the note below. + * + * FT_LOAD_CROP_BITMAP :: + * Indicates that the font driver should crop the loaded bitmap glyph + * (i.e., remove all space around its black bits). Not all drivers + * implement this. + * + * FT_LOAD_PEDANTIC :: + * Indicates that the font driver should perform pedantic verifications + * during glyph loading. This is mostly used to detect broken glyphs + * in fonts. By default, FreeType tries to handle broken fonts also. + * + * FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH :: + * Indicates that the font driver should ignore the global advance + * width defined in the font. By default, that value is used as the + * advance width for all glyphs when the face has + * @FT_FACE_FLAG_FIXED_WIDTH set. + * + * This flag exists for historical reasons (to support buggy CJK + * fonts). + * + * FT_LOAD_NO_RECURSE :: + * This flag is only used internally. It merely indicates that the + * font driver should not load composite glyphs recursively. Instead, + * it should set the `num_subglyph' and `subglyphs' values of the + * glyph slot accordingly, and set `glyph->format' to + * @FT_GLYPH_FORMAT_COMPOSITE. + * + * The description of sub-glyphs is not available to client + * applications for now. + * + * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. + * + * FT_LOAD_IGNORE_TRANSFORM :: + * Indicates that the transform matrix set by @FT_Set_Transform should + * be ignored. + * + * FT_LOAD_MONOCHROME :: + * This flag is used with @FT_LOAD_RENDER to indicate that you want to + * render an outline glyph to a 1-bit monochrome bitmap glyph, with + * 8~pixels packed into each byte of the bitmap data. + * + * Note that this has no effect on the hinting algorithm used. You + * should use @FT_LOAD_TARGET_MONO instead so that the + * monochrome-optimized hinting algorithm is used. + * + * FT_LOAD_LINEAR_DESIGN :: + * Indicates that the `linearHoriAdvance' and `linearVertAdvance' + * fields of @FT_GlyphSlotRec should be kept in font units. See + * @FT_GlyphSlotRec for details. + * + * FT_LOAD_NO_AUTOHINT :: + * Disable auto-hinter. See also the note below. + * + * @note: + * By default, hinting is enabled and the font's native hinter (see + * @FT_FACE_FLAG_HINTER) is preferred over the auto-hinter. You can + * disable hinting by setting @FT_LOAD_NO_HINTING or change the + * precedence by setting @FT_LOAD_FORCE_AUTOHINT. You can also set + * @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be + * used at all. + * + * Besides deciding which hinter to use, you can also decide which + * hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details. + */ +#define FT_LOAD_DEFAULT 0x0 +#define FT_LOAD_NO_SCALE 0x1 +#define FT_LOAD_NO_HINTING 0x2 +#define FT_LOAD_RENDER 0x4 +#define FT_LOAD_NO_BITMAP 0x8 +#define FT_LOAD_VERTICAL_LAYOUT 0x10 +#define FT_LOAD_FORCE_AUTOHINT 0x20 +#define FT_LOAD_CROP_BITMAP 0x40 +#define FT_LOAD_PEDANTIC 0x80 +#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 0x200 +#define FT_LOAD_NO_RECURSE 0x400 +#define FT_LOAD_IGNORE_TRANSFORM 0x800 +#define FT_LOAD_MONOCHROME 0x1000 +#define FT_LOAD_LINEAR_DESIGN 0x2000 +#define FT_LOAD_SBITS_ONLY 0x4000 /* temporary hack! */ +#define FT_LOAD_NO_AUTOHINT 0x8000U + + /* */ + + + /************************************************************************** + * + * @enum: + * FT_LOAD_TARGET_XXX + * + * @description: + * A list of values that are used to select a specific hinting algorithm + * to use by the hinter. You should OR one of these values to your + * `load_flags' when calling @FT_Load_Glyph. + * + * Note that font's native hinters may ignore the hinting algorithm you + * have specified (e.g., the TrueType bytecode interpreter). You can set + * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. + * + * Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it + * always implies @FT_LOAD_FORCE_AUTOHINT. + * + * @values: + * FT_LOAD_TARGET_NORMAL :: + * This corresponds to the default hinting algorithm, optimized for + * standard gray-level rendering. For monochrome output, use + * @FT_LOAD_TARGET_MONO instead. + * + * FT_LOAD_TARGET_LIGHT :: + * A lighter hinting algorithm for non-monochrome modes. Many + * generated glyphs are more fuzzy but better resemble its original + * shape. A bit like rendering on Mac OS~X. + * + * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. + * + * FT_LOAD_TARGET_MONO :: + * Strong hinting algorithm that should only be used for monochrome + * output. The result is probably unpleasant if the glyph is rendered + * in non-monochrome modes. + * + * FT_LOAD_TARGET_LCD :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for horizontally + * decimated LCD displays. + * + * FT_LOAD_TARGET_LCD_V :: + * A variant of @FT_LOAD_TARGET_NORMAL optimized for vertically + * decimated LCD displays. + * + * @note: + * You should use only _one_ of the FT_LOAD_TARGET_XXX values in your + * `load_flags'. They can't be ORed. + * + * If @FT_LOAD_RENDER is also set, the glyph is rendered in the + * corresponding mode (i.e., the mode which matches the used algorithm + * best) unless @FT_LOAD_MONOCHROME is set. + * + * You can use a hinting algorithm that doesn't correspond to the same + * rendering mode. As an example, it is possible to use the `light' + * hinting algorithm and have the results rendered in horizontal LCD + * pixel mode, with code like + * + * { + * FT_Load_Glyph( face, glyph_index, + * load_flags | FT_LOAD_TARGET_LIGHT ); + * + * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); + * } + */ + +#define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) + +#define FT_LOAD_TARGET_NORMAL FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL ) +#define FT_LOAD_TARGET_LIGHT FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT ) +#define FT_LOAD_TARGET_MONO FT_LOAD_TARGET_( FT_RENDER_MODE_MONO ) +#define FT_LOAD_TARGET_LCD FT_LOAD_TARGET_( FT_RENDER_MODE_LCD ) +#define FT_LOAD_TARGET_LCD_V FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V ) + + + /************************************************************************** + * + * @macro: + * FT_LOAD_TARGET_MODE + * + * @description: + * Return the @FT_Render_Mode corresponding to a given + * @FT_LOAD_TARGET_XXX value. + * + */ + +#define FT_LOAD_TARGET_MODE( x ) ( (FT_Render_Mode)( ( (x) >> 16 ) & 15 ) ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Transform */ + /* */ + /* <Description> */ + /* A function used to set the transformation that is applied to glyph */ + /* images when they are loaded into a glyph slot through */ + /* @FT_Load_Glyph. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ + /* the identity matrix. */ + /* delta :: A pointer to the translation vector. Use~0 for the null */ + /* vector. */ + /* */ + /* <Note> */ + /* The transformation is only applied to scalable image formats after */ + /* the glyph has been loaded. It means that hinting is unaltered by */ + /* the transformation and is performed on the character size given in */ + /* the last call to @FT_Set_Char_Size or @FT_Set_Pixel_Sizes. */ + /* */ + /* Note that this also transforms the `face.glyph.advance' field, but */ + /* *not* the values in `face.glyph.metrics'. */ + /* */ + FT_EXPORT( void ) + FT_Set_Transform( FT_Face face, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Render_Mode */ + /* */ + /* <Description> */ + /* An enumeration type that lists the render modes supported by */ + /* FreeType~2. Each mode corresponds to a specific type of scanline */ + /* conversion performed on the outline. */ + /* */ + /* For bitmap fonts the `bitmap->pixel_mode' field in the */ + /* @FT_GlyphSlotRec structure gives the format of the returned */ + /* bitmap. */ + /* */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ + /* */ + /* <Values> */ + /* FT_RENDER_MODE_NORMAL :: */ + /* This is the default render mode; it corresponds to 8-bit */ + /* anti-aliased bitmaps. */ + /* */ + /* FT_RENDER_MODE_LIGHT :: */ + /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ + /* defined as a separate value because render modes are also used */ + /* indirectly to define hinting algorithm selectors. See */ + /* @FT_LOAD_TARGET_XXX for details. */ + /* */ + /* FT_RENDER_MODE_MONO :: */ + /* This mode corresponds to 1-bit bitmaps (with 2~levels of */ + /* opacity). */ + /* */ + /* FT_RENDER_MODE_LCD :: */ + /* This mode corresponds to horizontal RGB and BGR sub-pixel */ + /* displays, like LCD-screens. It produces 8-bit bitmaps that are */ + /* 3~times the width of the original glyph outline in pixels, and */ + /* which use the @FT_PIXEL_MODE_LCD mode. */ + /* */ + /* FT_RENDER_MODE_LCD_V :: */ + /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ + /* (like PDA screens, rotated LCD displays, etc.). It produces */ + /* 8-bit bitmaps that are 3~times the height of the original */ + /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ + /* */ + /* <Note> */ + /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ + /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ + /* (not active in the default builds). It is up to the caller to */ + /* either call @FT_Library_SetLcdFilter (if available) or do the */ + /* filtering itself. */ + /* */ + typedef enum FT_Render_Mode_ + { + FT_RENDER_MODE_NORMAL = 0, + FT_RENDER_MODE_LIGHT, + FT_RENDER_MODE_MONO, + FT_RENDER_MODE_LCD, + FT_RENDER_MODE_LCD_V, + + FT_RENDER_MODE_MAX + + } FT_Render_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_render_mode_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated. Use the corresponding */ + /* @FT_Render_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_render_mode_normal :: see @FT_RENDER_MODE_NORMAL */ + /* ft_render_mode_mono :: see @FT_RENDER_MODE_MONO */ + /* */ +#define ft_render_mode_normal FT_RENDER_MODE_NORMAL +#define ft_render_mode_mono FT_RENDER_MODE_MONO + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Render_Glyph */ + /* */ + /* <Description> */ + /* Convert a given glyph image to a bitmap. It does so by inspecting */ + /* the glyph image format, finding the relevant renderer, and */ + /* invoking it. */ + /* */ + /* <InOut> */ + /* slot :: A handle to the glyph slot containing the image to */ + /* convert. */ + /* */ + /* <Input> */ + /* render_mode :: This is the render mode used to render the glyph */ + /* image into a bitmap. See @FT_Render_Mode for a */ + /* list of possible values. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Render_Glyph( FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Kerning_Mode */ + /* */ + /* <Description> */ + /* An enumeration used to specify which kerning values to return in */ + /* @FT_Get_Kerning. */ + /* */ + /* <Values> */ + /* FT_KERNING_DEFAULT :: Return scaled and grid-fitted kerning */ + /* distances (value is~0). */ + /* */ + /* FT_KERNING_UNFITTED :: Return scaled but un-grid-fitted kerning */ + /* distances. */ + /* */ + /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ + /* units. */ + /* */ + typedef enum FT_Kerning_Mode_ + { + FT_KERNING_DEFAULT = 0, + FT_KERNING_UNFITTED, + FT_KERNING_UNSCALED + + } FT_Kerning_Mode; + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_default */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_DEFAULT */ + /* instead. */ + /* */ +#define ft_kerning_default FT_KERNING_DEFAULT + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_unfitted */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_UNFITTED */ + /* instead. */ + /* */ +#define ft_kerning_unfitted FT_KERNING_UNFITTED + + + /*************************************************************************/ + /* */ + /* <Const> */ + /* ft_kerning_unscaled */ + /* */ + /* <Description> */ + /* This constant is deprecated. Please use @FT_KERNING_UNSCALED */ + /* instead. */ + /* */ +#define ft_kerning_unscaled FT_KERNING_UNSCALED + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Kerning */ + /* */ + /* <Description> */ + /* Return the kerning vector between two glyphs of a same face. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* left_glyph :: The index of the left glyph in the kern pair. */ + /* */ + /* right_glyph :: The index of the right glyph in the kern pair. */ + /* */ + /* kern_mode :: See @FT_Kerning_Mode for more information. */ + /* Determines the scale and dimension of the returned */ + /* kerning vector. */ + /* */ + /* <Output> */ + /* akerning :: The kerning vector. This is either in font units */ + /* or in pixels (26.6 format) for scalable formats, */ + /* and in pixels for fixed-sizes formats. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* Only horizontal layouts (left-to-right & right-to-left) are */ + /* supported by this method. Other layouts, or more sophisticated */ + /* kernings, are out of the scope of this API function -- they can be */ + /* implemented through format-specific interfaces. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Kerning( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_UInt kern_mode, + FT_Vector *akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Track_Kerning */ + /* */ + /* <Description> */ + /* Return the track kerning for a given face object at a given size. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* point_size :: The point size in 16.16 fractional points. */ + /* */ + /* degree :: The degree of tightness. */ + /* */ + /* <Output> */ + /* akerning :: The kerning in 16.16 fractional points. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Track_Kerning( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII name of a given glyph in a face. This only */ + /* works for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1. */ + /* */ + /* <Input> */ + /* face :: A handle to a source face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* buffer_max :: The maximal number of bytes available in the */ + /* buffer. */ + /* */ + /* <Output> */ + /* buffer :: A pointer to a target buffer where the name is */ + /* copied to. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error is returned if the face doesn't provide glyph names or if */ + /* the glyph index is invalid. In all cases of failure, the first */ + /* byte of `buffer' is set to~0 to indicate an empty name. */ + /* */ + /* The glyph name is truncated to fit within the buffer if it is too */ + /* long. The returned string is always zero-terminated. */ + /* */ + /* This function is not compiled within the library if the config */ + /* macro `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is defined in */ + /* `include/freetype/config/ftoptions.h'. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph_Name( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Postscript_Name */ + /* */ + /* <Description> */ + /* Retrieve the ASCII PostScript name of a given face, if available. */ + /* This only works with PostScript and TrueType fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to the face's PostScript name. NULL if unavailable. */ + /* */ + /* <Note> */ + /* The returned pointer is owned by the face and is destroyed with */ + /* it. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_Postscript_Name( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Select_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap by its encoding tag (as listed in */ + /* `freetype.h'). */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* encoding :: A handle to the selected encoding. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if no charmap in the face */ + /* corresponds to the encoding queried here. */ + /* */ + /* Because many fonts contain more than a single cmap for Unicode */ + /* encoding, this function has some special code to select the one */ + /* which covers Unicode best (`best' in the sense that a UCS-4 cmap */ + /* is preferred to a UCS-2 cmap). It is thus preferable to */ + /* @FT_Set_Charmap in this case. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Select_Charmap( FT_Face face, + FT_Encoding encoding ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Charmap */ + /* */ + /* <Description> */ + /* Select a given charmap for character code to glyph index mapping. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Input> */ + /* charmap :: A handle to the selected charmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function returns an error if the charmap is not part of */ + /* the face (i.e., if it is not listed in the `face->charmaps' */ + /* table). */ + /* */ + /* It also fails if a type~14 charmap is selected. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Charmap( FT_Face face, + FT_CharMap charmap ); + + + /************************************************************************* + * + * @function: + * FT_Get_Charmap_Index + * + * @description: + * Retrieve index of a given charmap. + * + * @input: + * charmap :: + * A handle to a charmap. + * + * @return: + * The index into the array of character maps within the face to which + * `charmap' belongs. + * + */ + FT_EXPORT( FT_Int ) + FT_Get_Charmap_Index( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Char_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code. This function */ + /* uses a charmap object to do the mapping. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* charcode :: The character code. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within */ + /* the file. This is done to ensure that value~0 always corresponds */ + /* to the `missing glyph'. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Char_Index( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_First_Char */ + /* */ + /* <Description> */ + /* This function is used to return the first character code in the */ + /* current charmap of a given face. It also returns the */ + /* corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of first character code. 0~if charmap is */ + /* empty. */ + /* */ + /* <Return> */ + /* The charmap's first character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_Next_Char to be able to */ + /* parse all character codes available in a given charmap. The code */ + /* should look like this: */ + /* */ + /* { */ + /* FT_ULong charcode; */ + /* FT_UInt gindex; */ + /* */ + /* */ + /* charcode = FT_Get_First_Char( face, &gindex ); */ + /* while ( gindex != 0 ) */ + /* { */ + /* ... do something with (charcode,gindex) pair ... */ + /* */ + /* charcode = FT_Get_Next_Char( face, charcode, &gindex ); */ + /* } */ + /* } */ + /* */ + /* Note that `*agindex' is set to~0 if the charmap is empty. The */ + /* result itself can be~0 in two cases: if the charmap is empty or */ + /* when the value~0 is the first valid character code. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_First_Char( FT_Face face, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Next_Char */ + /* */ + /* <Description> */ + /* This function is used to return the next character code in the */ + /* current charmap of a given face following the value `char_code', */ + /* as well as the corresponding glyph index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* char_code :: The starting character code. */ + /* */ + /* <Output> */ + /* agindex :: Glyph index of first character code. 0~if charmap */ + /* is empty. */ + /* */ + /* <Return> */ + /* The charmap's next character code. */ + /* */ + /* <Note> */ + /* You should use this function with @FT_Get_First_Char to walk */ + /* over all character codes available in a given charmap. See the */ + /* note for this function for a simple code example. */ + /* */ + /* Note that `*agindex' is set to~0 when there are no more codes in */ + /* the charmap. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_Next_Char( FT_Face face, + FT_ULong char_code, + FT_UInt *agindex ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Name_Index */ + /* */ + /* <Description> */ + /* Return the glyph index of a given glyph name. This function uses */ + /* driver specific objects to do the translation. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* glyph_name :: The glyph name. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means `undefined character code'. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Name_Index( FT_Face face, + FT_String* glyph_name ); + + + /************************************************************************* + * + * @macro: + * FT_SUBGLYPH_FLAG_XXX + * + * @description: + * A list of constants used to describe subglyphs. Please refer to the + * TrueType specification for the meaning of the various flags. + * + * @values: + * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: + * FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES :: + * FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID :: + * FT_SUBGLYPH_FLAG_SCALE :: + * FT_SUBGLYPH_FLAG_XY_SCALE :: + * FT_SUBGLYPH_FLAG_2X2 :: + * FT_SUBGLYPH_FLAG_USE_MY_METRICS :: + * + */ +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 +#define FT_SUBGLYPH_FLAG_SCALE 8 +#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 +#define FT_SUBGLYPH_FLAG_2X2 0x80 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 + + + /************************************************************************* + * + * @func: + * FT_Get_SubGlyph_Info + * + * @description: + * Retrieve a description of a given subglyph. Only use it if + * `glyph->format' is @FT_GLYPH_FORMAT_COMPOSITE, or an error is + * returned. + * + * @input: + * glyph :: + * The source glyph slot. + * + * sub_index :: + * The index of subglyph. Must be less than `glyph->num_subglyphs'. + * + * @output: + * p_index :: + * The glyph index of the subglyph. + * + * p_flags :: + * The subglyph flags, see @FT_SUBGLYPH_FLAG_XXX. + * + * p_arg1 :: + * The subglyph's first argument (if any). + * + * p_arg2 :: + * The subglyph's second argument (if any). + * + * p_transform :: + * The subglyph transformation (if any). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be + * interpreted depending on the flags returned in `*p_flags'. See the + * TrueType specification for details. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_SubGlyph_Info( FT_GlyphSlot glyph, + FT_UInt sub_index, + FT_Int *p_index, + FT_UInt *p_flags, + FT_Int *p_arg1, + FT_Int *p_arg2, + FT_Matrix *p_transform ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_variants */ + /* */ + /* <Title> */ + /* Glyph Variants */ + /* */ + /* <Abstract> */ + /* The FreeType~2 interface to Unicode Ideographic Variation */ + /* Sequences (IVS), using the SFNT cmap format~14. */ + /* */ + /* <Description> */ + /* Many CJK characters have variant forms. They are a sort of grey */ + /* area somewhere between being totally irrelevant and semantically */ + /* distinct; for this reason, the Unicode consortium decided to */ + /* introduce Ideographic Variation Sequences (IVS), consisting of a */ + /* Unicode base character and one of 240 variant selectors */ + /* (U+E0100-U+E01EF), instead of further extending the already huge */ + /* code range for CJK characters. */ + /* */ + /* An IVS is registered and unique; for further details please refer */ + /* to Unicode Technical Report #37, the Ideographic Variation */ + /* Database. To date (October 2007), the character with the most */ + /* variants is U+908A, having 8~such IVS. */ + /* */ + /* Adobe and MS decided to support IVS with a new cmap subtable */ + /* (format~14). It is an odd subtable because it is not a mapping of */ + /* input code points to glyphs, but contains lists of all variants */ + /* supported by the font. */ + /* */ + /* A variant may be either `default' or `non-default'. A default */ + /* variant is the one you will get for that code point if you look it */ + /* up in the standard Unicode cmap. A non-default variant is a */ + /* different glyph. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIndex */ + /* */ + /* <Description> */ + /* Return the glyph index of a given character code as modified by */ + /* the variation selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character code point in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode code point of the variation selector. */ + /* */ + /* <Return> */ + /* The glyph index. 0~means either `undefined character code', or */ + /* `undefined selector code', or `no variation selector cmap */ + /* subtable', or `current CharMap is not Unicode'. */ + /* */ + /* <Note> */ + /* If you use FreeType to manipulate the contents of font files */ + /* directly, be aware that the glyph index returned by this function */ + /* doesn't always correspond to the internal indices used within */ + /* the file. This is done to ensure that value~0 always corresponds */ + /* to the `missing glyph'. */ + /* */ + /* This function is only meaningful if */ + /* a) the font has a variation selector cmap sub table, */ + /* and */ + /* b) the current charmap has a Unicode encoding. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Face_GetCharVariantIndex( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharVariantIsDefault */ + /* */ + /* <Description> */ + /* Check whether this variant of this Unicode character is the one to */ + /* be found in the `cmap'. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* variantSelector :: */ + /* The Unicode codepoint of the variation selector. */ + /* */ + /* <Return> */ + /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ + /* variation selector cmap, or -1 if it is not a variant. */ + /* */ + /* <Note> */ + /* This function is only meaningful if the font has a variation */ + /* selector cmap subtable. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_Int ) + FT_Face_GetCharVariantIsDefault( FT_Face face, + FT_ULong charcode, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantSelectors */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* in the font. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* <Return> */ + /* A pointer to an array of selector code points, or NULL if there is */ + /* no valid variant selector cmap subtable. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantSelectors( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetVariantsOfChar */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode variant selectors found */ + /* for the specified character code. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* charcode :: */ + /* The character codepoint in Unicode. */ + /* */ + /* <Return> */ + /* A pointer to an array of variant selector code points which are */ + /* active for the given character, or NULL if the corresponding list */ + /* is empty. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetVariantsOfChar( FT_Face face, + FT_ULong charcode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_GetCharsOfVariant */ + /* */ + /* <Description> */ + /* Return a zero-terminated list of Unicode character codes found for */ + /* the specified variant selector. */ + /* */ + /* <Input> */ + /* face :: */ + /* A handle to the source face object. */ + /* */ + /* variantSelector :: */ + /* The variant selector code point in Unicode. */ + /* */ + /* <Return> */ + /* A list of all the code points which are specified by this selector */ + /* (both default and non-default codes are returned) or NULL if there */ + /* is no valid cmap or the variant selector is invalid. */ + /* */ + /* <Note> */ + /* The last item in the array is~0; the array is owned by the */ + /* @FT_Face object but can be overwritten or released on the next */ + /* call to a FreeType function. */ + /* */ + /* <Since> */ + /* 2.3.6 */ + /* */ + FT_EXPORT( FT_UInt32* ) + FT_Face_GetCharsOfVariant( FT_Face face, + FT_ULong variantSelector ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /* <Title> */ + /* Computations */ + /* */ + /* <Abstract> */ + /* Crunching fixed numbers and vectors. */ + /* */ + /* <Description> */ + /* This section contains various functions used to perform */ + /* computations on 16.16 fixed-float numbers or 2d vectors. */ + /* */ + /* <Order> */ + /* FT_MulDiv */ + /* FT_MulFix */ + /* FT_DivFix */ + /* FT_RoundFix */ + /* FT_CeilFix */ + /* FT_FloorFix */ + /* FT_Vector_Transform */ + /* FT_Matrix_Multiply */ + /* FT_Matrix_Invert */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* with maximal accuracy (it uses a 64-bit intermediate integer */ + /* whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulDiv( FT_Long a, + FT_Long b, + FT_Long c ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*b)/0x10000' with maximal accuracy. Most of the time this is */ + /* used to multiply a given value by a 16.16 fixed float factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*b)/0x10000'. */ + /* */ + /* <Note> */ + /* This function has been optimized for the case where the absolute */ + /* value of `a' is less than 2048, and `b' is a 16.16 scaling factor. */ + /* As this happens mainly when scaling from notional units to */ + /* fractional pixels in FreeType, it resulted in noticeable speed */ + /* improvements between versions 2.x and 1.x. */ + /* */ + /* As a conclusion, always try to place a 16.16 factor as the */ + /* _second_ argument of this function; this can make a great */ + /* difference. */ + /* */ + FT_EXPORT( FT_Long ) + FT_MulFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_DivFix */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation */ + /* `(a*0x10000)/b' with maximal accuracy. Most of the time, this is */ + /* used to divide a given value by a 16.16 fixed float factor. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. Use a 16.16 factor here whenever */ + /* possible (see note below). */ + /* */ + /* <Return> */ + /* The result of `(a*0x10000)/b'. */ + /* */ + /* <Note> */ + /* The optimization for FT_DivFix() is simple: If (a~<<~16) fits in */ + /* 32~bits, then the division is computed directly. Otherwise, we */ + /* use a specialized version of @FT_MulDiv. */ + /* */ + FT_EXPORT( FT_Long ) + FT_DivFix( FT_Long a, + FT_Long b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_RoundFix */ + /* */ + /* <Description> */ + /* A very simple function used to round a 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number to be rounded. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x8000) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_RoundFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_CeilFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the ceiling function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the ceiling function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `(a + 0x10000 - 1) & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_CeilFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_FloorFix */ + /* */ + /* <Description> */ + /* A very simple function used to compute the floor function of a */ + /* 16.16 fixed number. */ + /* */ + /* <Input> */ + /* a :: The number for which the floor function is to be computed. */ + /* */ + /* <Return> */ + /* The result of `a & -0x10000'. */ + /* */ + FT_EXPORT( FT_Fixed ) + FT_FloorFix( FT_Fixed a ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Vector_Transform */ + /* */ + /* <Description> */ + /* Transform a single vector through a 2x2 matrix. */ + /* */ + /* <InOut> */ + /* vector :: The target vector to transform. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the source 2x2 matrix. */ + /* */ + /* <Note> */ + /* The result is undefined if either `vector' or `matrix' is invalid. */ + /* */ + FT_EXPORT( void ) + FT_Vector_Transform( FT_Vector* vec, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* version */ + /* */ + /* <Title> */ + /* FreeType Version */ + /* */ + /* <Abstract> */ + /* Functions and macros related to FreeType versions. */ + /* */ + /* <Description> */ + /* Note that those functions and macros are of limited use because */ + /* even a new release of FreeType with only documentation changes */ + /* increases the version number. */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FREETYPE_XXX + * + * @description: + * These three macros identify the FreeType source code version. + * Use @FT_Library_Version to access them at runtime. + * + * @values: + * FREETYPE_MAJOR :: The major version number. + * FREETYPE_MINOR :: The minor version number. + * FREETYPE_PATCH :: The patch level. + * + * @note: + * The version number of FreeType if built as a dynamic link library + * with the `libtool' package is _not_ controlled by these three + * macros. + */ +#define FREETYPE_MAJOR 2 +#define FREETYPE_MINOR 3 +#define FREETYPE_PATCH 7 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Library_Version */ + /* */ + /* <Description> */ + /* Return the version of the FreeType library being used. This is */ + /* useful when dynamically linking to the library, since one cannot */ + /* use the macros @FREETYPE_MAJOR, @FREETYPE_MINOR, and */ + /* @FREETYPE_PATCH. */ + /* */ + /* <Input> */ + /* library :: A source library handle. */ + /* */ + /* <Output> */ + /* amajor :: The major version number. */ + /* */ + /* aminor :: The minor version number. */ + /* */ + /* apatch :: The patch version number. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' argument is because */ + /* certain programs implement library initialization in a custom way */ + /* that doesn't use @FT_Init_FreeType. */ + /* */ + /* In such cases, the library version might not be available before */ + /* the library object has been created. */ + /* */ + FT_EXPORT( void ) + FT_Library_Version( FT_Library library, + FT_Int *amajor, + FT_Int *aminor, + FT_Int *apatch ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_CheckTrueTypePatents */ + /* */ + /* <Description> */ + /* Parse all bytecode instructions of a TrueType font file to check */ + /* whether any of the patented opcodes are used. This is only useful */ + /* if you want to be able to use the unpatented hinter with */ + /* fonts that do *not* use these opcodes. */ + /* */ + /* Note that this function parses *all* glyph instructions in the */ + /* font file, which may be slow. */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* <Return> */ + /* 1~if this is a TrueType font that uses one of the patented */ + /* opcodes, 0~otherwise. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_CheckTrueTypePatents( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Face_SetUnpatentedHinting */ + /* */ + /* <Description> */ + /* Enable or disable the unpatented hinter for a given face. */ + /* Only enable it if you have determined that the face doesn't */ + /* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */ + /* */ + /* <Input> */ + /* face :: A face handle. */ + /* */ + /* value :: New boolean setting. */ + /* */ + /* <Return> */ + /* The old setting value. This will always be false if this is not */ + /* a SFNT font, or if the unpatented hinter is not compiled in this */ + /* instance of the library. */ + /* */ + /* <Since> */ + /* 2.3.5 */ + /* */ + FT_EXPORT( FT_Bool ) + FT_Face_SetUnpatentedHinting( FT_Face face, + FT_Bool value ); + + /* */ + + +FT_END_HEADER + +#endif /* __FREETYPE_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftbbox.h b/utils/openttd/freetype/ftbbox.h new file mode 100644 index 00000000000..01fe3fb0d10 --- /dev/null +++ b/utils/openttd/freetype/ftbbox.h @@ -0,0 +1,94 @@ +/***************************************************************************/ +/* */ +/* ftbbox.h */ +/* */ +/* FreeType exact bbox computation (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This component has a _single_ role: to compute exact outline bounding */ + /* boxes. */ + /* */ + /* It is separated from the rest of the engine for various technical */ + /* reasons. It may well be integrated in `ftoutln' later. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTBBOX_H__ +#define __FTBBOX_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_BBox */ + /* */ + /* <Description> */ + /* Compute the exact bounding box of an outline. This is slower */ + /* than computing the control box. However, it uses an advanced */ + /* algorithm which returns _very_ quickly when the two boxes */ + /* coincide. Otherwise, the outline Bézier arcs are traversed to */ + /* extract their extrema. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline. */ + /* */ + /* <Output> */ + /* abbox :: The outline's exact bounding box. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_BBox( FT_Outline* outline, + FT_BBox *abbox ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTBBOX_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/utils/openttd/freetype/ftbdf.h b/utils/openttd/freetype/ftbdf.h new file mode 100644 index 00000000000..a8cf6a51452 --- /dev/null +++ b/utils/openttd/freetype/ftbdf.h @@ -0,0 +1,201 @@ +/***************************************************************************/ +/* */ +/* ftbdf.h */ +/* */ +/* FreeType API for accessing BDF-specific strings (specification). */ +/* */ +/* Copyright 2002, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBDF_H__ +#define __FTBDF_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bdf_fonts */ + /* */ + /* <Title> */ + /* BDF and PCF Files */ + /* */ + /* <Abstract> */ + /* BDF and PCF specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions specific to BDF */ + /* and PCF fonts. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * FT_PropertyType + * + * @description: + * A list of BDF property types. + * + * @values: + * BDF_PROPERTY_TYPE_NONE :: + * Value~0 is used to indicate a missing property. + * + * BDF_PROPERTY_TYPE_ATOM :: + * Property is a string atom. + * + * BDF_PROPERTY_TYPE_INTEGER :: + * Property is a 32-bit signed integer. + * + * BDF_PROPERTY_TYPE_CARDINAL :: + * Property is a 32-bit unsigned integer. + */ + typedef enum BDF_PropertyType_ + { + BDF_PROPERTY_TYPE_NONE = 0, + BDF_PROPERTY_TYPE_ATOM = 1, + BDF_PROPERTY_TYPE_INTEGER = 2, + BDF_PROPERTY_TYPE_CARDINAL = 3 + + } BDF_PropertyType; + + + /********************************************************************** + * + * @type: + * BDF_Property + * + * @description: + * A handle to a @BDF_PropertyRec structure to model a given + * BDF/PCF property. + */ + typedef struct BDF_PropertyRec_* BDF_Property; + + + /********************************************************************** + * + * @struct: + * BDF_PropertyRec + * + * @description: + * This structure models a given BDF/PCF property. + * + * @fields: + * type :: + * The property type. + * + * u.atom :: + * The atom string, if type is @BDF_PROPERTY_TYPE_ATOM. + * + * u.integer :: + * A signed integer, if type is @BDF_PROPERTY_TYPE_INTEGER. + * + * u.cardinal :: + * An unsigned integer, if type is @BDF_PROPERTY_TYPE_CARDINAL. + */ + typedef struct BDF_PropertyRec_ + { + BDF_PropertyType type; + union { + const char* atom; + FT_Int32 integer; + FT_UInt32 cardinal; + + } u; + + } BDF_PropertyRec; + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Charset_ID + * + * @description: + * Retrieve a BDF font character set identity, according to + * the BDF specification. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * acharset_encoding :: + * Charset encoding, as a C~string, owned by the face. + * + * acharset_registry :: + * Charset registry, as a C~string, owned by the face. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with BDF faces, returning an error otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Charset_ID( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + + /********************************************************************** + * + * @function: + * FT_Get_BDF_Property + * + * @description: + * Retrieve a BDF property from a BDF or PCF font file. + * + * @input: + * face :: A handle to the input face. + * + * name :: The property name. + * + * @output: + * aproperty :: The property. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function works with BDF _and_ PCF fonts. It returns an error + * otherwise. It also returns an error if the property is not in the + * font. + * + * In case of error, `aproperty->type' is always set to + * @BDF_PROPERTY_TYPE_NONE. + */ + FT_EXPORT( FT_Error ) + FT_Get_BDF_Property( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + /* */ + +FT_END_HEADER + +#endif /* __FTBDF_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftbitmap.h b/utils/openttd/freetype/ftbitmap.h new file mode 100644 index 00000000000..982b6aed2b2 --- /dev/null +++ b/utils/openttd/freetype/ftbitmap.h @@ -0,0 +1,206 @@ +/***************************************************************************/ +/* */ +/* ftbitmap.h */ +/* */ +/* FreeType utility functions for converting 1bpp, 2bpp, 4bpp, and 8bpp */ +/* bitmaps into 8bpp format (specification). */ +/* */ +/* Copyright 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTBITMAP_H__ +#define __FTBITMAP_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* bitmap_handling */ + /* */ + /* <Title> */ + /* Bitmap Handling */ + /* */ + /* <Abstract> */ + /* Handling FT_Bitmap objects. */ + /* */ + /* <Description> */ + /* This section contains functions for converting FT_Bitmap objects. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_New */ + /* */ + /* <Description> */ + /* Initialize a pointer to an @FT_Bitmap structure. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the bitmap structure. */ + /* */ + FT_EXPORT( void ) + FT_Bitmap_New( FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Copy */ + /* */ + /* <Description> */ + /* Copy a bitmap into another one. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: A handle to the source bitmap. */ + /* */ + /* <Output> */ + /* target :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Copy( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Embolden */ + /* */ + /* <Description> */ + /* Embolden a bitmap. The new bitmap will be about `xStrength' */ + /* pixels wider and `yStrength' pixels higher. The left and bottom */ + /* borders are kept unchanged. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* xStrength :: How strong the glyph is emboldened horizontally. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* yStrength :: How strong the glyph is emboldened vertically. */ + /* Expressed in 26.6 pixel format. */ + /* */ + /* <InOut> */ + /* bitmap :: A handle to the target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The current implementation restricts `xStrength' to be less than */ + /* or equal to~8 if bitmap is of pixel_mode @FT_PIXEL_MODE_MONO. */ + /* */ + /* If you want to embolden the bitmap owned by a @FT_GlyphSlotRec, */ + /* you should call `FT_GlyphSlot_Own_Bitmap' on the slot first. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Embolden( FT_Library library, + FT_Bitmap* bitmap, + FT_Pos xStrength, + FT_Pos yStrength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Convert */ + /* */ + /* <Description> */ + /* Convert a bitmap object with depth 1bpp, 2bpp, 4bpp, or 8bpp to a */ + /* bitmap object with depth 8bpp, making the number of used bytes per */ + /* line (a.k.a. the `pitch') a multiple of `alignment'. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* source :: The source bitmap. */ + /* */ + /* alignment :: The pitch of the bitmap is a multiple of this */ + /* parameter. Common values are 1, 2, or 4. */ + /* */ + /* <Output> */ + /* target :: The target bitmap. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* It is possible to call @FT_Bitmap_Convert multiple times without */ + /* calling @FT_Bitmap_Done (the memory is simply reallocated). */ + /* */ + /* Use @FT_Bitmap_Done to finally remove the bitmap object. */ + /* */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Convert( FT_Library library, + const FT_Bitmap *source, + FT_Bitmap *target, + FT_Int alignment ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Bitmap_Done */ + /* */ + /* <Description> */ + /* Destroy a bitmap object created with @FT_Bitmap_New. */ + /* */ + /* <Input> */ + /* library :: A handle to a library object. */ + /* */ + /* bitmap :: The bitmap object to be freed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `library' argument is taken to have access to FreeType's */ + /* memory handling functions. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Bitmap_Done( FT_Library library, + FT_Bitmap *bitmap ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTBITMAP_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftcache.h b/utils/openttd/freetype/ftcache.h new file mode 100644 index 00000000000..bb03b311791 --- /dev/null +++ b/utils/openttd/freetype/ftcache.h @@ -0,0 +1,1121 @@ +/***************************************************************************/ +/* */ +/* ftcache.h */ +/* */ +/* FreeType Cache subsystem (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCACHE_H__ +#define __FTCACHE_H__ + + +#include <ft2build.h> +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************* + * + * <Section> + * cache_subsystem + * + * <Title> + * Cache Sub-System + * + * <Abstract> + * How to cache face, size, and glyph data with FreeType~2. + * + * <Description> + * This section describes the FreeType~2 cache sub-system, which is used + * to limit the number of concurrently opened @FT_Face and @FT_Size + * objects, as well as caching information like character maps and glyph + * images while limiting their maximum memory usage. + * + * Note that all types and functions begin with the `FTC_' prefix. + * + * The cache is highly portable and thus doesn't know anything about the + * fonts installed on your system, or how to access them. This implies + * the following scheme: + * + * First, available or installed font faces are uniquely identified by + * @FTC_FaceID values, provided to the cache by the client. Note that + * the cache only stores and compares these values, and doesn't try to + * interpret them in any way. + * + * Second, the cache calls, only when needed, a client-provided function + * to convert a @FTC_FaceID into a new @FT_Face object. The latter is + * then completely managed by the cache, including its termination + * through @FT_Done_Face. + * + * Clients are free to map face IDs to anything else. The most simple + * usage is to associate them to a (pathname,face_index) pair that is + * used to call @FT_New_Face. However, more complex schemes are also + * possible. + * + * Note that for the cache to work correctly, the face ID values must be + * *persistent*, which means that the contents they point to should not + * change at runtime, or that their value should not become invalid. + * + * If this is unavoidable (e.g., when a font is uninstalled at runtime), + * you should call @FTC_Manager_RemoveFaceID as soon as possible, to let + * the cache get rid of any references to the old @FTC_FaceID it may + * keep internally. Failure to do so will lead to incorrect behaviour + * or even crashes. + * + * To use the cache, start with calling @FTC_Manager_New to create a new + * @FTC_Manager object, which models a single cache instance. You can + * then look up @FT_Face and @FT_Size objects with + * @FTC_Manager_LookupFace and @FTC_Manager_LookupSize, respectively. + * + * If you want to use the charmap caching, call @FTC_CMapCache_New, then + * later use @FTC_CMapCache_Lookup to perform the equivalent of + * @FT_Get_Char_Index, only much faster. + * + * If you want to use the @FT_Glyph caching, call @FTC_ImageCache, then + * later use @FTC_ImageCache_Lookup to retrieve the corresponding + * @FT_Glyph objects from the cache. + * + * If you need lots of small bitmaps, it is much more memory efficient + * to call @FTC_SBitCache_New followed by @FTC_SBitCache_Lookup. This + * returns @FTC_SBitRec structures, which are used to store small + * bitmaps directly. (A small bitmap is one whose metrics and + * dimensions all fit into 8-bit integers). + * + * We hope to also provide a kerning cache in the near future. + * + * + * <Order> + * FTC_Manager + * FTC_FaceID + * FTC_Face_Requester + * + * FTC_Manager_New + * FTC_Manager_Reset + * FTC_Manager_Done + * FTC_Manager_LookupFace + * FTC_Manager_LookupSize + * FTC_Manager_RemoveFaceID + * + * FTC_Node + * FTC_Node_Unref + * + * FTC_ImageCache + * FTC_ImageCache_New + * FTC_ImageCache_Lookup + * + * FTC_SBit + * FTC_SBitCache + * FTC_SBitCache_New + * FTC_SBitCache_Lookup + * + * FTC_CMapCache + * FTC_CMapCache_New + * FTC_CMapCache_Lookup + * + *************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** BASIC TYPE DEFINITIONS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: FTC_FaceID + * + * @description: + * An opaque pointer type that is used to identity face objects. The + * contents of such objects is application-dependent. + * + * These pointers are typically used to point to a user-defined + * structure containing a font file path, and face index. + * + * @note: + * Never use NULL as a valid @FTC_FaceID. + * + * Face IDs are passed by the client to the cache manager, which calls, + * when needed, the @FTC_Face_Requester to translate them into new + * @FT_Face objects. + * + * If the content of a given face ID changes at runtime, or if the value + * becomes invalid (e.g., when uninstalling a font), you should + * immediately call @FTC_Manager_RemoveFaceID before any other cache + * function. + * + * Failure to do so will result in incorrect behaviour or even + * memory leaks and crashes. + */ + typedef FT_Pointer FTC_FaceID; + + + /************************************************************************ + * + * @functype: + * FTC_Face_Requester + * + * @description: + * A callback function provided by client applications. It is used by + * the cache manager to translate a given @FTC_FaceID into a new valid + * @FT_Face object, on demand. + * + * <Input> + * face_id :: + * The face ID to resolve. + * + * library :: + * A handle to a FreeType library object. + * + * req_data :: + * Application-provided request data (see note below). + * + * <Output> + * aface :: + * A new @FT_Face handle. + * + * <Return> + * FreeType error code. 0~means success. + * + * <Note> + * The third parameter `req_data' is the same as the one passed by the + * client when @FTC_Manager_New is called. + * + * The face requester should not perform funny things on the returned + * face object, like creating a new @FT_Size for it, or setting a + * transformation through @FT_Set_Transform! + */ + typedef FT_Error + (*FTC_Face_Requester)( FTC_FaceID face_id, + FT_Library library, + FT_Pointer request_data, + FT_Face* aface ); + + /* */ + +#define FT_POINTER_TO_ULONG( p ) ( (FT_ULong)(FT_Pointer)(p) ) + +#define FTC_FACE_ID_HASH( i ) \ + ((FT_UInt32)(( FT_POINTER_TO_ULONG( i ) >> 3 ) ^ \ + ( FT_POINTER_TO_ULONG( i ) << 7 ) ) ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CACHE MANAGER OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Manager */ + /* */ + /* <Description> */ + /* This object corresponds to one instance of the cache-subsystem. */ + /* It is used to cache one or more @FT_Face objects, along with */ + /* corresponding @FT_Size objects. */ + /* */ + /* The manager intentionally limits the total number of opened */ + /* @FT_Face and @FT_Size objects to control memory usage. See the */ + /* `max_faces' and `max_sizes' parameters of @FTC_Manager_New. */ + /* */ + /* The manager is also used to cache `nodes' of various types while */ + /* limiting their total memory usage. */ + /* */ + /* All limitations are enforced by keeping lists of managed objects */ + /* in most-recently-used order, and flushing old nodes to make room */ + /* for new ones. */ + /* */ + typedef struct FTC_ManagerRec_* FTC_Manager; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_Node */ + /* */ + /* <Description> */ + /* An opaque handle to a cache node object. Each cache node is */ + /* reference-counted. A node with a count of~0 might be flushed */ + /* out of a full cache whenever a lookup request is performed. */ + /* */ + /* If you lookup nodes, you have the ability to `acquire' them, i.e., */ + /* to increment their reference count. This will prevent the node */ + /* from being flushed out of the cache until you explicitly `release' */ + /* it (see @FTC_Node_Unref). */ + /* */ + /* See also @FTC_SBitCache_Lookup and @FTC_ImageCache_Lookup. */ + /* */ + typedef struct FTC_NodeRec_* FTC_Node; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_New */ + /* */ + /* <Description> */ + /* Create a new cache manager. */ + /* */ + /* <Input> */ + /* library :: The parent FreeType library handle to use. */ + /* */ + /* max_faces :: Maximum number of opened @FT_Face objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_sizes :: Maximum number of opened @FT_Size objects managed by */ + /* this cache instance. Use~0 for defaults. */ + /* */ + /* max_bytes :: Maximum number of bytes to use for cached data nodes. */ + /* Use~0 for defaults. Note that this value does not */ + /* account for managed @FT_Face and @FT_Size objects. */ + /* */ + /* requester :: An application-provided callback used to translate */ + /* face IDs into real @FT_Face objects. */ + /* */ + /* req_data :: A generic pointer that is passed to the requester */ + /* each time it is called (see @FTC_Face_Requester). */ + /* */ + /* <Output> */ + /* amanager :: A handle to a new manager object. 0~in case of */ + /* failure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_New( FT_Library library, + FT_UInt max_faces, + FT_UInt max_sizes, + FT_ULong max_bytes, + FTC_Face_Requester requester, + FT_Pointer req_data, + FTC_Manager *amanager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Reset */ + /* */ + /* <Description> */ + /* Empty a given cache manager. This simply gets rid of all the */ + /* currently cached @FT_Face and @FT_Size objects within the manager. */ + /* */ + /* <InOut> */ + /* manager :: A handle to the manager. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Reset( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_Done */ + /* */ + /* <Description> */ + /* Destroy a given manager after emptying it. */ + /* */ + /* <Input> */ + /* manager :: A handle to the target cache manager object. */ + /* */ + FT_EXPORT( void ) + FTC_Manager_Done( FTC_Manager manager ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupFace */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Face object that corresponds to a given face ID */ + /* through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* face_id :: The ID of the face object. */ + /* */ + /* <Output> */ + /* aface :: A handle to the face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Face object is always owned by the manager. You */ + /* should never try to discard it yourself. */ + /* */ + /* The @FT_Face object doesn't necessarily have a current size object */ + /* (i.e., face->size can be 0). If you need a specific `font size', */ + /* use @FTC_Manager_LookupSize instead. */ + /* */ + /* Never change the face's transformation matrix (i.e., never call */ + /* the @FT_Set_Transform function) on a returned face! If you need */ + /* to transform glyphs, do it yourself after glyph loading. */ + /* */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory was available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupFace( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_ScalerRec */ + /* */ + /* <Description> */ + /* A structure used to describe a given character size in either */ + /* pixels or points to the cache manager. See */ + /* @FTC_Manager_LookupSize. */ + /* */ + /* <Fields> */ + /* face_id :: The source face ID. */ + /* */ + /* width :: The character width. */ + /* */ + /* height :: The character height. */ + /* */ + /* pixel :: A Boolean. If 1, the `width' and `height' fields are */ + /* interpreted as integer pixel character sizes. */ + /* Otherwise, they are expressed as 1/64th of points. */ + /* */ + /* x_res :: Only used when `pixel' is value~0 to indicate the */ + /* horizontal resolution in dpi. */ + /* */ + /* y_res :: Only used when `pixel' is value~0 to indicate the */ + /* vertical resolution in dpi. */ + /* */ + /* <Note> */ + /* This type is mainly used to retrieve @FT_Size objects through the */ + /* cache manager. */ + /* */ + typedef struct FTC_ScalerRec_ + { + FTC_FaceID face_id; + FT_UInt width; + FT_UInt height; + FT_Int pixel; + FT_UInt x_res; + FT_UInt y_res; + + } FTC_ScalerRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_Scaler */ + /* */ + /* <Description> */ + /* A handle to an @FTC_ScalerRec structure. */ + /* */ + typedef struct FTC_ScalerRec_* FTC_Scaler; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Manager_LookupSize */ + /* */ + /* <Description> */ + /* Retrieve the @FT_Size object that corresponds to a given */ + /* @FTC_ScalerRec pointer through a cache manager. */ + /* */ + /* <Input> */ + /* manager :: A handle to the cache manager. */ + /* */ + /* scaler :: A scaler handle. */ + /* */ + /* <Output> */ + /* asize :: A handle to the size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned @FT_Size object is always owned by the manager. You */ + /* should never try to discard it by yourself. */ + /* */ + /* You can access the parent @FT_Face object simply as `size->face' */ + /* if you need it. Note that this object is also owned by the */ + /* manager. */ + /* */ + /* <Note> */ + /* When you perform a lookup, out-of-memory errors are detected */ + /* _within_ the lookup and force incremental flushes of the cache */ + /* until enough memory is released for the lookup to succeed. */ + /* */ + /* If a lookup fails with `FT_Err_Out_Of_Memory' the cache has */ + /* already been completely flushed, and still no memory is available */ + /* for the operation. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_Manager_LookupSize( FTC_Manager manager, + FTC_Scaler scaler, + FT_Size *asize ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_Node_Unref */ + /* */ + /* <Description> */ + /* Decrement a cache node's internal reference count. When the count */ + /* reaches 0, it is not destroyed but becomes eligible for subsequent */ + /* cache flushes. */ + /* */ + /* <Input> */ + /* node :: The cache node handle. */ + /* */ + /* manager :: The cache manager handle. */ + /* */ + FT_EXPORT( void ) + FTC_Node_Unref( FTC_Node node, + FTC_Manager manager ); + + + /************************************************************************* + * + * @function: + * FTC_Manager_RemoveFaceID + * + * @description: + * A special function used to indicate to the cache manager that + * a given @FTC_FaceID is no longer valid, either because its + * content changed, or because it was deallocated or uninstalled. + * + * @input: + * manager :: + * The cache manager handle. + * + * face_id :: + * The @FTC_FaceID to be removed. + * + * @note: + * This function flushes all nodes from the cache corresponding to this + * `face_id', with the exception of nodes with a non-null reference + * count. + * + * Such nodes are however modified internally so as to never appear + * in later lookups with the same `face_id' value, and to be immediately + * destroyed when released by all their users. + * + */ + FT_EXPORT( void ) + FTC_Manager_RemoveFaceID( FTC_Manager manager, + FTC_FaceID face_id ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * FTC_CMapCache + * + * @description: + * An opaque handle used to model a charmap cache. This cache is to + * hold character codes -> glyph indices mappings. + * + */ + typedef struct FTC_CMapCacheRec_* FTC_CMapCache; + + + /************************************************************************* + * + * @function: + * FTC_CMapCache_New + * + * @description: + * Create a new charmap cache. + * + * @input: + * manager :: + * A handle to the cache manager. + * + * @output: + * acache :: + * A new cache handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Like all other caches, this one will be destroyed with the cache + * manager. + * + */ + FT_EXPORT( FT_Error ) + FTC_CMapCache_New( FTC_Manager manager, + FTC_CMapCache *acache ); + + + /************************************************************************ + * + * @function: + * FTC_CMapCache_Lookup + * + * @description: + * Translate a character code into a glyph index, using the charmap + * cache. + * + * @input: + * cache :: + * A charmap cache handle. + * + * face_id :: + * The source face ID. + * + * cmap_index :: + * The index of the charmap in the source face. + * + * char_code :: + * The character code (in the corresponding charmap). + * + * @return: + * Glyph index. 0~means `no glyph'. + * + */ + FT_EXPORT( FT_UInt ) + FTC_CMapCache_Lookup( FTC_CMapCache cache, + FTC_FaceID face_id, + FT_Int cmap_index, + FT_UInt32 char_code ); + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cache_subsystem */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** IMAGE CACHE OBJECT *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /************************************************************************* + * + * @struct: + * FTC_ImageTypeRec + * + * @description: + * A structure used to model the type of images in a glyph cache. + * + * @fields: + * face_id :: + * The face ID. + * + * width :: + * The width in pixels. + * + * height :: + * The height in pixels. + * + * flags :: + * The load flags, as in @FT_Load_Glyph. + * + */ + typedef struct FTC_ImageTypeRec_ + { + FTC_FaceID face_id; + FT_Int width; + FT_Int height; + FT_Int32 flags; + + } FTC_ImageTypeRec; + + + /************************************************************************* + * + * @type: + * FTC_ImageType + * + * @description: + * A handle to an @FTC_ImageTypeRec structure. + * + */ + typedef struct FTC_ImageTypeRec_* FTC_ImageType; + + + /* */ + + +#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \ + ( (d1)->face_id == (d2)->face_id && \ + (d1)->width == (d2)->width && \ + (d1)->flags == (d2)->flags ) + +#define FTC_IMAGE_TYPE_HASH( d ) \ + (FT_UFast)( FTC_FACE_ID_HASH( (d)->face_id ) ^ \ + ( (d)->width << 8 ) ^ (d)->height ^ \ + ( (d)->flags << 4 ) ) + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_ImageCache */ + /* */ + /* <Description> */ + /* A handle to an glyph image cache object. They are designed to */ + /* hold many distinct glyph images while not exceeding a certain */ + /* memory threshold. */ + /* */ + typedef struct FTC_ImageCacheRec_* FTC_ImageCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_New */ + /* */ + /* <Description> */ + /* Create a new glyph image cache. */ + /* */ + /* <Input> */ + /* manager :: The parent manager for the image cache. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new glyph image cache object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_New( FTC_Manager manager, + FTC_ImageCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_Lookup */ + /* */ + /* <Description> */ + /* Retrieve a given glyph image from a glyph image cache. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* type :: A pointer to a glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_Lookup( FTC_ImageCache cache, + FTC_ImageType type, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_ImageCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_ImageCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source glyph image cache. */ + /* */ + /* scaler :: A pointer to a scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index to retrieve. */ + /* */ + /* <Output> */ + /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ + /* failure. */ + /* */ + /* anode :: Used to return the address of of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The returned glyph is owned and managed by the glyph image cache. */ + /* Never try to transform or discard it manually! You can however */ + /* create a copy with @FT_Glyph_Copy and modify the new one. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the glyph image, after increasing its reference */ + /* count. This ensures that the node (as well as the @FT_Glyph) will */ + /* always be kept in the cache until you call @FTC_Node_Unref to */ + /* `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the @FT_Glyph could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_ImageCache_LookupScaler( FTC_ImageCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FT_Glyph *aglyph, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBit */ + /* */ + /* <Description> */ + /* A handle to a small bitmap descriptor. See the @FTC_SBitRec */ + /* structure for details. */ + /* */ + typedef struct FTC_SBitRec_* FTC_SBit; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FTC_SBitRec */ + /* */ + /* <Description> */ + /* A very compact structure used to describe a small glyph bitmap. */ + /* */ + /* <Fields> */ + /* width :: The bitmap width in pixels. */ + /* */ + /* height :: The bitmap height in pixels. */ + /* */ + /* left :: The horizontal distance from the pen position to the */ + /* left bitmap border (a.k.a. `left side bearing', or */ + /* `lsb'). */ + /* */ + /* top :: The vertical distance from the pen position (on the */ + /* baseline) to the upper bitmap border (a.k.a. `top */ + /* side bearing'). The distance is positive for upwards */ + /* y~coordinates. */ + /* */ + /* format :: The format of the glyph bitmap (monochrome or gray). */ + /* */ + /* max_grays :: Maximum gray level value (in the range 1 to~255). */ + /* */ + /* pitch :: The number of bytes per bitmap line. May be positive */ + /* or negative. */ + /* */ + /* xadvance :: The horizontal advance width in pixels. */ + /* */ + /* yadvance :: The vertical advance height in pixels. */ + /* */ + /* buffer :: A pointer to the bitmap pixels. */ + /* */ + typedef struct FTC_SBitRec_ + { + FT_Byte width; + FT_Byte height; + FT_Char left; + FT_Char top; + + FT_Byte format; + FT_Byte max_grays; + FT_Short pitch; + FT_Char xadvance; + FT_Char yadvance; + + FT_Byte* buffer; + + } FTC_SBitRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FTC_SBitCache */ + /* */ + /* <Description> */ + /* A handle to a small bitmap cache. These are special cache objects */ + /* used to store small glyph bitmaps (and anti-aliased pixmaps) in a */ + /* much more efficient way than the traditional glyph image cache */ + /* implemented by @FTC_ImageCache. */ + /* */ + typedef struct FTC_SBitCacheRec_* FTC_SBitCache; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_New */ + /* */ + /* <Description> */ + /* Create a new cache to store small glyph bitmaps. */ + /* */ + /* <Input> */ + /* manager :: A handle to the source cache manager. */ + /* */ + /* <Output> */ + /* acache :: A handle to the new sbit cache. NULL in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_New( FTC_Manager manager, + FTC_SBitCache *acache ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_Lookup */ + /* */ + /* <Description> */ + /* Look up a given small glyph bitmap in a given sbit cache and */ + /* `lock' it to prevent its flushing from the cache until needed. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* type :: A pointer to the glyph image type descriptor. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding cache */ + /* node after incrementing its reference count (see note */ + /* below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_Lookup( FTC_SBitCache cache, + FTC_ImageType type, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FTC_SBitCache_LookupScaler */ + /* */ + /* <Description> */ + /* A variant of @FTC_SBitCache_Lookup that uses an @FTC_ScalerRec */ + /* to specify the face ID and its size. */ + /* */ + /* <Input> */ + /* cache :: A handle to the source sbit cache. */ + /* */ + /* scaler :: A pointer to the scaler descriptor. */ + /* */ + /* load_flags :: The corresponding load flags. */ + /* */ + /* gindex :: The glyph index. */ + /* */ + /* <Output> */ + /* sbit :: A handle to a small bitmap descriptor. */ + /* */ + /* anode :: Used to return the address of of the corresponding */ + /* cache node after incrementing its reference count */ + /* (see note below). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The small bitmap descriptor and its bit buffer are owned by the */ + /* cache and should never be freed by the application. They might */ + /* as well disappear from memory on the next cache lookup, so don't */ + /* treat them as persistent data. */ + /* */ + /* The descriptor's `buffer' field is set to~0 to indicate a missing */ + /* glyph bitmap. */ + /* */ + /* If `anode' is _not_ NULL, it receives the address of the cache */ + /* node containing the bitmap, after increasing its reference count. */ + /* This ensures that the node (as well as the image) will always be */ + /* kept in the cache until you call @FTC_Node_Unref to `release' it. */ + /* */ + /* If `anode' is NULL, the cache node is left unchanged, which means */ + /* that the bitmap could be flushed out of the cache on the next */ + /* call to one of the caching sub-system APIs. Don't assume that it */ + /* is persistent! */ + /* */ + FT_EXPORT( FT_Error ) + FTC_SBitCache_LookupScaler( FTC_SBitCache cache, + FTC_Scaler scaler, + FT_ULong load_flags, + FT_UInt gindex, + FTC_SBit *sbit, + FTC_Node *anode ); + + + /* */ + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*@***********************************************************************/ + /* */ + /* <Struct> */ + /* FTC_FontRec */ + /* */ + /* <Description> */ + /* A simple structure used to describe a given `font' to the cache */ + /* manager. Note that a `font' is the combination of a given face */ + /* with a given character size. */ + /* */ + /* <Fields> */ + /* face_id :: The ID of the face to use. */ + /* */ + /* pix_width :: The character width in integer pixels. */ + /* */ + /* pix_height :: The character height in integer pixels. */ + /* */ + typedef struct FTC_FontRec_ + { + FTC_FaceID face_id; + FT_UShort pix_width; + FT_UShort pix_height; + + } FTC_FontRec; + + + /* */ + + +#define FTC_FONT_COMPARE( f1, f2 ) \ + ( (f1)->face_id == (f2)->face_id && \ + (f1)->pix_width == (f2)->pix_width && \ + (f1)->pix_height == (f2)->pix_height ) + +#define FTC_FONT_HASH( f ) \ + (FT_UInt32)( FTC_FACE_ID_HASH((f)->face_id) ^ \ + ((f)->pix_width << 8) ^ \ + ((f)->pix_height) ) + + typedef FTC_FontRec* FTC_Font; + + + FT_EXPORT( FT_Error ) + FTC_Manager_Lookup_Face( FTC_Manager manager, + FTC_FaceID face_id, + FT_Face *aface ); + + FT_EXPORT( FT_Error ) + FTC_Manager_Lookup_Size( FTC_Manager manager, + FTC_Font font, + FT_Face *aface, + FT_Size *asize ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /* */ + +FT_END_HEADER + +#endif /* __FTCACHE_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftchapters.h b/utils/openttd/freetype/ftchapters.h new file mode 100644 index 00000000000..4c618242ef0 --- /dev/null +++ b/utils/openttd/freetype/ftchapters.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* This file defines the structure of the FreeType reference. */ +/* It is used by the python script which generates the HTML files. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* general_remarks */ +/* */ +/* <Title> */ +/* General Remarks */ +/* */ +/* <Sections> */ +/* user_allocation */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* core_api */ +/* */ +/* <Title> */ +/* Core API */ +/* */ +/* <Sections> */ +/* version */ +/* basic_types */ +/* base_interface */ +/* glyph_variants */ +/* glyph_management */ +/* mac_specific */ +/* sizes_management */ +/* header_file_macros */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* format_specific */ +/* */ +/* <Title> */ +/* Format-Specific API */ +/* */ +/* <Sections> */ +/* multiple_masters */ +/* truetype_tables */ +/* type1_tables */ +/* sfnt_names */ +/* bdf_fonts */ +/* cid_fonts */ +/* pfr_fonts */ +/* winfnt_fonts */ +/* font_formats */ +/* gasp_table */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* cache_subsystem */ +/* */ +/* <Title> */ +/* Cache Sub-System */ +/* */ +/* <Sections> */ +/* cache_subsystem */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* <Chapter> */ +/* support_api */ +/* */ +/* <Title> */ +/* Support API */ +/* */ +/* <Sections> */ +/* computations */ +/* list_processing */ +/* outline_processing */ +/* bitmap_handling */ +/* raster */ +/* glyph_stroker */ +/* system_interface */ +/* module_management */ +/* gzip */ +/* lzw */ +/* lcd_filtering */ +/* */ +/***************************************************************************/ diff --git a/utils/openttd/freetype/ftcid.h b/utils/openttd/freetype/ftcid.h new file mode 100644 index 00000000000..02df2a03522 --- /dev/null +++ b/utils/openttd/freetype/ftcid.h @@ -0,0 +1,98 @@ +/***************************************************************************/ +/* */ +/* ftcid.h */ +/* */ +/* FreeType API for accessing CID font information (specification). */ +/* */ +/* Copyright 2007 by Dereg Clegg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCID_H__ +#define __FTCID_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* cid_fonts */ + /* */ + /* <Title> */ + /* CID Fonts */ + /* */ + /* <Abstract> */ + /* CID-keyed font specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of CID-keyed font specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_CID_Registry_Ordering_Supplement + * + * @description: + * Retrieve the Registry/Ordering/Supplement triple (also known as the + * "R/O/S") from a CID-keyed font. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * registry :: + * The registry, as a C~string, owned by the face. + * + * ordering :: + * The ordering, as a C~string, owned by the face. + * + * supplement :: + * The supplement. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces, returning an error + * otherwise. + * + * @since: + * 2.3.6 + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement); + + /* */ + +FT_END_HEADER + +#endif /* __FTCID_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/fterrdef.h b/utils/openttd/freetype/fterrdef.h new file mode 100644 index 00000000000..d7ad256bdb0 --- /dev/null +++ b/utils/openttd/freetype/fterrdef.h @@ -0,0 +1,239 @@ +/***************************************************************************/ +/* */ +/* fterrdef.h */ +/* */ +/* FreeType error codes (specification). */ +/* */ +/* Copyright 2002, 2004, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST OF ERROR CODES/MESSAGES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + + /* You need to define both FT_ERRORDEF_ and FT_NOERRORDEF_ before */ + /* including this file. */ + + + /* generic errors */ + + FT_NOERRORDEF_( Ok, 0x00, \ + "no error" ) + + FT_ERRORDEF_( Cannot_Open_Resource, 0x01, \ + "cannot open resource" ) + FT_ERRORDEF_( Unknown_File_Format, 0x02, \ + "unknown file format" ) + FT_ERRORDEF_( Invalid_File_Format, 0x03, \ + "broken file" ) + FT_ERRORDEF_( Invalid_Version, 0x04, \ + "invalid FreeType version" ) + FT_ERRORDEF_( Lower_Module_Version, 0x05, \ + "module version is too low" ) + FT_ERRORDEF_( Invalid_Argument, 0x06, \ + "invalid argument" ) + FT_ERRORDEF_( Unimplemented_Feature, 0x07, \ + "unimplemented feature" ) + FT_ERRORDEF_( Invalid_Table, 0x08, \ + "broken table" ) + FT_ERRORDEF_( Invalid_Offset, 0x09, \ + "broken offset within table" ) + FT_ERRORDEF_( Array_Too_Large, 0x0A, \ + "array allocation size too large" ) + + /* glyph/character errors */ + + FT_ERRORDEF_( Invalid_Glyph_Index, 0x10, \ + "invalid glyph index" ) + FT_ERRORDEF_( Invalid_Character_Code, 0x11, \ + "invalid character code" ) + FT_ERRORDEF_( Invalid_Glyph_Format, 0x12, \ + "unsupported glyph image format" ) + FT_ERRORDEF_( Cannot_Render_Glyph, 0x13, \ + "cannot render this glyph format" ) + FT_ERRORDEF_( Invalid_Outline, 0x14, \ + "invalid outline" ) + FT_ERRORDEF_( Invalid_Composite, 0x15, \ + "invalid composite glyph" ) + FT_ERRORDEF_( Too_Many_Hints, 0x16, \ + "too many hints" ) + FT_ERRORDEF_( Invalid_Pixel_Size, 0x17, \ + "invalid pixel size" ) + + /* handle errors */ + + FT_ERRORDEF_( Invalid_Handle, 0x20, \ + "invalid object handle" ) + FT_ERRORDEF_( Invalid_Library_Handle, 0x21, \ + "invalid library handle" ) + FT_ERRORDEF_( Invalid_Driver_Handle, 0x22, \ + "invalid module handle" ) + FT_ERRORDEF_( Invalid_Face_Handle, 0x23, \ + "invalid face handle" ) + FT_ERRORDEF_( Invalid_Size_Handle, 0x24, \ + "invalid size handle" ) + FT_ERRORDEF_( Invalid_Slot_Handle, 0x25, \ + "invalid glyph slot handle" ) + FT_ERRORDEF_( Invalid_CharMap_Handle, 0x26, \ + "invalid charmap handle" ) + FT_ERRORDEF_( Invalid_Cache_Handle, 0x27, \ + "invalid cache manager handle" ) + FT_ERRORDEF_( Invalid_Stream_Handle, 0x28, \ + "invalid stream handle" ) + + /* driver errors */ + + FT_ERRORDEF_( Too_Many_Drivers, 0x30, \ + "too many modules" ) + FT_ERRORDEF_( Too_Many_Extensions, 0x31, \ + "too many extensions" ) + + /* memory errors */ + + FT_ERRORDEF_( Out_Of_Memory, 0x40, \ + "out of memory" ) + FT_ERRORDEF_( Unlisted_Object, 0x41, \ + "unlisted object" ) + + /* stream errors */ + + FT_ERRORDEF_( Cannot_Open_Stream, 0x51, \ + "cannot open stream" ) + FT_ERRORDEF_( Invalid_Stream_Seek, 0x52, \ + "invalid stream seek" ) + FT_ERRORDEF_( Invalid_Stream_Skip, 0x53, \ + "invalid stream skip" ) + FT_ERRORDEF_( Invalid_Stream_Read, 0x54, \ + "invalid stream read" ) + FT_ERRORDEF_( Invalid_Stream_Operation, 0x55, \ + "invalid stream operation" ) + FT_ERRORDEF_( Invalid_Frame_Operation, 0x56, \ + "invalid frame operation" ) + FT_ERRORDEF_( Nested_Frame_Access, 0x57, \ + "nested frame access" ) + FT_ERRORDEF_( Invalid_Frame_Read, 0x58, \ + "invalid frame read" ) + + /* raster errors */ + + FT_ERRORDEF_( Raster_Uninitialized, 0x60, \ + "raster uninitialized" ) + FT_ERRORDEF_( Raster_Corrupted, 0x61, \ + "raster corrupted" ) + FT_ERRORDEF_( Raster_Overflow, 0x62, \ + "raster overflow" ) + FT_ERRORDEF_( Raster_Negative_Height, 0x63, \ + "negative height while rastering" ) + + /* cache errors */ + + FT_ERRORDEF_( Too_Many_Caches, 0x70, \ + "too many registered caches" ) + + /* TrueType and SFNT errors */ + + FT_ERRORDEF_( Invalid_Opcode, 0x80, \ + "invalid opcode" ) + FT_ERRORDEF_( Too_Few_Arguments, 0x81, \ + "too few arguments" ) + FT_ERRORDEF_( Stack_Overflow, 0x82, \ + "stack overflow" ) + FT_ERRORDEF_( Code_Overflow, 0x83, \ + "code overflow" ) + FT_ERRORDEF_( Bad_Argument, 0x84, \ + "bad argument" ) + FT_ERRORDEF_( Divide_By_Zero, 0x85, \ + "division by zero" ) + FT_ERRORDEF_( Invalid_Reference, 0x86, \ + "invalid reference" ) + FT_ERRORDEF_( Debug_OpCode, 0x87, \ + "found debug opcode" ) + FT_ERRORDEF_( ENDF_In_Exec_Stream, 0x88, \ + "found ENDF opcode in execution stream" ) + FT_ERRORDEF_( Nested_DEFS, 0x89, \ + "nested DEFS" ) + FT_ERRORDEF_( Invalid_CodeRange, 0x8A, \ + "invalid code range" ) + FT_ERRORDEF_( Execution_Too_Long, 0x8B, \ + "execution context too long" ) + FT_ERRORDEF_( Too_Many_Function_Defs, 0x8C, \ + "too many function definitions" ) + FT_ERRORDEF_( Too_Many_Instruction_Defs, 0x8D, \ + "too many instruction definitions" ) + FT_ERRORDEF_( Table_Missing, 0x8E, \ + "SFNT font table missing" ) + FT_ERRORDEF_( Horiz_Header_Missing, 0x8F, \ + "horizontal header (hhea) table missing" ) + FT_ERRORDEF_( Locations_Missing, 0x90, \ + "locations (loca) table missing" ) + FT_ERRORDEF_( Name_Table_Missing, 0x91, \ + "name table missing" ) + FT_ERRORDEF_( CMap_Table_Missing, 0x92, \ + "character map (cmap) table missing" ) + FT_ERRORDEF_( Hmtx_Table_Missing, 0x93, \ + "horizontal metrics (hmtx) table missing" ) + FT_ERRORDEF_( Post_Table_Missing, 0x94, \ + "PostScript (post) table missing" ) + FT_ERRORDEF_( Invalid_Horiz_Metrics, 0x95, \ + "invalid horizontal metrics" ) + FT_ERRORDEF_( Invalid_CharMap_Format, 0x96, \ + "invalid character map (cmap) format" ) + FT_ERRORDEF_( Invalid_PPem, 0x97, \ + "invalid ppem value" ) + FT_ERRORDEF_( Invalid_Vert_Metrics, 0x98, \ + "invalid vertical metrics" ) + FT_ERRORDEF_( Could_Not_Find_Context, 0x99, \ + "could not find context" ) + FT_ERRORDEF_( Invalid_Post_Table_Format, 0x9A, \ + "invalid PostScript (post) table format" ) + FT_ERRORDEF_( Invalid_Post_Table, 0x9B, \ + "invalid PostScript (post) table" ) + + /* CFF, CID, and Type 1 errors */ + + FT_ERRORDEF_( Syntax_Error, 0xA0, \ + "opcode syntax error" ) + FT_ERRORDEF_( Stack_Underflow, 0xA1, \ + "argument stack underflow" ) + FT_ERRORDEF_( Ignore, 0xA2, \ + "ignore" ) + + /* BDF errors */ + + FT_ERRORDEF_( Missing_Startfont_Field, 0xB0, \ + "`STARTFONT' field missing" ) + FT_ERRORDEF_( Missing_Font_Field, 0xB1, \ + "`FONT' field missing" ) + FT_ERRORDEF_( Missing_Size_Field, 0xB2, \ + "`SIZE' field missing" ) + FT_ERRORDEF_( Missing_Chars_Field, 0xB3, \ + "`CHARS' field missing" ) + FT_ERRORDEF_( Missing_Startchar_Field, 0xB4, \ + "`STARTCHAR' field missing" ) + FT_ERRORDEF_( Missing_Encoding_Field, 0xB5, \ + "`ENCODING' field missing" ) + FT_ERRORDEF_( Missing_Bbx_Field, 0xB6, \ + "`BBX' field missing" ) + FT_ERRORDEF_( Bbx_Too_Big, 0xB7, \ + "`BBX' too big" ) + FT_ERRORDEF_( Corrupted_Font_Header, 0xB8, \ + "Font header corrupted or missing fields" ) + FT_ERRORDEF_( Corrupted_Font_Glyphs, 0xB9, \ + "Font glyphs corrupted or missing fields" ) + + +/* END */ diff --git a/utils/openttd/freetype/fterrors.h b/utils/openttd/freetype/fterrors.h new file mode 100644 index 00000000000..6600dadd0df --- /dev/null +++ b/utils/openttd/freetype/fterrors.h @@ -0,0 +1,206 @@ +/***************************************************************************/ +/* */ +/* fterrors.h */ +/* */ +/* FreeType error code handling (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This special header file is used to define the handling of FT2 */ + /* enumeration constants. It can also be used to generate error message */ + /* strings with a small macro trick explained below. */ + /* */ + /* I - Error Formats */ + /* ----------------- */ + /* */ + /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ + /* defined in ftoption.h in order to make the higher byte indicate */ + /* the module where the error has happened (this is not compatible */ + /* with standard builds of FreeType 2). You can then use the macro */ + /* FT_ERROR_BASE macro to extract the generic error code from an */ + /* FT_Error value. */ + /* */ + /* */ + /* II - Error Message strings */ + /* -------------------------- */ + /* */ + /* The error definitions below are made through special macros that */ + /* allow client applications to build a table of error message strings */ + /* if they need it. The strings are not included in a normal build of */ + /* FreeType 2 to save space (most client applications do not use */ + /* them). */ + /* */ + /* To do so, you have to define the following macros before including */ + /* this file: */ + /* */ + /* FT_ERROR_START_LIST :: */ + /* This macro is called before anything else to define the start of */ + /* the error list. It is followed by several FT_ERROR_DEF calls */ + /* (see below). */ + /* */ + /* FT_ERROR_DEF( e, v, s ) :: */ + /* This macro is called to define one single error. */ + /* `e' is the error code identifier (e.g. FT_Err_Invalid_Argument). */ + /* `v' is the error numerical value. */ + /* `s' is the corresponding error string. */ + /* */ + /* FT_ERROR_END_LIST :: */ + /* This macro ends the list. */ + /* */ + /* Additionally, you have to undefine __FTERRORS_H__ before #including */ + /* this file. */ + /* */ + /* Here is a simple example: */ + /* */ + /* { */ + /* #undef __FTERRORS_H__ */ + /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ + /* #define FT_ERROR_START_LIST { */ + /* #define FT_ERROR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int err_code; */ + /* const char* err_msg; */ + /* } ft_errors[] = */ + /* */ + /* #include FT_ERRORS_H */ + /* } */ + /* */ + /*************************************************************************/ + + +#ifndef __FTERRORS_H__ +#define __FTERRORS_H__ + + + /* include module base error codes */ +#include FT_MODULE_ERRORS_H + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + +#undef FT_ERR_XCAT +#undef FT_ERR_CAT + +#define FT_ERR_XCAT( x, y ) x ## y +#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) + + + /* FT_ERR_PREFIX is used as a prefix for error identifiers. */ + /* By default, we use `FT_Err_'. */ + /* */ +#ifndef FT_ERR_PREFIX +#define FT_ERR_PREFIX FT_Err_ +#endif + + + /* FT_ERR_BASE is used as the base for module-specific errors. */ + /* */ +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS + +#ifndef FT_ERR_BASE +#define FT_ERR_BASE FT_Mod_Err_Base +#endif + +#else + +#undef FT_ERR_BASE +#define FT_ERR_BASE 0 + +#endif /* FT_CONFIG_OPTION_USE_MODULE_ERRORS */ + + + /* If FT_ERRORDEF is not defined, we need to define a simple */ + /* enumeration type. */ + /* */ +#ifndef FT_ERRORDEF + +#define FT_ERRORDEF( e, v, s ) e = v, +#define FT_ERROR_START_LIST enum { +#define FT_ERROR_END_LIST FT_ERR_CAT( FT_ERR_PREFIX, Max ) }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_ERRORDEF */ + + + /* this macro is used to define an error */ +#define FT_ERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v + FT_ERR_BASE, s ) + + /* this is only used for <module>_Err_Ok, which must be 0! */ +#define FT_NOERRORDEF_( e, v, s ) \ + FT_ERRORDEF( FT_ERR_CAT( FT_ERR_PREFIX, e ), v, s ) + + +#ifdef FT_ERROR_START_LIST + FT_ERROR_START_LIST +#endif + + + /* now include the error codes */ +#include FT_ERROR_DEFINITIONS_H + + +#ifdef FT_ERROR_END_LIST + FT_ERROR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SIMPLE CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_ERROR_START_LIST +#undef FT_ERROR_END_LIST + +#undef FT_ERRORDEF +#undef FT_ERRORDEF_ +#undef FT_NOERRORDEF_ + +#undef FT_NEED_EXTERN_C +#undef FT_ERR_CONCAT +#undef FT_ERR_BASE + + /* FT_KEEP_ERR_PREFIX is needed for ftvalid.h */ +#ifndef FT_KEEP_ERR_PREFIX +#undef FT_ERR_PREFIX +#endif + +#endif /* __FTERRORS_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftgasp.h b/utils/openttd/freetype/ftgasp.h new file mode 100644 index 00000000000..6355bae1066 --- /dev/null +++ b/utils/openttd/freetype/ftgasp.h @@ -0,0 +1,113 @@ +/***************************************************************************/ +/* */ +/* ftgasp.h */ +/* */ +/* Access of TrueType's `gasp' table (specification). */ +/* */ +/* Copyright 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef _FT_GASP_H_ +#define _FT_GASP_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + + /*************************************************************************** + * + * @section: + * gasp_table + * + * @title: + * Gasp Table + * + * @abstract: + * Retrieving TrueType `gasp' table entries. + * + * @description: + * The function @FT_Get_Gasp can be used to query a TrueType or OpenType + * font for specific entries in its `gasp' table, if any. This is + * mainly useful when implementing native TrueType hinting with the + * bytecode interpreter to duplicate the Windows text rendering results. + */ + + /************************************************************************* + * + * @enum: + * FT_GASP_XXX + * + * @description: + * A list of values and/or bit-flags returned by the @FT_Get_Gasp + * function. + * + * @values: + * FT_GASP_NO_TABLE :: + * This special value means that there is no GASP table in this face. + * It is up to the client to decide what to do. + * + * FT_GASP_DO_GRIDFIT :: + * Grid-fitting and hinting should be performed at the specified ppem. + * This *really* means TrueType bytecode interpretation. + * + * FT_GASP_DO_GRAY :: + * Anti-aliased rendering should be performed at the specified ppem. + * + * FT_GASP_SYMMETRIC_SMOOTHING :: + * Smoothing along multiple axes must be used with ClearType. + * + * FT_GASP_SYMMETRIC_GRIDFIT :: + * Grid-fitting must be used with ClearType's symmetric smoothing. + * + * @note: + * `ClearType' is Microsoft's implementation of LCD rendering, partly + * protected by patents. + * + * @since: + * 2.3.0 + */ +#define FT_GASP_NO_TABLE -1 +#define FT_GASP_DO_GRIDFIT 0x01 +#define FT_GASP_DO_GRAY 0x02 +#define FT_GASP_SYMMETRIC_SMOOTHING 0x08 +#define FT_GASP_SYMMETRIC_GRIDFIT 0x10 + + + /************************************************************************* + * + * @func: + * FT_Get_Gasp + * + * @description: + * Read the `gasp' table from a TrueType or OpenType font file and + * return the entry corresponding to a given character pixel size. + * + * @input: + * face :: The source face handle. + * ppem :: The vertical character pixel size. + * + * @return: + * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no + * `gasp' table in the face. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Int ) + FT_Get_Gasp( FT_Face face, + FT_UInt ppem ); + +/* */ + +#endif /* _FT_GASP_H_ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftglyph.h b/utils/openttd/freetype/ftglyph.h new file mode 100644 index 00000000000..2c6249ca751 --- /dev/null +++ b/utils/openttd/freetype/ftglyph.h @@ -0,0 +1,575 @@ +/***************************************************************************/ +/* */ +/* ftglyph.h */ +/* */ +/* FreeType convenience functions to handle glyphs (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file contains the definition of several convenience functions */ + /* that can be used by client applications to easily retrieve glyph */ + /* bitmaps and outlines from a given face. */ + /* */ + /* These functions should be optional if you are writing a font server */ + /* or text layout engine on top of FreeType. However, they are pretty */ + /* handy for many other simple uses of the library. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTGLYPH_H__ +#define __FTGLYPH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* glyph_management */ + /* */ + /* <Title> */ + /* Glyph Management */ + /* */ + /* <Abstract> */ + /* Generic interface to manage individual glyph data. */ + /* */ + /* <Description> */ + /* This section contains definitions used to manage glyph data */ + /* through generic FT_Glyph objects. Each of them can contain a */ + /* bitmap, a vector outline, or even images in other formats. */ + /* */ + /*************************************************************************/ + + + /* forward declaration to a private type */ + typedef struct FT_Glyph_Class_ FT_Glyph_Class; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Glyph */ + /* */ + /* <Description> */ + /* Handle to an object used to model generic glyph images. It is a */ + /* pointer to the @FT_GlyphRec structure and can contain a glyph */ + /* bitmap or pointer. */ + /* */ + /* <Note> */ + /* Glyph objects are not owned by the library. You must thus release */ + /* them manually (through @FT_Done_Glyph) _before_ calling */ + /* @FT_Done_FreeType. */ + /* */ + typedef struct FT_GlyphRec_* FT_Glyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphRec */ + /* */ + /* <Description> */ + /* The root glyph structure contains a given glyph image plus its */ + /* advance width in 16.16 fixed float format. */ + /* */ + /* <Fields> */ + /* library :: A handle to the FreeType library object. */ + /* */ + /* clazz :: A pointer to the glyph's class. Private. */ + /* */ + /* format :: The format of the glyph's image. */ + /* */ + /* advance :: A 16.16 vector that gives the glyph's advance width. */ + /* */ + typedef struct FT_GlyphRec_ + { + FT_Library library; + const FT_Glyph_Class* clazz; + FT_Glyph_Format format; + FT_Vector advance; + + } FT_GlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_BitmapGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model a bitmap glyph image. This is */ + /* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. */ + /* */ + typedef struct FT_BitmapGlyphRec_* FT_BitmapGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BitmapGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for bitmap glyph images. This really is a */ + /* `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* left :: The left-side bearing, i.e., the horizontal distance */ + /* from the current pen position to the left border of the */ + /* glyph bitmap. */ + /* */ + /* top :: The top-side bearing, i.e., the vertical distance from */ + /* the current pen position to the top border of the glyph */ + /* bitmap. This distance is positive for upwards~y! */ + /* */ + /* bitmap :: A descriptor for the bitmap. */ + /* */ + /* <Note> */ + /* You can typecast an @FT_Glyph to @FT_BitmapGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_BITMAP'. This lets you access */ + /* the bitmap's contents easily. */ + /* */ + /* The corresponding pixel buffer is always owned by @FT_BitmapGlyph */ + /* and is thus created and destroyed with it. */ + /* */ + typedef struct FT_BitmapGlyphRec_ + { + FT_GlyphRec root; + FT_Int left; + FT_Int top; + FT_Bitmap bitmap; + + } FT_BitmapGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_OutlineGlyph */ + /* */ + /* <Description> */ + /* A handle to an object used to model an outline glyph image. This */ + /* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. */ + /* */ + typedef struct FT_OutlineGlyphRec_* FT_OutlineGlyph; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_OutlineGlyphRec */ + /* */ + /* <Description> */ + /* A structure used for outline (vectorial) glyph images. This */ + /* really is a `sub-class' of @FT_GlyphRec. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Glyph fields. */ + /* */ + /* outline :: A descriptor for the outline. */ + /* */ + /* <Note> */ + /* You can typecast a @FT_Glyph to @FT_OutlineGlyph if you have */ + /* `glyph->format == FT_GLYPH_FORMAT_OUTLINE'. This lets you access */ + /* the outline's content easily. */ + /* */ + /* As the outline is extracted from a glyph slot, its coordinates are */ + /* expressed normally in 26.6 pixels, unless the flag */ + /* @FT_LOAD_NO_SCALE was used in @FT_Load_Glyph() or @FT_Load_Char(). */ + /* */ + /* The outline's tables are always owned by the object and are */ + /* destroyed with it. */ + /* */ + typedef struct FT_OutlineGlyphRec_ + { + FT_GlyphRec root; + FT_Outline outline; + + } FT_OutlineGlyphRec; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Glyph */ + /* */ + /* <Description> */ + /* A function used to extract a glyph image from a slot. */ + /* */ + /* <Input> */ + /* slot :: A handle to the source glyph slot. */ + /* */ + /* <Output> */ + /* aglyph :: A handle to the glyph object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Glyph( FT_GlyphSlot slot, + FT_Glyph *aglyph ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Copy */ + /* */ + /* <Description> */ + /* A function used to copy a glyph image. Note that the created */ + /* @FT_Glyph object must be released with @FT_Done_Glyph. */ + /* */ + /* <Input> */ + /* source :: A handle to the source glyph object. */ + /* */ + /* <Output> */ + /* target :: A handle to the target glyph object. 0~in case of */ + /* error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Copy( FT_Glyph source, + FT_Glyph *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Transform */ + /* */ + /* <Description> */ + /* Transform a glyph image if its format is scalable. */ + /* */ + /* <InOut> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to a 2x2 matrix to apply. */ + /* */ + /* delta :: A pointer to a 2d vector to apply. Coordinates are */ + /* expressed in 1/64th of a pixel. */ + /* */ + /* <Return> */ + /* FreeType error code (if not 0, the glyph format is not scalable). */ + /* */ + /* <Note> */ + /* The 2x2 transformation matrix is also applied to the glyph's */ + /* advance vector. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_Transform( FT_Glyph glyph, + FT_Matrix* matrix, + FT_Vector* delta ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_BBox_Mode */ + /* */ + /* <Description> */ + /* The mode how the values of @FT_Glyph_Get_CBox are returned. */ + /* */ + /* <Values> */ + /* FT_GLYPH_BBOX_UNSCALED :: */ + /* Return unscaled font units. */ + /* */ + /* FT_GLYPH_BBOX_SUBPIXELS :: */ + /* Return unfitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_GRIDFIT :: */ + /* Return grid-fitted 26.6 coordinates. */ + /* */ + /* FT_GLYPH_BBOX_TRUNCATE :: */ + /* Return coordinates in integer pixels. */ + /* */ + /* FT_GLYPH_BBOX_PIXELS :: */ + /* Return grid-fitted pixel coordinates. */ + /* */ + typedef enum FT_Glyph_BBox_Mode_ + { + FT_GLYPH_BBOX_UNSCALED = 0, + FT_GLYPH_BBOX_SUBPIXELS = 0, + FT_GLYPH_BBOX_GRIDFIT = 1, + FT_GLYPH_BBOX_TRUNCATE = 2, + FT_GLYPH_BBOX_PIXELS = 3 + + } FT_Glyph_BBox_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_glyph_bbox_xxx */ + /* */ + /* <Description> */ + /* These constants are deprecated. Use the corresponding */ + /* @FT_Glyph_BBox_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_glyph_bbox_unscaled :: See @FT_GLYPH_BBOX_UNSCALED. */ + /* ft_glyph_bbox_subpixels :: See @FT_GLYPH_BBOX_SUBPIXELS. */ + /* ft_glyph_bbox_gridfit :: See @FT_GLYPH_BBOX_GRIDFIT. */ + /* ft_glyph_bbox_truncate :: See @FT_GLYPH_BBOX_TRUNCATE. */ + /* ft_glyph_bbox_pixels :: See @FT_GLYPH_BBOX_PIXELS. */ + /* */ +#define ft_glyph_bbox_unscaled FT_GLYPH_BBOX_UNSCALED +#define ft_glyph_bbox_subpixels FT_GLYPH_BBOX_SUBPIXELS +#define ft_glyph_bbox_gridfit FT_GLYPH_BBOX_GRIDFIT +#define ft_glyph_bbox_truncate FT_GLYPH_BBOX_TRUNCATE +#define ft_glyph_bbox_pixels FT_GLYPH_BBOX_PIXELS + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_Get_CBox */ + /* */ + /* <Description> */ + /* Return a glyph's `control box'. The control box encloses all the */ + /* outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* which contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the source glyph object. */ + /* */ + /* mode :: The mode which indicates how to interpret the returned */ + /* bounding box values. */ + /* */ + /* <Output> */ + /* acbox :: The glyph coordinate bounding box. Coordinates are */ + /* expressed in 1/64th of pixels if it is grid-fitted. */ + /* */ + /* <Note> */ + /* Coordinates are relative to the glyph origin, using the y~upwards */ + /* convention. */ + /* */ + /* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' */ + /* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font */ + /* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS */ + /* is another name for this constant. */ + /* */ + /* Note that the maximum coordinates are exclusive, which means that */ + /* one can compute the width and height of the glyph image (be it in */ + /* integer or 26.6 pixels) as: */ + /* */ + /* { */ + /* width = bbox.xMax - bbox.xMin; */ + /* height = bbox.yMax - bbox.yMin; */ + /* } */ + /* */ + /* Note also that for 26.6 coordinates, if `bbox_mode' is set to */ + /* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, */ + /* which corresponds to: */ + /* */ + /* { */ + /* bbox.xMin = FLOOR(bbox.xMin); */ + /* bbox.yMin = FLOOR(bbox.yMin); */ + /* bbox.xMax = CEILING(bbox.xMax); */ + /* bbox.yMax = CEILING(bbox.yMax); */ + /* } */ + /* */ + /* To get the bbox in pixel coordinates, set `bbox_mode' to */ + /* @FT_GLYPH_BBOX_TRUNCATE. */ + /* */ + /* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' */ + /* to @FT_GLYPH_BBOX_PIXELS. */ + /* */ + FT_EXPORT( void ) + FT_Glyph_Get_CBox( FT_Glyph glyph, + FT_UInt bbox_mode, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Glyph_To_Bitmap */ + /* */ + /* <Description> */ + /* Convert a given glyph object to a bitmap glyph object. */ + /* */ + /* <InOut> */ + /* the_glyph :: A pointer to a handle to the target glyph. */ + /* */ + /* <Input> */ + /* render_mode :: An enumeration that describe how the data is */ + /* rendered. */ + /* */ + /* origin :: A pointer to a vector used to translate the glyph */ + /* image before rendering. Can be~0 (if no */ + /* translation). The origin is expressed in */ + /* 26.6 pixels. */ + /* */ + /* destroy :: A boolean that indicates that the original glyph */ + /* image should be destroyed by this function. It is */ + /* never destroyed in case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The glyph image is translated with the `origin' vector before */ + /* rendering. */ + /* */ + /* The first parameter is a pointer to an @FT_Glyph handle, that will */ + /* be replaced by this function. Typically, you would use (omitting */ + /* error handling): */ + /* */ + /* */ + /* { */ + /* FT_Glyph glyph; */ + /* FT_BitmapGlyph glyph_bitmap; */ + /* */ + /* */ + /* // load glyph */ + /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ + /* */ + /* // extract glyph image */ + /* error = FT_Get_Glyph( face->glyph, &glyph ); */ + /* */ + /* // convert to a bitmap (default render mode + destroy old) */ + /* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) */ + /* { */ + /* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT, */ + /* 0, 1 ); */ + /* if ( error ) // glyph unchanged */ + /* ... */ + /* } */ + /* */ + /* // access bitmap content by typecasting */ + /* glyph_bitmap = (FT_BitmapGlyph)glyph; */ + /* */ + /* // do funny stuff with it, like blitting/drawing */ + /* ... */ + /* */ + /* // discard glyph image (bitmap or not) */ + /* FT_Done_Glyph( glyph ); */ + /* } */ + /* */ + /* */ + /* This function does nothing if the glyph format isn't scalable. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Glyph_To_Bitmap( FT_Glyph* the_glyph, + FT_Render_Mode render_mode, + FT_Vector* origin, + FT_Bool destroy ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Glyph */ + /* */ + /* <Description> */ + /* Destroy a given glyph. */ + /* */ + /* <Input> */ + /* glyph :: A handle to the target glyph object. */ + /* */ + FT_EXPORT( void ) + FT_Done_Glyph( FT_Glyph glyph ); + + /* */ + + + /* other helpful functions */ + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Multiply */ + /* */ + /* <Description> */ + /* Perform the matrix operation `b = a*b'. */ + /* */ + /* <Input> */ + /* a :: A pointer to matrix `a'. */ + /* */ + /* <InOut> */ + /* b :: A pointer to matrix `b'. */ + /* */ + /* <Note> */ + /* The result is undefined if either `a' or `b' is zero. */ + /* */ + FT_EXPORT( void ) + FT_Matrix_Multiply( const FT_Matrix* a, + FT_Matrix* b ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Matrix_Invert */ + /* */ + /* <Description> */ + /* Invert a 2x2 matrix. Return an error if it can't be inverted. */ + /* */ + /* <InOut> */ + /* matrix :: A pointer to the target matrix. Remains untouched in */ + /* case of error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Matrix_Invert( FT_Matrix* matrix ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTGLYPH_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/utils/openttd/freetype/ftgxval.h b/utils/openttd/freetype/ftgxval.h new file mode 100644 index 00000000000..497015c1011 --- /dev/null +++ b/utils/openttd/freetype/ftgxval.h @@ -0,0 +1,358 @@ +/***************************************************************************/ +/* */ +/* ftgxval.h */ +/* */ +/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ +/* */ +/* Copyright 2004, 2005, 2006 by */ +/* Masatake YAMATO, Redhat K.K, */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGXVAL_H__ +#define __FTGXVAL_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gx_validation */ + /* */ + /* <Title> */ + /* TrueTypeGX/AAT Validation */ + /* */ + /* <Abstract> */ + /* An API to validate TrueTypeGX/AAT tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some TrueTypeGX tables (feat, mort, morx, bsln, just, kern, opbd, */ + /* trak, prop, lcar). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* */ + /* Warning: Use FT_VALIDATE_XXX to validate a table. */ + /* Following definitions are for gxvalid developers. */ + /* */ + /* */ + /*************************************************************************/ + +#define FT_VALIDATE_feat_INDEX 0 +#define FT_VALIDATE_mort_INDEX 1 +#define FT_VALIDATE_morx_INDEX 2 +#define FT_VALIDATE_bsln_INDEX 3 +#define FT_VALIDATE_just_INDEX 4 +#define FT_VALIDATE_kern_INDEX 5 +#define FT_VALIDATE_opbd_INDEX 6 +#define FT_VALIDATE_trak_INDEX 7 +#define FT_VALIDATE_prop_INDEX 8 +#define FT_VALIDATE_lcar_INDEX 9 +#define FT_VALIDATE_GX_LAST_INDEX FT_VALIDATE_lcar_INDEX + + + /************************************************************************* + * + * @macro: + * FT_VALIDATE_GX_LENGTH + * + * @description: + * The number of tables checked in this module. Use it as a parameter + * for the `table-length' argument of function @FT_TrueTypeGX_Validate. + */ +#define FT_VALIDATE_GX_LENGTH (FT_VALIDATE_GX_LAST_INDEX + 1) + + /* */ + + /* Up to 0x1000 is used by otvalid. + Ox2xxx is reserved for feature OT extension. */ +#define FT_VALIDATE_GX_START 0x4000 +#define FT_VALIDATE_GX_BITFIELD( tag ) \ + ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_GXXXX + * + * @description: + * A list of bit-field constants used with @FT_TrueTypeGX_Validate to + * indicate which TrueTypeGX/AAT Type tables should be validated. + * + * @values: + * FT_VALIDATE_feat :: + * Validate `feat' table. + * + * FT_VALIDATE_mort :: + * Validate `mort' table. + * + * FT_VALIDATE_morx :: + * Validate `morx' table. + * + * FT_VALIDATE_bsln :: + * Validate `bsln' table. + * + * FT_VALIDATE_just :: + * Validate `just' table. + * + * FT_VALIDATE_kern :: + * Validate `kern' table. + * + * FT_VALIDATE_opbd :: + * Validate `opbd' table. + * + * FT_VALIDATE_trak :: + * Validate `trak' table. + * + * FT_VALIDATE_prop :: + * Validate `prop' table. + * + * FT_VALIDATE_lcar :: + * Validate `lcar' table. + * + * FT_VALIDATE_GX :: + * Validate all TrueTypeGX tables (feat, mort, morx, bsln, just, kern, + * opbd, trak, prop and lcar). + * + */ + +#define FT_VALIDATE_feat FT_VALIDATE_GX_BITFIELD( feat ) +#define FT_VALIDATE_mort FT_VALIDATE_GX_BITFIELD( mort ) +#define FT_VALIDATE_morx FT_VALIDATE_GX_BITFIELD( morx ) +#define FT_VALIDATE_bsln FT_VALIDATE_GX_BITFIELD( bsln ) +#define FT_VALIDATE_just FT_VALIDATE_GX_BITFIELD( just ) +#define FT_VALIDATE_kern FT_VALIDATE_GX_BITFIELD( kern ) +#define FT_VALIDATE_opbd FT_VALIDATE_GX_BITFIELD( opbd ) +#define FT_VALIDATE_trak FT_VALIDATE_GX_BITFIELD( trak ) +#define FT_VALIDATE_prop FT_VALIDATE_GX_BITFIELD( prop ) +#define FT_VALIDATE_lcar FT_VALIDATE_GX_BITFIELD( lcar ) + +#define FT_VALIDATE_GX ( FT_VALIDATE_feat | \ + FT_VALIDATE_mort | \ + FT_VALIDATE_morx | \ + FT_VALIDATE_bsln | \ + FT_VALIDATE_just | \ + FT_VALIDATE_kern | \ + FT_VALIDATE_opbd | \ + FT_VALIDATE_trak | \ + FT_VALIDATE_prop | \ + FT_VALIDATE_lcar ) + + + /* */ + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Validate + * + * @description: + * Validate various TrueTypeGX tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library which + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field which specifies the tables to be validated. See + * @FT_VALIDATE_GXXXX for possible values. + * + * table_length :: + * The size of the `tables' array. Normally, @FT_VALIDATE_GX_LENGTH + * should be passed. + * + * @output: + * tables :: + * The array where all validated sfnt tables are stored. + * The array itself must be allocated by a client. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with TrueTypeGX fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the buffers pointed to by + * each `tables' element, by calling @FT_TrueTypeGX_Free. A NULL value + * indicates that the table either doesn't exist in the font, the + * application hasn't asked for validation, or the validator doesn't have + * the ability to validate the sfnt table. + */ + FT_EXPORT( FT_Error ) + FT_TrueTypeGX_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ); + + + /* */ + + /********************************************************************** + * + * @function: + * FT_TrueTypeGX_Free + * + * @description: + * Free the buffer allocated by TrueTypeGX validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer allocated by + * @FT_TrueTypeGX_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_TrueTypeGX_Validate only. + */ + FT_EXPORT( void ) + FT_TrueTypeGX_Free( FT_Face face, + FT_Bytes table ); + + + /* */ + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_CKERNXXX + * + * @description: + * A list of bit-field constants used with @FT_ClassicKern_Validate + * to indicate the classic kern dialect or dialects. If the selected + * type doesn't fit, @FT_ClassicKern_Validate regards the table as + * invalid. + * + * @values: + * FT_VALIDATE_MS :: + * Handle the `kern' table as a classic Microsoft kern table. + * + * FT_VALIDATE_APPLE :: + * Handle the `kern' table as a classic Apple kern table. + * + * FT_VALIDATE_CKERN :: + * Handle the `kern' as either classic Apple or Microsoft kern table. + */ +#define FT_VALIDATE_MS ( FT_VALIDATE_GX_START << 0 ) +#define FT_VALIDATE_APPLE ( FT_VALIDATE_GX_START << 1 ) + +#define FT_VALIDATE_CKERN ( FT_VALIDATE_MS | FT_VALIDATE_APPLE ) + + + /* */ + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Validate + * + * @description: + * Validate classic (16-bit format) kern table to assure that the offsets + * and indices are valid. The idea is that a higher-level library which + * actually does the text layout can access those tables without error + * checking (which can be quite time consuming). + * + * The `kern' table validator in @FT_TrueTypeGX_Validate deals with both + * the new 32-bit format and the classic 16-bit format, while + * FT_ClassicKern_Validate only supports the classic 16-bit format. + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field which specifies the dialect to be validated. See + * @FT_VALIDATE_CKERNXXX for possible values. + * + * @output: + * ckern_table :: + * A pointer to the kern table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * After use, the application should deallocate the buffers pointed to by + * `ckern_table', by calling @FT_ClassicKern_Free. A NULL value + * indicates that the table doesn't exist in the font. + */ + FT_EXPORT( FT_Error ) + FT_ClassicKern_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *ckern_table ); + + + /* */ + + /********************************************************************** + * + * @function: + * FT_ClassicKern_Free + * + * @description: + * Free the buffer allocated by classic Kern validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_ClassicKern_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_ClassicKern_Validate only. + */ + FT_EXPORT( void ) + FT_ClassicKern_Free( FT_Face face, + FT_Bytes table ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTGXVAL_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftgzip.h b/utils/openttd/freetype/ftgzip.h new file mode 100644 index 00000000000..acbc4f0327b --- /dev/null +++ b/utils/openttd/freetype/ftgzip.h @@ -0,0 +1,102 @@ +/***************************************************************************/ +/* */ +/* ftgzip.h */ +/* */ +/* Gzip-compressed stream support. */ +/* */ +/* Copyright 2002, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGZIP_H__ +#define __FTGZIP_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* gzip */ + /* */ + /* <Title> */ + /* GZIP Streams */ + /* */ + /* <Abstract> */ + /* Using gzip-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Gzip-specific functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************ + * + * @function: + * FT_Stream_OpenGzip + * + * @description: + * Open a new stream to parse gzip-compressed font files. This is + * mainly used to support the compressed `*.pcf.gz' fonts that come + * with XFree86. + * + * @input: + * stream :: + * The target embedding stream. + * + * source :: + * The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream. + * + * In certain builds of the library, gzip compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a gzipped stream from + * it and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with zlib support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenGzip( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGZIP_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftimage.h b/utils/openttd/freetype/ftimage.h new file mode 100644 index 00000000000..0a1960afc8a --- /dev/null +++ b/utils/openttd/freetype/ftimage.h @@ -0,0 +1,1253 @@ +/***************************************************************************/ +/* */ +/* ftimage.h */ +/* */ +/* FreeType glyph image formats and default raster interface */ +/* (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Note: A `raster' is simply a scan-line converter, used to render */ + /* FT_Outlines into FT_Bitmaps. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTIMAGE_H__ +#define __FTIMAGE_H__ + + + /* _STANDALONE_ is from ftgrays.c */ +#ifndef _STANDALONE_ +#include <ft2build.h> +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pos */ + /* */ + /* <Description> */ + /* The type FT_Pos is a 32-bit integer used to store vectorial */ + /* coordinates. Depending on the context, these can represent */ + /* distances in integer font units, or 16.16, or 26.6 fixed float */ + /* pixel coordinates. */ + /* */ + typedef signed long FT_Pos; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Vector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector; coordinates are of */ + /* the FT_Pos type. */ + /* */ + /* <Fields> */ + /* x :: The horizontal coordinate. */ + /* y :: The vertical coordinate. */ + /* */ + typedef struct FT_Vector_ + { + FT_Pos x; + FT_Pos y; + + } FT_Vector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_BBox */ + /* */ + /* <Description> */ + /* A structure used to hold an outline's bounding box, i.e., the */ + /* coordinates of its extrema in the horizontal and vertical */ + /* directions. */ + /* */ + /* <Fields> */ + /* xMin :: The horizontal minimum (left-most). */ + /* */ + /* yMin :: The vertical minimum (bottom-most). */ + /* */ + /* xMax :: The horizontal maximum (right-most). */ + /* */ + /* yMax :: The vertical maximum (top-most). */ + /* */ + typedef struct FT_BBox_ + { + FT_Pos xMin, yMin; + FT_Pos xMax, yMax; + + } FT_BBox; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Pixel_Mode */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of pixels in a */ + /* given bitmap. Note that additional formats may be added in the */ + /* future. */ + /* */ + /* <Values> */ + /* FT_PIXEL_MODE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_PIXEL_MODE_MONO :: */ + /* A monochrome bitmap, using 1~bit per pixel. Note that pixels */ + /* are stored in most-significant order (MSB), which means that */ + /* the left-most pixel in a byte has value 128. */ + /* */ + /* FT_PIXEL_MODE_GRAY :: */ + /* An 8-bit bitmap, generally used to represent anti-aliased glyph */ + /* images. Each pixel is stored in one byte. Note that the number */ + /* of value `gray' levels is stored in the `num_grays' field of */ + /* the @FT_Bitmap structure (it generally is 256). */ + /* */ + /* FT_PIXEL_MODE_GRAY2 :: */ + /* A 2-bit/pixel bitmap, used to represent embedded anti-aliased */ + /* bitmaps in font files according to the OpenType specification. */ + /* We haven't found a single font using this format, however. */ + /* */ + /* FT_PIXEL_MODE_GRAY4 :: */ + /* A 4-bit/pixel bitmap, used to represent embedded anti-aliased */ + /* bitmaps in font files according to the OpenType specification. */ + /* We haven't found a single font using this format, however. */ + /* */ + /* FT_PIXEL_MODE_LCD :: */ + /* An 8-bit bitmap, used to represent RGB or BGR decimated glyph */ + /* images used for display on LCD displays; the bitmap is three */ + /* times wider than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD. */ + /* */ + /* FT_PIXEL_MODE_LCD_V :: */ + /* An 8-bit bitmap, used to represent RGB or BGR decimated glyph */ + /* images used for display on rotated LCD displays; the bitmap */ + /* is three times taller than the original glyph image. See also */ + /* @FT_RENDER_MODE_LCD_V. */ + /* */ + typedef enum FT_Pixel_Mode_ + { + FT_PIXEL_MODE_NONE = 0, + FT_PIXEL_MODE_MONO, + FT_PIXEL_MODE_GRAY, + FT_PIXEL_MODE_GRAY2, + FT_PIXEL_MODE_GRAY4, + FT_PIXEL_MODE_LCD, + FT_PIXEL_MODE_LCD_V, + + FT_PIXEL_MODE_MAX /* do not remove */ + + } FT_Pixel_Mode; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_pixel_mode_xxx */ + /* */ + /* <Description> */ + /* A list of deprecated constants. Use the corresponding */ + /* @FT_Pixel_Mode values instead. */ + /* */ + /* <Values> */ + /* ft_pixel_mode_none :: See @FT_PIXEL_MODE_NONE. */ + /* ft_pixel_mode_mono :: See @FT_PIXEL_MODE_MONO. */ + /* ft_pixel_mode_grays :: See @FT_PIXEL_MODE_GRAY. */ + /* ft_pixel_mode_pal2 :: See @FT_PIXEL_MODE_GRAY2. */ + /* ft_pixel_mode_pal4 :: See @FT_PIXEL_MODE_GRAY4. */ + /* */ +#define ft_pixel_mode_none FT_PIXEL_MODE_NONE +#define ft_pixel_mode_mono FT_PIXEL_MODE_MONO +#define ft_pixel_mode_grays FT_PIXEL_MODE_GRAY +#define ft_pixel_mode_pal2 FT_PIXEL_MODE_GRAY2 +#define ft_pixel_mode_pal4 FT_PIXEL_MODE_GRAY4 + + /* */ + +#if 0 + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Palette_Mode */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT! */ + /* */ + /* An enumeration type to describe the format of a bitmap palette, */ + /* used with ft_pixel_mode_pal4 and ft_pixel_mode_pal8. */ + /* */ + /* <Values> */ + /* ft_palette_mode_rgb :: The palette is an array of 3-byte RGB */ + /* records. */ + /* */ + /* ft_palette_mode_rgba :: The palette is an array of 4-byte RGBA */ + /* records. */ + /* */ + /* <Note> */ + /* As ft_pixel_mode_pal2, pal4 and pal8 are currently unused by */ + /* FreeType, these types are not handled by the library itself. */ + /* */ + typedef enum FT_Palette_Mode_ + { + ft_palette_mode_rgb = 0, + ft_palette_mode_rgba, + + ft_palette_mode_max /* do not remove */ + + } FT_Palette_Mode; + + /* */ + +#endif + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Bitmap */ + /* */ + /* <Description> */ + /* A structure used to describe a bitmap or pixmap to the raster. */ + /* Note that we now manage pixmaps of various depths through the */ + /* `pixel_mode' field. */ + /* */ + /* <Fields> */ + /* rows :: The number of bitmap rows. */ + /* */ + /* width :: The number of pixels in bitmap row. */ + /* */ + /* pitch :: The pitch's absolute value is the number of bytes */ + /* taken by one bitmap row, including padding. */ + /* However, the pitch is positive when the bitmap has */ + /* a `down' flow, and negative when it has an `up' */ + /* flow. In all cases, the pitch is an offset to add */ + /* to a bitmap pointer in order to go down one row. */ + /* */ + /* buffer :: A typeless pointer to the bitmap buffer. This */ + /* value should be aligned on 32-bit boundaries in */ + /* most cases. */ + /* */ + /* num_grays :: This field is only used with */ + /* @FT_PIXEL_MODE_GRAY; it gives the number of gray */ + /* levels used in the bitmap. */ + /* */ + /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ + /* See @FT_Pixel_Mode for possible values. */ + /* */ + /* palette_mode :: This field is intended for paletted pixel modes; */ + /* it indicates how the palette is stored. Not */ + /* used currently. */ + /* */ + /* palette :: A typeless pointer to the bitmap palette; this */ + /* field is intended for paletted pixel modes. Not */ + /* used currently. */ + /* */ + /* <Note> */ + /* For now, the only pixel modes supported by FreeType are mono and */ + /* grays. However, drivers might be added in the future to support */ + /* more `colorful' options. */ + /* */ + typedef struct FT_Bitmap_ + { + int rows; + int width; + int pitch; + unsigned char* buffer; + short num_grays; + char pixel_mode; + char palette_mode; + void* palette; + + } FT_Bitmap; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline */ + /* */ + /* <Description> */ + /* This structure is used to describe an outline to the scan-line */ + /* converter. */ + /* */ + /* <Fields> */ + /* n_contours :: The number of contours in the outline. */ + /* */ + /* n_points :: The number of points in the outline. */ + /* */ + /* points :: A pointer to an array of `n_points' @FT_Vector */ + /* elements, giving the outline's point coordinates. */ + /* */ + /* tags :: A pointer to an array of `n_points' chars, giving */ + /* each outline point's type. If bit~0 is unset, the */ + /* point is `off' the curve, i.e., a Bézier control */ + /* point, while it is `on' when set. */ + /* */ + /* Bit~1 is meaningful for `off' points only. If set, */ + /* it indicates a third-order Bézier arc control point; */ + /* and a second-order control point if unset. */ + /* */ + /* contours :: An array of `n_contours' shorts, giving the end */ + /* point of each contour within the outline. For */ + /* example, the first contour is defined by the points */ + /* `0' to `contours[0]', the second one is defined by */ + /* the points `contours[0]+1' to `contours[1]', etc. */ + /* */ + /* flags :: A set of bit flags used to characterize the outline */ + /* and give hints to the scan-converter and hinter on */ + /* how to convert/grid-fit it. See @FT_OUTLINE_FLAGS. */ + /* */ + typedef struct FT_Outline_ + { + short n_contours; /* number of contours in glyph */ + short n_points; /* number of points in the glyph */ + + FT_Vector* points; /* the outline's points */ + char* tags; /* the points flags */ + short* contours; /* the contour end points */ + + int flags; /* outline masks */ + + } FT_Outline; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_OUTLINE_FLAGS */ + /* */ + /* <Description> */ + /* A list of bit-field constants use for the flags in an outline's */ + /* `flags' field. */ + /* */ + /* <Values> */ + /* FT_OUTLINE_NONE :: */ + /* Value~0 is reserved. */ + /* */ + /* FT_OUTLINE_OWNER :: */ + /* If set, this flag indicates that the outline's field arrays */ + /* (i.e., `points', `flags', and `contours') are `owned' by the */ + /* outline object, and should thus be freed when it is destroyed. */ + /* */ + /* FT_OUTLINE_EVEN_ODD_FILL :: */ + /* By default, outlines are filled using the non-zero winding rule. */ + /* If set to 1, the outline will be filled using the even-odd fill */ + /* rule (only works with the smooth raster). */ + /* */ + /* FT_OUTLINE_REVERSE_FILL :: */ + /* By default, outside contours of an outline are oriented in */ + /* clock-wise direction, as defined in the TrueType specification. */ + /* This flag is set if the outline uses the opposite direction */ + /* (typically for Type~1 fonts). This flag is ignored by the scan */ + /* converter. */ + /* */ + /* FT_OUTLINE_IGNORE_DROPOUTS :: */ + /* By default, the scan converter will try to detect drop-outs in */ + /* an outline and correct the glyph bitmap to ensure consistent */ + /* shape continuity. If set, this flag hints the scan-line */ + /* converter to ignore such cases. */ + /* */ + /* FT_OUTLINE_SMART_DROPOUTS :: */ + /* Select smart dropout control. If unset, use simple dropout */ + /* control. Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. */ + /* */ + /* FT_OUTLINE_INCLUDE_STUBS :: */ + /* If set, turn pixels on for `stubs', otherwise exclude them. */ + /* Ignored if @FT_OUTLINE_IGNORE_DROPOUTS is set. */ + /* */ + /* FT_OUTLINE_HIGH_PRECISION :: */ + /* This flag indicates that the scan-line converter should try to */ + /* convert this outline to bitmaps with the highest possible */ + /* quality. It is typically set for small character sizes. Note */ + /* that this is only a hint that might be completely ignored by a */ + /* given scan-converter. */ + /* */ + /* FT_OUTLINE_SINGLE_PASS :: */ + /* This flag is set to force a given scan-converter to only use a */ + /* single pass over the outline to render a bitmap glyph image. */ + /* Normally, it is set for very large character sizes. It is only */ + /* a hint that might be completely ignored by a given */ + /* scan-converter. */ + /* */ + /* <Note> */ + /* Please refer to the description of the `SCANTYPE' instruction in */ + /* the OpenType specification (in file `ttinst1.doc') how simple */ + /* drop-outs, smart drop-outs, and stubs are defined. */ + /* */ +#define FT_OUTLINE_NONE 0x0 +#define FT_OUTLINE_OWNER 0x1 +#define FT_OUTLINE_EVEN_ODD_FILL 0x2 +#define FT_OUTLINE_REVERSE_FILL 0x4 +#define FT_OUTLINE_IGNORE_DROPOUTS 0x8 +#define FT_OUTLINE_SMART_DROPOUTS 0x10 +#define FT_OUTLINE_INCLUDE_STUBS 0x20 + +#define FT_OUTLINE_HIGH_PRECISION 0x100 +#define FT_OUTLINE_SINGLE_PASS 0x200 + + + /************************************************************************* + * + * @enum: + * ft_outline_flags + * + * @description: + * These constants are deprecated. Please use the corresponding + * @FT_OUTLINE_FLAGS values. + * + * @values: + * ft_outline_none :: See @FT_OUTLINE_NONE. + * ft_outline_owner :: See @FT_OUTLINE_OWNER. + * ft_outline_even_odd_fill :: See @FT_OUTLINE_EVEN_ODD_FILL. + * ft_outline_reverse_fill :: See @FT_OUTLINE_REVERSE_FILL. + * ft_outline_ignore_dropouts :: See @FT_OUTLINE_IGNORE_DROPOUTS. + * ft_outline_high_precision :: See @FT_OUTLINE_HIGH_PRECISION. + * ft_outline_single_pass :: See @FT_OUTLINE_SINGLE_PASS. + */ +#define ft_outline_none FT_OUTLINE_NONE +#define ft_outline_owner FT_OUTLINE_OWNER +#define ft_outline_even_odd_fill FT_OUTLINE_EVEN_ODD_FILL +#define ft_outline_reverse_fill FT_OUTLINE_REVERSE_FILL +#define ft_outline_ignore_dropouts FT_OUTLINE_IGNORE_DROPOUTS +#define ft_outline_high_precision FT_OUTLINE_HIGH_PRECISION +#define ft_outline_single_pass FT_OUTLINE_SINGLE_PASS + + /* */ + +#define FT_CURVE_TAG( flag ) ( flag & 3 ) + +#define FT_CURVE_TAG_ON 1 +#define FT_CURVE_TAG_CONIC 0 +#define FT_CURVE_TAG_CUBIC 2 + +#define FT_CURVE_TAG_TOUCH_X 8 /* reserved for the TrueType hinter */ +#define FT_CURVE_TAG_TOUCH_Y 16 /* reserved for the TrueType hinter */ + +#define FT_CURVE_TAG_TOUCH_BOTH ( FT_CURVE_TAG_TOUCH_X | \ + FT_CURVE_TAG_TOUCH_Y ) + +#define FT_Curve_Tag_On FT_CURVE_TAG_ON +#define FT_Curve_Tag_Conic FT_CURVE_TAG_CONIC +#define FT_Curve_Tag_Cubic FT_CURVE_TAG_CUBIC +#define FT_Curve_Tag_Touch_X FT_CURVE_TAG_TOUCH_X +#define FT_Curve_Tag_Touch_Y FT_CURVE_TAG_TOUCH_Y + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_MoveToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `move */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `move to' is emitted to start a new contour in an outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `move to'. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_MoveToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_MoveTo_Func FT_Outline_MoveToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_LineToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `line */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `line to' is emitted to indicate a segment in the outline. */ + /* */ + /* <Input> */ + /* to :: A pointer to the target point of the `line to'. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of the */ + /* decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_LineToFunc)( const FT_Vector* to, + void* user ); + +#define FT_Outline_LineTo_Func FT_Outline_LineToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_ConicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type use to describe the signature of a `conic */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `conic to' is emitted to indicate a second-order Bézier arc in */ + /* the outline. */ + /* */ + /* <Input> */ + /* control :: An intermediate control point between the last position */ + /* and the new target in `to'. */ + /* */ + /* to :: A pointer to the target end point of the conic arc. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_ConicToFunc)( const FT_Vector* control, + const FT_Vector* to, + void* user ); + +#define FT_Outline_ConicTo_Func FT_Outline_ConicToFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Outline_CubicToFunc */ + /* */ + /* <Description> */ + /* A function pointer type used to describe the signature of a `cubic */ + /* to' function during outline walking/decomposition. */ + /* */ + /* A `cubic to' is emitted to indicate a third-order Bézier arc. */ + /* */ + /* <Input> */ + /* control1 :: A pointer to the first Bézier control point. */ + /* */ + /* control2 :: A pointer to the second Bézier control point. */ + /* */ + /* to :: A pointer to the target end point. */ + /* */ + /* user :: A typeless pointer which is passed from the caller of */ + /* the decomposition function. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + typedef int + (*FT_Outline_CubicToFunc)( const FT_Vector* control1, + const FT_Vector* control2, + const FT_Vector* to, + void* user ); + +#define FT_Outline_CubicTo_Func FT_Outline_CubicToFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Outline_Funcs */ + /* */ + /* <Description> */ + /* A structure to hold various function pointers used during outline */ + /* decomposition in order to emit segments, conic, and cubic Béziers, */ + /* as well as `move to' and `close to' operations. */ + /* */ + /* <Fields> */ + /* move_to :: The `move to' emitter. */ + /* */ + /* line_to :: The segment emitter. */ + /* */ + /* conic_to :: The second-order Bézier arc emitter. */ + /* */ + /* cubic_to :: The third-order Bézier arc emitter. */ + /* */ + /* shift :: The shift that is applied to coordinates before they */ + /* are sent to the emitter. */ + /* */ + /* delta :: The delta that is applied to coordinates before they */ + /* are sent to the emitter, but after the shift. */ + /* */ + /* <Note> */ + /* The point coordinates sent to the emitters are the transformed */ + /* version of the original coordinates (this is important for high */ + /* accuracy during scan-conversion). The transformation is simple: */ + /* */ + /* { */ + /* x' = (x << shift) - delta */ + /* y' = (x << shift) - delta */ + /* } */ + /* */ + /* Set the value of `shift' and `delta' to~0 to get the original */ + /* point coordinates. */ + /* */ + typedef struct FT_Outline_Funcs_ + { + FT_Outline_MoveToFunc move_to; + FT_Outline_LineToFunc line_to; + FT_Outline_ConicToFunc conic_to; + FT_Outline_CubicToFunc cubic_to; + + int shift; + FT_Pos delta; + + } FT_Outline_Funcs; + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_IMAGE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags to an unsigned long type. */ + /* */ + /* <Note> */ + /* Since many 16-bit compilers don't like 32-bit enumerations, you */ + /* should redefine this macro in case of problems to something like */ + /* this: */ + /* */ + /* { */ + /* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value */ + /* } */ + /* */ + /* to get a simple enumeration without assigning special numbers. */ + /* */ +#ifndef FT_IMAGE_TAG +#define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \ + value = ( ( (unsigned long)_x1 << 24 ) | \ + ( (unsigned long)_x2 << 16 ) | \ + ( (unsigned long)_x3 << 8 ) | \ + (unsigned long)_x4 ) +#endif /* FT_IMAGE_TAG */ + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Glyph_Format */ + /* */ + /* <Description> */ + /* An enumeration type used to describe the format of a given glyph */ + /* image. Note that this version of FreeType only supports two image */ + /* formats, even though future font drivers will be able to register */ + /* their own format. */ + /* */ + /* <Values> */ + /* FT_GLYPH_FORMAT_NONE :: */ + /* The value~0 is reserved. */ + /* */ + /* FT_GLYPH_FORMAT_COMPOSITE :: */ + /* The glyph image is a composite of several other images. This */ + /* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to */ + /* report compound glyphs (like accented characters). */ + /* */ + /* FT_GLYPH_FORMAT_BITMAP :: */ + /* The glyph image is a bitmap, and can be described as an */ + /* @FT_Bitmap. You generally need to access the `bitmap' field of */ + /* the @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_OUTLINE :: */ + /* The glyph image is a vectorial outline made of line segments */ + /* and Bézier arcs; it can be described as an @FT_Outline; you */ + /* generally want to access the `outline' field of the */ + /* @FT_GlyphSlotRec structure to read it. */ + /* */ + /* FT_GLYPH_FORMAT_PLOTTER :: */ + /* The glyph image is a vectorial path with no inside and outside */ + /* contours. Some Type~1 fonts, like those in the Hershey family, */ + /* contain glyphs in this format. These are described as */ + /* @FT_Outline, but FreeType isn't currently capable of rendering */ + /* them correctly. */ + /* */ + typedef enum FT_Glyph_Format_ + { + FT_IMAGE_TAG( FT_GLYPH_FORMAT_NONE, 0, 0, 0, 0 ), + + FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ), + FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ) + + } FT_Glyph_Format; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* ft_glyph_format_xxx */ + /* */ + /* <Description> */ + /* A list of deprecated constants. Use the corresponding */ + /* @FT_Glyph_Format values instead. */ + /* */ + /* <Values> */ + /* ft_glyph_format_none :: See @FT_GLYPH_FORMAT_NONE. */ + /* ft_glyph_format_composite :: See @FT_GLYPH_FORMAT_COMPOSITE. */ + /* ft_glyph_format_bitmap :: See @FT_GLYPH_FORMAT_BITMAP. */ + /* ft_glyph_format_outline :: See @FT_GLYPH_FORMAT_OUTLINE. */ + /* ft_glyph_format_plotter :: See @FT_GLYPH_FORMAT_PLOTTER. */ + /* */ +#define ft_glyph_format_none FT_GLYPH_FORMAT_NONE +#define ft_glyph_format_composite FT_GLYPH_FORMAT_COMPOSITE +#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP +#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE +#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** R A S T E R D E F I N I T I O N S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* A raster is a scan converter, in charge of rendering an outline into */ + /* a a bitmap. This section contains the public API for rasters. */ + /* */ + /* Note that in FreeType 2, all rasters are now encapsulated within */ + /* specific modules called `renderers'. See `freetype/ftrender.h' for */ + /* more details on renderers. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* raster */ + /* */ + /* <Title> */ + /* Scanline Converter */ + /* */ + /* <Abstract> */ + /* How vectorial outlines are converted into bitmaps and pixmaps. */ + /* */ + /* <Description> */ + /* This section contains technical definitions. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Raster */ + /* */ + /* <Description> */ + /* A handle (pointer) to a raster object. Each object can be used */ + /* independently to convert an outline into a bitmap or pixmap. */ + /* */ + typedef struct FT_RasterRec_* FT_Raster; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Span */ + /* */ + /* <Description> */ + /* A structure used to model a single span of gray (or black) pixels */ + /* when rendering a monochrome or anti-aliased bitmap. */ + /* */ + /* <Fields> */ + /* x :: The span's horizontal start position. */ + /* */ + /* len :: The span's length in pixels. */ + /* */ + /* coverage :: The span color/coverage, ranging from 0 (background) */ + /* to 255 (foreground). Only used for anti-aliased */ + /* rendering. */ + /* */ + /* <Note> */ + /* This structure is used by the span drawing callback type named */ + /* @FT_SpanFunc which takes the y~coordinate of the span as a */ + /* a parameter. */ + /* */ + /* The coverage value is always between 0 and 255. If you want less */ + /* gray values, the callback function has to reduce them. */ + /* */ + typedef struct FT_Span_ + { + short x; + unsigned short len; + unsigned char coverage; + + } FT_Span; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_SpanFunc */ + /* */ + /* <Description> */ + /* A function used as a call-back by the anti-aliased renderer in */ + /* order to let client applications draw themselves the gray pixel */ + /* spans on each scan line. */ + /* */ + /* <Input> */ + /* y :: The scanline's y~coordinate. */ + /* */ + /* count :: The number of spans to draw on this scanline. */ + /* */ + /* spans :: A table of `count' spans to draw on the scanline. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Note> */ + /* This callback allows client applications to directly render the */ + /* gray spans of the anti-aliased bitmap to any kind of surfaces. */ + /* */ + /* This can be used to write anti-aliased outlines directly to a */ + /* given background bitmap, and even perform translucency. */ + /* */ + /* Note that the `count' field cannot be greater than a fixed value */ + /* defined by the `FT_MAX_GRAY_SPANS' configuration macro in */ + /* `ftoption.h'. By default, this value is set to~32, which means */ + /* that if there are more than 32~spans on a given scanline, the */ + /* callback is called several times with the same `y' parameter in */ + /* order to draw all callbacks. */ + /* */ + /* Otherwise, the callback is only called once per scan-line, and */ + /* only for those scanlines that do have `gray' pixels on them. */ + /* */ + typedef void + (*FT_SpanFunc)( int y, + int count, + const FT_Span* spans, + void* user ); + +#define FT_Raster_Span_Func FT_SpanFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitTest_Func */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ + /* */ + /* A function used as a call-back by the monochrome scan-converter */ + /* to test whether a given target pixel is already set to the drawing */ + /* `color'. These tests are crucial to implement drop-out control */ + /* per-se the TrueType spec. */ + /* */ + /* <Input> */ + /* y :: The pixel's y~coordinate. */ + /* */ + /* x :: The pixel's x~coordinate. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Return> */ + /* 1~if the pixel is `set', 0~otherwise. */ + /* */ + typedef int + (*FT_Raster_BitTest_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_BitSet_Func */ + /* */ + /* <Description> */ + /* THIS TYPE IS DEPRECATED. DO NOT USE IT. */ + /* */ + /* A function used as a call-back by the monochrome scan-converter */ + /* to set an individual target pixel. This is crucial to implement */ + /* drop-out control according to the TrueType specification. */ + /* */ + /* <Input> */ + /* y :: The pixel's y~coordinate. */ + /* */ + /* x :: The pixel's x~coordinate. */ + /* */ + /* user :: User-supplied data that is passed to the callback. */ + /* */ + /* <Return> */ + /* 1~if the pixel is `set', 0~otherwise. */ + /* */ + typedef void + (*FT_Raster_BitSet_Func)( int y, + int x, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_RASTER_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flag constants as used in the `flags' field of a */ + /* @FT_Raster_Params structure. */ + /* */ + /* <Values> */ + /* FT_RASTER_FLAG_DEFAULT :: This value is 0. */ + /* */ + /* FT_RASTER_FLAG_AA :: This flag is set to indicate that an */ + /* anti-aliased glyph image should be */ + /* generated. Otherwise, it will be */ + /* monochrome (1-bit). */ + /* */ + /* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct */ + /* rendering. In this mode, client */ + /* applications must provide their own span */ + /* callback. This lets them directly */ + /* draw or compose over an existing bitmap. */ + /* If this bit is not set, the target */ + /* pixmap's buffer _must_ be zeroed before */ + /* rendering. */ + /* */ + /* Note that for now, direct rendering is */ + /* only possible with anti-aliased glyphs. */ + /* */ + /* FT_RASTER_FLAG_CLIP :: This flag is only used in direct */ + /* rendering mode. If set, the output will */ + /* be clipped to a box specified in the */ + /* `clip_box' field of the */ + /* @FT_Raster_Params structure. */ + /* */ + /* Note that by default, the glyph bitmap */ + /* is clipped to the target pixmap, except */ + /* in direct rendering mode where all spans */ + /* are generated if no clipping box is set. */ + /* */ +#define FT_RASTER_FLAG_DEFAULT 0x0 +#define FT_RASTER_FLAG_AA 0x1 +#define FT_RASTER_FLAG_DIRECT 0x2 +#define FT_RASTER_FLAG_CLIP 0x4 + + /* deprecated */ +#define ft_raster_flag_default FT_RASTER_FLAG_DEFAULT +#define ft_raster_flag_aa FT_RASTER_FLAG_AA +#define ft_raster_flag_direct FT_RASTER_FLAG_DIRECT +#define ft_raster_flag_clip FT_RASTER_FLAG_CLIP + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Params */ + /* */ + /* <Description> */ + /* A structure to hold the arguments used by a raster's render */ + /* function. */ + /* */ + /* <Fields> */ + /* target :: The target bitmap. */ + /* */ + /* source :: A pointer to the source glyph image (e.g., an */ + /* @FT_Outline). */ + /* */ + /* flags :: The rendering flags. */ + /* */ + /* gray_spans :: The gray span drawing callback. */ + /* */ + /* black_spans :: The black span drawing callback. */ + /* */ + /* bit_test :: The bit test callback. UNIMPLEMENTED! */ + /* */ + /* bit_set :: The bit set callback. UNIMPLEMENTED! */ + /* */ + /* user :: User-supplied data that is passed to each drawing */ + /* callback. */ + /* */ + /* clip_box :: An optional clipping box. It is only used in */ + /* direct rendering mode. Note that coordinates here */ + /* should be expressed in _integer_ pixels (and not in */ + /* 26.6 fixed-point units). */ + /* */ + /* <Note> */ + /* An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA */ + /* bit flag is set in the `flags' field, otherwise a monochrome */ + /* bitmap is generated. */ + /* */ + /* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the */ + /* raster will call the `gray_spans' callback to draw gray pixel */ + /* spans, in the case of an aa glyph bitmap, it will call */ + /* `black_spans', and `bit_test' and `bit_set' in the case of a */ + /* monochrome bitmap. This allows direct composition over a */ + /* pre-existing bitmap through user-provided callbacks to perform the */ + /* span drawing/composition. */ + /* */ + /* Note that the `bit_test' and `bit_set' callbacks are required when */ + /* rendering a monochrome bitmap, as they are crucial to implement */ + /* correct drop-out control as defined in the TrueType specification. */ + /* */ + typedef struct FT_Raster_Params_ + { + const FT_Bitmap* target; + const void* source; + int flags; + FT_SpanFunc gray_spans; + FT_SpanFunc black_spans; + FT_Raster_BitTest_Func bit_test; /* doesn't work! */ + FT_Raster_BitSet_Func bit_set; /* doesn't work! */ + void* user; + FT_BBox clip_box; + + } FT_Raster_Params; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_NewFunc */ + /* */ + /* <Description> */ + /* A function used to create a new raster object. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory allocator. */ + /* */ + /* <Output> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `memory' parameter is a typeless pointer in order to avoid */ + /* un-wanted dependencies on the rest of the FreeType code. In */ + /* practice, it is an @FT_Memory object, i.e., a handle to the */ + /* standard FreeType memory allocator. However, this field can be */ + /* completely ignored by a given raster implementation. */ + /* */ + typedef int + (*FT_Raster_NewFunc)( void* memory, + FT_Raster* raster ); + +#define FT_Raster_New_Func FT_Raster_NewFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_DoneFunc */ + /* */ + /* <Description> */ + /* A function used to destroy a given raster object. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + typedef void + (*FT_Raster_DoneFunc)( FT_Raster raster ); + +#define FT_Raster_Done_Func FT_Raster_DoneFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_ResetFunc */ + /* */ + /* <Description> */ + /* FreeType provides an area of memory called the `render pool', */ + /* available to all registered rasters. This pool can be freely used */ + /* during a given scan-conversion but is shared by all rasters. Its */ + /* content is thus transient. */ + /* */ + /* This function is called each time the render pool changes, or just */ + /* after a new raster object is created. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* pool_base :: The address in memory of the render pool. */ + /* */ + /* pool_size :: The size in bytes of the render pool. */ + /* */ + /* <Note> */ + /* Rasters can ignore the render pool and rely on dynamic memory */ + /* allocation if they want to (a handle to the memory allocator is */ + /* passed to the raster constructor). However, this is not */ + /* recommended for efficiency purposes. */ + /* */ + typedef void + (*FT_Raster_ResetFunc)( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ); + +#define FT_Raster_Reset_Func FT_Raster_ResetFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_SetModeFunc */ + /* */ + /* <Description> */ + /* This function is a generic facility to change modes or attributes */ + /* in a given raster. This can be used for debugging purposes, or */ + /* simply to allow implementation-specific `features' in a given */ + /* raster module. */ + /* */ + /* <Input> */ + /* raster :: A handle to the new raster object. */ + /* */ + /* mode :: A 4-byte tag used to name the mode or property. */ + /* */ + /* args :: A pointer to the new mode/property to use. */ + /* */ + typedef int + (*FT_Raster_SetModeFunc)( FT_Raster raster, + unsigned long mode, + void* args ); + +#define FT_Raster_Set_Mode_Func FT_Raster_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Raster_RenderFunc */ + /* */ + /* <Description> */ + /* Invoke a given raster to scan-convert a given glyph image into a */ + /* target bitmap. */ + /* */ + /* <Input> */ + /* raster :: A handle to the raster object. */ + /* */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* store the rendering parameters. */ + /* */ + /* <Return> */ + /* Error code. 0~means success. */ + /* */ + /* <Note> */ + /* The exact format of the source image depends on the raster's glyph */ + /* format defined in its @FT_Raster_Funcs structure. It can be an */ + /* @FT_Outline or anything else in order to support a large array of */ + /* glyph formats. */ + /* */ + /* Note also that the render function can fail and return a */ + /* `FT_Err_Unimplemented_Feature' error code if the raster used does */ + /* not support direct composition. */ + /* */ + /* XXX: For now, the standard raster doesn't support direct */ + /* composition but this should change for the final release (see */ + /* the files `demos/src/ftgrays.c' and `demos/src/ftgrays2.c' */ + /* for examples of distinct implementations which support direct */ + /* composition). */ + /* */ + typedef int + (*FT_Raster_RenderFunc)( FT_Raster raster, + const FT_Raster_Params* params ); + +#define FT_Raster_Render_Func FT_Raster_RenderFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Raster_Funcs */ + /* */ + /* <Description> */ + /* A structure used to describe a given raster class to the library. */ + /* */ + /* <Fields> */ + /* glyph_format :: The supported glyph format for this raster. */ + /* */ + /* raster_new :: The raster constructor. */ + /* */ + /* raster_reset :: Used to reset the render pool within the raster. */ + /* */ + /* raster_render :: A function to render a glyph into a given bitmap. */ + /* */ + /* raster_done :: The raster destructor. */ + /* */ + typedef struct FT_Raster_Funcs_ + { + FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; + FT_Raster_ResetFunc raster_reset; + FT_Raster_SetModeFunc raster_set_mode; + FT_Raster_RenderFunc raster_render; + FT_Raster_DoneFunc raster_done; + + } FT_Raster_Funcs; + + + /* */ + + +FT_END_HEADER + +#endif /* __FTIMAGE_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/utils/openttd/freetype/ftincrem.h b/utils/openttd/freetype/ftincrem.h new file mode 100644 index 00000000000..96abedea7b6 --- /dev/null +++ b/utils/openttd/freetype/ftincrem.h @@ -0,0 +1,349 @@ +/***************************************************************************/ +/* */ +/* ftincrem.h */ +/* */ +/* FreeType incremental loading (specification). */ +/* */ +/* Copyright 2002, 2003, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTINCREM_H__ +#define __FTINCREM_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * incremental + * + * @title: + * Incremental Loading + * + * @abstract: + * Custom Glyph Loading. + * + * @description: + * This section contains various functions used to perform so-called + * `incremental' glyph loading. This is a mode where all glyphs loaded + * from a given @FT_Face are provided by the client application, + * + * Apart from that, all other tables are loaded normally from the font + * file. This mode is useful when FreeType is used within another + * engine, e.g., a PostScript Imaging Processor. + * + * To enable this mode, you must use @FT_Open_Face, passing an + * @FT_Parameter with the @FT_PARAM_TAG_INCREMENTAL tag and an + * @FT_Incremental_Interface value. See the comments for + * @FT_Incremental_InterfaceRec for an example. + * + */ + + + /*************************************************************************** + * + * @type: + * FT_Incremental + * + * @description: + * An opaque type describing a user-provided object used to implement + * `incremental' glyph loading within FreeType. This is used to support + * embedded fonts in certain environments (e.g., PostScript interpreters), + * where the glyph data isn't in the font file, or must be overridden by + * different values. + * + * @note: + * It is up to client applications to create and implement @FT_Incremental + * objects, as long as they provide implementations for the methods + * @FT_Incremental_GetGlyphDataFunc, @FT_Incremental_FreeGlyphDataFunc + * and @FT_Incremental_GetGlyphMetricsFunc. + * + * See the description of @FT_Incremental_InterfaceRec to understand how + * to use incremental objects with FreeType. + * + */ + typedef struct FT_IncrementalRec_* FT_Incremental; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_MetricsRec + * + * @description: + * A small structure used to contain the basic glyph metrics returned + * by the @FT_Incremental_GetGlyphMetricsFunc method. + * + * @fields: + * bearing_x :: + * Left bearing, in font units. + * + * bearing_y :: + * Top bearing, in font units. + * + * advance :: + * Glyph advance, in font units. + * + * @note: + * These correspond to horizontal or vertical metrics depending on the + * value of the `vertical' argument to the function + * @FT_Incremental_GetGlyphMetricsFunc. + * + */ + typedef struct FT_Incremental_MetricsRec_ + { + FT_Long bearing_x; + FT_Long bearing_y; + FT_Long advance; + + } FT_Incremental_MetricsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_Metrics + * + * @description: + * A handle to an @FT_Incremental_MetricsRec structure. + * + */ + typedef struct FT_Incremental_MetricsRec_* FT_Incremental_Metrics; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphDataFunc + * + * @description: + * A function called by FreeType to access a given glyph's data bytes + * during @FT_Load_Glyph or @FT_Load_Char if incremental loading is + * enabled. + * + * Note that the format of the glyph's data bytes depends on the font + * file format. For TrueType, it must correspond to the raw bytes within + * the `glyf' table. For PostScript formats, it must correspond to the + * *unencrypted* charstring bytes, without any `lenIV' header. It is + * undefined for any other format. + * + * @input: + * incremental :: + * Handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * @output: + * adata :: + * A structure describing the returned glyph data bytes (which will be + * accessed as a read-only byte block). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If this function returns successfully the method + * @FT_Incremental_FreeGlyphDataFunc will be called later to release + * the data bytes. + * + * Nested calls to @FT_Incremental_GetGlyphDataFunc can happen for + * compound glyphs. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphDataFunc)( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Data* adata ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_FreeGlyphDataFunc + * + * @description: + * A function used to release the glyph data bytes returned by a + * successful call to @FT_Incremental_GetGlyphDataFunc. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * data :: + * A structure describing the glyph data bytes (which will be accessed + * as a read-only byte block). + * + */ + typedef void + (*FT_Incremental_FreeGlyphDataFunc)( FT_Incremental incremental, + FT_Data* data ); + + + /*************************************************************************** + * + * @type: + * FT_Incremental_GetGlyphMetricsFunc + * + * @description: + * A function used to retrieve the basic metrics of a given glyph index + * before accessing its data. This is necessary because, in certain + * formats like TrueType, the metrics are stored in a different place from + * the glyph images proper. + * + * @input: + * incremental :: + * A handle to an opaque @FT_Incremental handle provided by the client + * application. + * + * glyph_index :: + * Index of relevant glyph. + * + * vertical :: + * If true, return vertical metrics. + * + * ametrics :: + * This parameter is used for both input and output. + * The original glyph metrics, if any, in font units. If metrics are + * not available all the values must be set to zero. + * + * @output: + * ametrics :: + * The replacement glyph metrics in font units. + * + */ + typedef FT_Error + (*FT_Incremental_GetGlyphMetricsFunc) + ( FT_Incremental incremental, + FT_UInt glyph_index, + FT_Bool vertical, + FT_Incremental_MetricsRec *ametrics ); + + + /************************************************************************** + * + * @struct: + * FT_Incremental_FuncsRec + * + * @description: + * A table of functions for accessing fonts that load data + * incrementally. Used in @FT_Incremental_InterfaceRec. + * + * @fields: + * get_glyph_data :: + * The function to get glyph data. Must not be null. + * + * free_glyph_data :: + * The function to release glyph data. Must not be null. + * + * get_glyph_metrics :: + * The function to get glyph metrics. May be null if the font does + * not provide overriding glyph metrics. + * + */ + typedef struct FT_Incremental_FuncsRec_ + { + FT_Incremental_GetGlyphDataFunc get_glyph_data; + FT_Incremental_FreeGlyphDataFunc free_glyph_data; + FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics; + + } FT_Incremental_FuncsRec; + + + /*************************************************************************** + * + * @struct: + * FT_Incremental_InterfaceRec + * + * @description: + * A structure to be used with @FT_Open_Face to indicate that the user + * wants to support incremental glyph loading. You should use it with + * @FT_PARAM_TAG_INCREMENTAL as in the following example: + * + * { + * FT_Incremental_InterfaceRec inc_int; + * FT_Parameter parameter; + * FT_Open_Args open_args; + * + * + * // set up incremental descriptor + * inc_int.funcs = my_funcs; + * inc_int.object = my_object; + * + * // set up optional parameter + * parameter.tag = FT_PARAM_TAG_INCREMENTAL; + * parameter.data = &inc_int; + * + * // set up FT_Open_Args structure + * open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; + * open_args.pathname = my_font_pathname; + * open_args.num_params = 1; + * open_args.params = ¶meter; // we use one optional argument + * + * // open the font + * error = FT_Open_Face( library, &open_args, index, &face ); + * ... + * } + * + */ + typedef struct FT_Incremental_InterfaceRec_ + { + const FT_Incremental_FuncsRec* funcs; + FT_Incremental object; + + } FT_Incremental_InterfaceRec; + + + /*************************************************************************** + * + * @type: + * FT_Incremental_Interface + * + * @description: + * A pointer to an @FT_Incremental_InterfaceRec structure. + * + */ + typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_INCREMENTAL + * + * @description: + * A constant used as the tag of @FT_Parameter structures to indicate + * an incremental loading object to be used by FreeType. + * + */ +#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) + + /* */ + +FT_END_HEADER + +#endif /* __FTINCREM_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftlcdfil.h b/utils/openttd/freetype/ftlcdfil.h new file mode 100644 index 00000000000..1e38fe7fb25 --- /dev/null +++ b/utils/openttd/freetype/ftlcdfil.h @@ -0,0 +1,166 @@ +/***************************************************************************/ +/* */ +/* ftlcdfil.h */ +/* */ +/* FreeType API for color filtering of subpixel bitmap glyphs */ +/* (specification). */ +/* */ +/* Copyright 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_LCD_FILTER_H__ +#define __FT_LCD_FILTER_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + /*************************************************************************** + * + * @section: + * lcd_filtering + * + * @title: + * LCD Filtering + * + * @abstract: + * Reduce color fringes of LCD-optimized bitmaps. + * + * @description: + * The @FT_Library_SetLcdFilter API can be used to specify a low-pass + * filter which is then applied to LCD-optimized bitmaps generated + * through @FT_Render_Glyph. This is useful to reduce color fringes + * which would occur with unfiltered rendering. + * + * Note that no filter is active by default, and that this function is + * *not* implemented in default builds of the library. You need to + * #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file + * in order to activate it. + */ + + + /**************************************************************************** + * + * @func: + * FT_LcdFilter + * + * @description: + * A list of values to identify various types of LCD filters. + * + * @values: + * FT_LCD_FILTER_NONE :: + * Do not perform filtering. When used with subpixel rendering, this + * results in sometimes severe color fringes. + * + * FT_LCD_FILTER_DEFAULT :: + * The default filter reduces color fringes considerably, at the cost + * of a slight blurriness in the output. + * + * FT_LCD_FILTER_LIGHT :: + * The light filter is a variant that produces less blurriness at the + * cost of slightly more color fringes than the default one. It might + * be better, depending on taste, your monitor, or your personal vision. + * + * FT_LCD_FILTER_LEGACY :: + * This filter corresponds to the original libXft color filter. It + * provides high contrast output but can exhibit really bad color + * fringes if glyphs are not extremely well hinted to the pixel grid. + * In other words, it only works well if the TrueType bytecode + * interpreter is enabled *and* high-quality hinted fonts are used. + * + * This filter is only provided for comparison purposes, and might be + * disabled or stay unsupported in the future. + * + * @since: + * 2.3.0 + */ + typedef enum FT_LcdFilter_ + { + FT_LCD_FILTER_NONE = 0, + FT_LCD_FILTER_DEFAULT = 1, + FT_LCD_FILTER_LIGHT = 2, + FT_LCD_FILTER_LEGACY = 16, + + FT_LCD_FILTER_MAX /* do not remove */ + + } FT_LcdFilter; + + + /************************************************************************** + * + * @func: + * FT_Library_SetLcdFilter + * + * @description: + * This function is used to apply color filtering to LCD decimated + * bitmaps, like the ones used when calling @FT_Render_Glyph with + * @FT_RENDER_MODE_LCD or @FT_RENDER_MODE_LCD_V. + * + * @input: + * library :: + * A handle to the target library instance. + * + * filter :: + * The filter type. + * + * You can use @FT_LCD_FILTER_NONE here to disable this feature, or + * @FT_LCD_FILTER_DEFAULT to use a default filter that should work + * well on most LCD screens. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This feature is always disabled by default. Clients must make an + * explicit call to this function with a `filter' value other than + * @FT_LCD_FILTER_NONE in order to enable it. + * + * Due to *PATENTS* covering subpixel rendering, this function doesn't + * do anything except returning `FT_Err_Unimplemented_Feature' if the + * configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING is not + * defined in your build of the library, which should correspond to all + * default builds of FreeType. + * + * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, + * @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char. + * + * It does _not_ affect the output of @FT_Outline_Render and + * @FT_Outline_Get_Bitmap. + * + * If this feature is activated, the dimensions of LCD glyph bitmaps are + * either larger or taller than the dimensions of the corresponding + * outline with regards to the pixel grid. For example, for + * @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and + * up to 3~pixels to the right. + * + * The bitmap offset values are adjusted correctly, so clients shouldn't + * need to modify their layout and glyph positioning code when enabling + * the filter. + * + * @since: + * 2.3.0 + */ + FT_EXPORT( FT_Error ) + FT_Library_SetLcdFilter( FT_Library library, + FT_LcdFilter filter ); + + /* */ + + +FT_END_HEADER + +#endif /* __FT_LCD_FILTER_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftlist.h b/utils/openttd/freetype/ftlist.h new file mode 100644 index 00000000000..93b05fc0d62 --- /dev/null +++ b/utils/openttd/freetype/ftlist.h @@ -0,0 +1,273 @@ +/***************************************************************************/ +/* */ +/* ftlist.h */ +/* */ +/* Generic list support for FreeType (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file implements functions relative to list processing. Its */ + /* data structures are defined in `freetype.h'. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTLIST_H__ +#define __FTLIST_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /* <Title> */ + /* List Processing */ + /* */ + /* <Abstract> */ + /* Simple management of lists. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to list */ + /* processing using doubly-linked nodes. */ + /* */ + /* <Order> */ + /* FT_List */ + /* FT_ListNode */ + /* FT_ListRec */ + /* FT_ListNodeRec */ + /* */ + /* FT_List_Add */ + /* FT_List_Insert */ + /* FT_List_Find */ + /* FT_List_Remove */ + /* FT_List_Up */ + /* FT_List_Iterate */ + /* FT_List_Iterator */ + /* FT_List_Finalize */ + /* FT_List_Destructor */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Find */ + /* */ + /* <Description> */ + /* Find the list node for a given listed object. */ + /* */ + /* <Input> */ + /* list :: A pointer to the parent list. */ + /* data :: The address of the listed object. */ + /* */ + /* <Return> */ + /* List node. NULL if it wasn't found. */ + /* */ + FT_EXPORT( FT_ListNode ) + FT_List_Find( FT_List list, + void* data ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Add */ + /* */ + /* <Description> */ + /* Append an element to the end of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to append. */ + /* */ + FT_EXPORT( void ) + FT_List_Add( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Insert */ + /* */ + /* <Description> */ + /* Insert an element at the head of a list. */ + /* */ + /* <InOut> */ + /* list :: A pointer to parent list. */ + /* node :: The node to insert. */ + /* */ + FT_EXPORT( void ) + FT_List_Insert( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Remove */ + /* */ + /* <Description> */ + /* Remove a node from a list. This function doesn't check whether */ + /* the node is in the list! */ + /* */ + /* <Input> */ + /* node :: The node to remove. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* */ + FT_EXPORT( void ) + FT_List_Remove( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Up */ + /* */ + /* <Description> */ + /* Move a node to the head/top of a list. Used to maintain LRU */ + /* lists. */ + /* */ + /* <InOut> */ + /* list :: A pointer to the parent list. */ + /* node :: The node to move. */ + /* */ + FT_EXPORT( void ) + FT_List_Up( FT_List list, + FT_ListNode node ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Iterator */ + /* */ + /* <Description> */ + /* An FT_List iterator function which is called during a list parse */ + /* by @FT_List_Iterate. */ + /* */ + /* <Input> */ + /* node :: The current iteration list node. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. */ + /* Can be used to point to the iteration's state. */ + /* */ + typedef FT_Error + (*FT_List_Iterator)( FT_ListNode node, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Iterate */ + /* */ + /* <Description> */ + /* Parse a list and calls a given iterator function on each element. */ + /* Note that parsing is stopped as soon as one of the iterator calls */ + /* returns a non-zero value. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* iterator :: An iterator function, called on each node of the list. */ + /* user :: A user-supplied field which is passed as the second */ + /* argument to the iterator. */ + /* */ + /* <Return> */ + /* The result (a FreeType error code) of the last iterator call. */ + /* */ + FT_EXPORT( FT_Error ) + FT_List_Iterate( FT_List list, + FT_List_Iterator iterator, + void* user ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_List_Destructor */ + /* */ + /* <Description> */ + /* An @FT_List iterator function which is called during a list */ + /* finalization by @FT_List_Finalize to destroy all elements in a */ + /* given list. */ + /* */ + /* <Input> */ + /* system :: The current system object. */ + /* */ + /* data :: The current object to destroy. */ + /* */ + /* user :: A typeless pointer passed to @FT_List_Iterate. It can */ + /* be used to point to the iteration's state. */ + /* */ + typedef void + (*FT_List_Destructor)( FT_Memory memory, + void* data, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_List_Finalize */ + /* */ + /* <Description> */ + /* Destroy all elements in the list as well as the list itself. */ + /* */ + /* <Input> */ + /* list :: A handle to the list. */ + /* */ + /* destroy :: A list destructor that will be applied to each element */ + /* of the list. */ + /* */ + /* memory :: The current memory object which handles deallocation. */ + /* */ + /* user :: A user-supplied field which is passed as the last */ + /* argument to the destructor. */ + /* */ + FT_EXPORT( void ) + FT_List_Finalize( FT_List list, + FT_List_Destructor destroy, + FT_Memory memory, + void* user ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTLIST_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftlzw.h b/utils/openttd/freetype/ftlzw.h new file mode 100644 index 00000000000..00d40169a75 --- /dev/null +++ b/utils/openttd/freetype/ftlzw.h @@ -0,0 +1,99 @@ +/***************************************************************************/ +/* */ +/* ftlzw.h */ +/* */ +/* LZW-compressed stream support. */ +/* */ +/* Copyright 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTLZW_H__ +#define __FTLZW_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* lzw */ + /* */ + /* <Title> */ + /* LZW Streams */ + /* */ + /* <Abstract> */ + /* Using LZW-compressed font files. */ + /* */ + /* <Description> */ + /* This section contains the declaration of LZW-specific functions. */ + /* */ + /*************************************************************************/ + + /************************************************************************ + * + * @function: + * FT_Stream_OpenLZW + * + * @description: + * Open a new stream to parse LZW-compressed font files. This is + * mainly used to support the compressed `*.pcf.Z' fonts that come + * with XFree86. + * + * @input: + * stream :: The target embedding stream. + * + * source :: The source stream. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source stream must be opened _before_ calling this function. + * + * Calling the internal function `FT_Stream_Close' on the new stream will + * *not* call `FT_Stream_Close' on the source stream. None of the stream + * objects will be released to the heap. + * + * The stream implementation is very basic and resets the decompression + * process each time seeking backwards is needed within the stream + * + * In certain builds of the library, LZW compression recognition is + * automatically handled when calling @FT_New_Face or @FT_Open_Face. + * This means that if no font driver is capable of handling the raw + * compressed file, the library will try to open a LZW stream from it + * and re-open the face with it. + * + * This function may return `FT_Err_Unimplemented_Feature' if your build + * of FreeType was not compiled with LZW support. + */ + FT_EXPORT( FT_Error ) + FT_Stream_OpenLZW( FT_Stream stream, + FT_Stream source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTLZW_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftmac.h b/utils/openttd/freetype/ftmac.h new file mode 100644 index 00000000000..ab5bab5170c --- /dev/null +++ b/utils/openttd/freetype/ftmac.h @@ -0,0 +1,274 @@ +/***************************************************************************/ +/* */ +/* ftmac.h */ +/* */ +/* Additional Mac-specific API. */ +/* */ +/* Copyright 1996-2001, 2004, 2006, 2007 by */ +/* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* NOTE: Include this file after <freetype/freetype.h> and after any */ +/* Mac-specific headers (because this header uses Mac types such as */ +/* Handle, FSSpec, FSRef, etc.) */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMAC_H__ +#define __FTMAC_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + +/* gcc-3.4.1 and later can warn about functions tagged as deprecated */ +#ifndef FT_DEPRECATED_ATTRIBUTE +#if defined(__GNUC__) && \ + ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) +#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) +#else +#define FT_DEPRECATED_ATTRIBUTE +#endif +#endif + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* mac_specific */ + /* */ + /* <Title> */ + /* Mac Specific Interface */ + /* */ + /* <Abstract> */ + /* Only available on the Macintosh. */ + /* */ + /* <Description> */ + /* The following definitions are only available if FreeType is */ + /* compiled on a Macintosh. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FOND */ + /* */ + /* <Description> */ + /* Create a new face object from a FOND resource. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* fond :: A FOND resource. */ + /* */ + /* face_index :: Only supported for the -1 `sanity check' special */ + /* case. */ + /* */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Notes> */ + /* This function can be used to create @FT_Face objects from fonts */ + /* that are installed in the system as follows. */ + /* */ + /* { */ + /* fond = GetResource( 'FOND', fontName ); */ + /* error = FT_New_Face_From_FOND( library, fond, 0, &face ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FOND( FT_Library library, + Handle fond, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font (e.g., Times New Roman */ + /* Bold). */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFile_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return an FSSpec for the disk file containing the named font. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* pathSpec :: FSSpec to the file. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* face_index :: Index of the face. For passing to */ + /* @FT_New_Face_From_FSSpec. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFile_From_Mac_ATS_Name( const char* fontName, + FSSpec* pathSpec, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_GetFilePath_From_Mac_ATS_Name */ + /* */ + /* <Description> */ + /* Return a pathname of the disk file and face index for given font */ + /* name which is handled by ATS framework. */ + /* */ + /* <Input> */ + /* fontName :: Mac OS name of the font in ATS framework. */ + /* */ + /* <Output> */ + /* path :: Buffer to store pathname of the file. For passing */ + /* to @FT_New_Face. The client must allocate this */ + /* buffer before calling this function. */ + /* */ + /* maxPathSize :: Lengths of the buffer `path' that client allocated. */ + /* */ + /* face_index :: Index of the face. For passing to @FT_New_Face. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_GetFilePath_From_Mac_ATS_Name( const char* fontName, + UInt8* path, + UInt32 maxPathSize, + FT_Long* face_index ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSSpec */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSSpec to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSSpec to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSSpec is identical to @FT_New_Face except */ + /* it accepts an FSSpec instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSSpec( FT_Library library, + const FSSpec *spec, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Face_From_FSRef */ + /* */ + /* <Description> */ + /* Create a new face object from a given resource and typeface index */ + /* using an FSRef to the font file. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library resource. */ + /* */ + /* <Input> */ + /* spec :: FSRef to the font file. */ + /* */ + /* face_index :: The index of the face within the resource. The */ + /* first face has index~0. */ + /* <Output> */ + /* aface :: A handle to a new face object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* @FT_New_Face_From_FSRef is identical to @FT_New_Face except */ + /* it accepts an FSRef instead of a path. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Face_From_FSRef( FT_Library library, + const FSRef *ref, + FT_Long face_index, + FT_Face *aface ) + FT_DEPRECATED_ATTRIBUTE; + + /* */ + + +FT_END_HEADER + + +#endif /* __FTMAC_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftmm.h b/utils/openttd/freetype/ftmm.h new file mode 100644 index 00000000000..6261fa87b14 --- /dev/null +++ b/utils/openttd/freetype/ftmm.h @@ -0,0 +1,378 @@ +/***************************************************************************/ +/* */ +/* ftmm.h */ +/* */ +/* FreeType Multiple Master font interface (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMM_H__ +#define __FTMM_H__ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* multiple_masters */ + /* */ + /* <Title> */ + /* Multiple Masters */ + /* */ + /* <Abstract> */ + /* How to manage Multiple Masters fonts. */ + /* */ + /* <Description> */ + /* The following types and functions are used to manage Multiple */ + /* Master fonts, i.e., the selection of specific design instances by */ + /* setting design axis coordinates. */ + /* */ + /* George Williams has extended this interface to make it work with */ + /* both Type~1 Multiple Masters fonts and GX distortable (var) */ + /* fonts. Some of these routines only work with MM fonts, others */ + /* will work with both types. They are similar enough that a */ + /* consistent interface makes sense. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters fonts. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + typedef struct FT_MM_Axis_ + { + FT_String* name; + FT_Long minimum; + FT_Long maximum; + + } FT_MM_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Multi_Master */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* font. */ + /* */ + /* This structure can't be used for GX var fonts. */ + /* */ + /* <Fields> */ + /* num_axis :: Number of axes. Cannot exceed~4. */ + /* */ + /* num_designs :: Number of designs; should be normally 2^num_axis */ + /* even though the Type~1 specification strangely */ + /* allows for intermediate designs to be present. This */ + /* number cannot exceed~16. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* */ + typedef struct FT_Multi_Master_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_MM_Axis axis[T1_MAX_MM_AXIS]; + + } FT_Multi_Master; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Axis */ + /* */ + /* <Description> */ + /* A simple structure used to model a given axis in design space for */ + /* Multiple Masters and GX var fonts. */ + /* */ + /* <Fields> */ + /* name :: The axis's name. */ + /* Not always meaningful for GX. */ + /* */ + /* minimum :: The axis's minimum design coordinate. */ + /* */ + /* def :: The axis's default design coordinate. */ + /* FreeType computes meaningful default values for MM; it */ + /* is then an integer value, not in 16.16 format. */ + /* */ + /* maximum :: The axis's maximum design coordinate. */ + /* */ + /* tag :: The axis's tag (the GX equivalent to `name'). */ + /* FreeType provides default values for MM if possible. */ + /* */ + /* strid :: The entry in `name' table (another GX version of */ + /* `name'). */ + /* Not meaningful for MM. */ + /* */ + typedef struct FT_Var_Axis_ + { + FT_String* name; + + FT_Fixed minimum; + FT_Fixed def; + FT_Fixed maximum; + + FT_ULong tag; + FT_UInt strid; + + } FT_Var_Axis; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Var_Named_Style */ + /* */ + /* <Description> */ + /* A simple structure used to model a named style in a GX var font. */ + /* */ + /* This structure can't be used for MM fonts. */ + /* */ + /* <Fields> */ + /* coords :: The design coordinates for this style. */ + /* This is an array with one entry for each axis. */ + /* */ + /* strid :: The entry in `name' table identifying this style. */ + /* */ + typedef struct FT_Var_Named_Style_ + { + FT_Fixed* coords; + FT_UInt strid; + + } FT_Var_Named_Style; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_MM_Var */ + /* */ + /* <Description> */ + /* A structure used to model the axes and space of a Multiple Masters */ + /* or GX var distortable font. */ + /* */ + /* Some fields are specific to one format and not to the other. */ + /* */ + /* <Fields> */ + /* num_axis :: The number of axes. The maximum value is~4 for */ + /* MM; no limit in GX. */ + /* */ + /* num_designs :: The number of designs; should be normally */ + /* 2^num_axis for MM fonts. Not meaningful for GX */ + /* (where every glyph could have a different */ + /* number of designs). */ + /* */ + /* num_namedstyles :: The number of named styles; only meaningful for */ + /* GX which allows certain design coordinates to */ + /* have a string ID (in the `name' table) */ + /* associated with them. The font can tell the */ + /* user that, for example, Weight=1.5 is `Bold'. */ + /* */ + /* axis :: A table of axis descriptors. */ + /* GX fonts contain slightly more data than MM. */ + /* */ + /* namedstyles :: A table of named styles. */ + /* Only meaningful with GX. */ + /* */ + typedef struct FT_MM_Var_ + { + FT_UInt num_axis; + FT_UInt num_designs; + FT_UInt num_namedstyles; + FT_Var_Axis* axis; + FT_Var_Named_Style* namedstyle; + + } FT_MM_Var; + + + /* */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Multi_Master */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master descriptor of a given font. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Multi_Master( FT_Face face, + FT_Multi_Master *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_MM_Var */ + /* */ + /* <Description> */ + /* Retrieve the Multiple Master/GX var descriptor of a given font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Output> */ + /* amaster :: The Multiple Masters descriptor. */ + /* Allocates a data structure, which the user must free */ + /* (a single call to FT_FREE will do it). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_Var( FT_Face face, + FT_MM_Var* *amaster ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters fonts, choose an interpolated font design */ + /* through design coordinates. */ + /* */ + /* This function can't be used with GX fonts. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Design_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Master or GX Var fonts, choose an interpolated font */ + /* design through design coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: An array of design coordinates. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_MM_Blend_Coordinates */ + /* */ + /* <Description> */ + /* For Multiple Masters and GX var fonts, choose an interpolated font */ + /* design through normalized blend coordinates. */ + /* */ + /* <InOut> */ + /* face :: A handle to the source face. */ + /* */ + /* <Input> */ + /* num_coords :: The number of design coordinates (must be equal to */ + /* the number of axes in the font). */ + /* */ + /* coords :: The design coordinates array (each element must be */ + /* between 0 and 1.0). */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Var_Blend_Coordinates */ + /* */ + /* <Description> */ + /* This is another name of @FT_Set_MM_Blend_Coordinates. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTMM_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftmodapi.h b/utils/openttd/freetype/ftmodapi.h new file mode 100644 index 00000000000..899812ad4ec --- /dev/null +++ b/utils/openttd/freetype/ftmodapi.h @@ -0,0 +1,441 @@ +/***************************************************************************/ +/* */ +/* ftmodapi.h */ +/* */ +/* FreeType modules public interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMODAPI_H__ +#define __FTMODAPI_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /* <Title> */ + /* Module Management */ + /* */ + /* <Abstract> */ + /* How to add, upgrade, and remove modules from FreeType. */ + /* */ + /* <Description> */ + /* The definitions below are used to manage modules within FreeType. */ + /* Modules can be added, upgraded, and removed at runtime. */ + /* */ + /*************************************************************************/ + + + /* module bit flags */ +#define FT_MODULE_FONT_DRIVER 1 /* this module is a font driver */ +#define FT_MODULE_RENDERER 2 /* this module is a renderer */ +#define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ +#define FT_MODULE_STYLER 8 /* this module is a styler */ + +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ + /* scalable fonts */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ + /* support vector outlines */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ + /* own hinter */ + + + /* deprecated values */ +#define ft_module_font_driver FT_MODULE_FONT_DRIVER +#define ft_module_renderer FT_MODULE_RENDERER +#define ft_module_hinter FT_MODULE_HINTER +#define ft_module_styler FT_MODULE_STYLER + +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER + + + typedef FT_Pointer FT_Module_Interface; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Constructor */ + /* */ + /* <Description> */ + /* A function used to initialize (not create) a new module object. */ + /* */ + /* <Input> */ + /* module :: The module to initialize. */ + /* */ + typedef FT_Error + (*FT_Module_Constructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Destructor */ + /* */ + /* <Description> */ + /* A function used to finalize (not destroy) a given module object. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ + typedef void + (*FT_Module_Destructor)( FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Module_Requester */ + /* */ + /* <Description> */ + /* A function used to query a given module for a specific interface. */ + /* */ + /* <Input> */ + /* module :: The module to finalize. */ + /* */ + /* name :: The name of the interface in the module. */ + /* */ + typedef FT_Module_Interface + (*FT_Module_Requester)( FT_Module module, + const char* name ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Module_Class */ + /* */ + /* <Description> */ + /* The module class descriptor. */ + /* */ + /* <Fields> */ + /* module_flags :: Bit flags describing the module. */ + /* */ + /* module_size :: The size of one module object/instance in */ + /* bytes. */ + /* */ + /* module_name :: The name of the module. */ + /* */ + /* module_version :: The version, as a 16.16 fixed number */ + /* (major.minor). */ + /* */ + /* module_requires :: The version of FreeType this module requires, */ + /* as a 16.16 fixed number (major.minor). Starts */ + /* at version 2.0, i.e., 0x20000. */ + /* */ + /* module_init :: The initializing function. */ + /* */ + /* module_done :: The finalizing function. */ + /* */ + /* get_interface :: The interface requesting function. */ + /* */ + typedef struct FT_Module_Class_ + { + FT_ULong module_flags; + FT_Long module_size; + const FT_String* module_name; + FT_Fixed module_version; + FT_Fixed module_requires; + + const void* module_interface; + + FT_Module_Constructor module_init; + FT_Module_Destructor module_done; + FT_Module_Requester get_interface; + + } FT_Module_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Module */ + /* */ + /* <Description> */ + /* Add a new module to a given library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* clazz :: A pointer to class descriptor for the module. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Add_Module( FT_Library library, + const FT_Module_Class* clazz ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module */ + /* */ + /* <Description> */ + /* Find a module by its name. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module handle. 0~if none was found. */ + /* */ + /* <Note> */ + /* FreeType's internal modules aren't documented very well, and you */ + /* should look up the source code for details. */ + /* */ + FT_EXPORT( FT_Module ) + FT_Get_Module( FT_Library library, + const char* module_name ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Remove_Module */ + /* */ + /* <Description> */ + /* Remove a given module from a library instance. */ + /* */ + /* <InOut> */ + /* library :: A handle to a library object. */ + /* */ + /* <Input> */ + /* module :: A handle to a module object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The module object is destroyed by the function in case of success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Remove_Module( FT_Library library, + FT_Module module ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Library */ + /* */ + /* <Description> */ + /* This function is used to create a new FreeType library instance */ + /* from a given memory object. It is thus possible to use libraries */ + /* with distinct memory allocators within the same program. */ + /* */ + /* <Input> */ + /* memory :: A handle to the original memory object. */ + /* */ + /* <Output> */ + /* alibrary :: A pointer to handle of a new library object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Library( FT_Memory memory, + FT_Library *alibrary ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Library */ + /* */ + /* <Description> */ + /* Discard a given library object. This closes all drivers and */ + /* discards all resource objects. */ + /* */ + /* <Input> */ + /* library :: A handle to the target library. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Library( FT_Library library ); + +/* */ + + typedef void + (*FT_DebugHook_Func)( void* arg ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Debug_Hook */ + /* */ + /* <Description> */ + /* Set a debug hook function for debugging the interpreter of a font */ + /* format. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* hook_index :: The index of the debug hook. You should use the */ + /* values defined in `ftobjs.h', e.g., */ + /* `FT_DEBUG_HOOK_TRUETYPE'. */ + /* */ + /* debug_hook :: The function used to debug the interpreter. */ + /* */ + /* <Note> */ + /* Currently, four debug hook slots are available, but only two (for */ + /* the TrueType and the Type~1 interpreter) are defined. */ + /* */ + /* Since the internal headers of FreeType are no longer installed, */ + /* the symbol `FT_DEBUG_HOOK_TRUETYPE' isn't available publicly. */ + /* This is a bug and will be fixed in a forthcoming release. */ + /* */ + FT_EXPORT( void ) + FT_Set_Debug_Hook( FT_Library library, + FT_UInt hook_index, + FT_DebugHook_Func debug_hook ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Add_Default_Modules */ + /* */ + /* <Description> */ + /* Add the set of default drivers to a given library object. */ + /* This is only useful when you create a library object with */ + /* @FT_New_Library (usually to plug a custom memory manager). */ + /* */ + /* <InOut> */ + /* library :: A handle to a new library object. */ + /* */ + FT_EXPORT( void ) + FT_Add_Default_Modules( FT_Library library ); + + + + /************************************************************************** + * + * @section: + * truetype_engine + * + * @title: + * The TrueType Engine + * + * @abstract: + * TrueType bytecode support. + * + * @description: + * This section contains a function used to query the level of TrueType + * bytecode support compiled in this version of the library. + * + */ + + + /************************************************************************** + * + * @enum: + * FT_TrueTypeEngineType + * + * @description: + * A list of values describing which kind of TrueType bytecode + * engine is implemented in a given FT_Library instance. It is used + * by the @FT_Get_TrueType_Engine_Type function. + * + * @values: + * FT_TRUETYPE_ENGINE_TYPE_NONE :: + * The library doesn't implement any kind of bytecode interpreter. + * + * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: + * The library implements a bytecode interpreter that doesn't + * support the patented operations of the TrueType virtual machine. + * + * Its main use is to load certain Asian fonts which position and + * scale glyph components with bytecode instructions. It produces + * bad output for most other fonts. + * + * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: + * The library implements a bytecode interpreter that covers + * the full instruction set of the TrueType virtual machine. + * See the file `docs/PATENTS' for legal aspects. + * + * @since: + * 2.2 + * + */ + typedef enum FT_TrueTypeEngineType_ + { + FT_TRUETYPE_ENGINE_TYPE_NONE = 0, + FT_TRUETYPE_ENGINE_TYPE_UNPATENTED, + FT_TRUETYPE_ENGINE_TYPE_PATENTED + + } FT_TrueTypeEngineType; + + + /************************************************************************** + * + * @func: + * FT_Get_TrueType_Engine_Type + * + * @description: + * Return a @FT_TrueTypeEngineType value to indicate which level of + * the TrueType virtual machine a given library instance supports. + * + * @input: + * library :: + * A library instance. + * + * @return: + * A value indicating which level is supported. + * + * @since: + * 2.2 + * + */ + FT_EXPORT( FT_TrueTypeEngineType ) + FT_Get_TrueType_Engine_Type( FT_Library library ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTMODAPI_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftmoderr.h b/utils/openttd/freetype/ftmoderr.h new file mode 100644 index 00000000000..b0115dd0dd3 --- /dev/null +++ b/utils/openttd/freetype/ftmoderr.h @@ -0,0 +1,155 @@ +/***************************************************************************/ +/* */ +/* ftmoderr.h */ +/* */ +/* FreeType module error offsets (specification). */ +/* */ +/* Copyright 2001, 2002, 2003, 2004, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is used to define the FreeType module error offsets. */ + /* */ + /* The lower byte gives the error code, the higher byte gives the */ + /* module. The base module has error offset 0. For example, the error */ + /* `FT_Err_Invalid_File_Format' has value 0x003, the error */ + /* `TT_Err_Invalid_File_Format' has value 0x1103, the error */ + /* `T1_Err_Invalid_File_Format' has value 0x1203, etc. */ + /* */ + /* Undefine the macro FT_CONFIG_OPTION_USE_MODULE_ERRORS in ftoption.h */ + /* to make the higher byte always zero (disabling the module error */ + /* mechanism). */ + /* */ + /* It can also be used to create a module error message table easily */ + /* with something like */ + /* */ + /* { */ + /* #undef __FTMODERR_H__ */ + /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ + /* #define FT_MODERR_START_LIST { */ + /* #define FT_MODERR_END_LIST { 0, 0 } }; */ + /* */ + /* const struct */ + /* { */ + /* int mod_err_offset; */ + /* const char* mod_err_msg */ + /* } ft_mod_errors[] = */ + /* */ + /* #include FT_MODULE_ERRORS_H */ + /* } */ + /* */ + /* To use such a table, all errors must be ANDed with 0xFF00 to remove */ + /* the error code. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTMODERR_H__ +#define __FTMODERR_H__ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** SETUP MACROS *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#undef FT_NEED_EXTERN_C + +#ifndef FT_MODERRDEF + +#ifdef FT_CONFIG_OPTION_USE_MODULE_ERRORS +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = v, +#else +#define FT_MODERRDEF( e, v, s ) FT_Mod_Err_ ## e = 0, +#endif + +#define FT_MODERR_START_LIST enum { +#define FT_MODERR_END_LIST FT_Mod_Err_Max }; + +#ifdef __cplusplus +#define FT_NEED_EXTERN_C + extern "C" { +#endif + +#endif /* !FT_MODERRDEF */ + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** LIST MODULE ERROR BASES *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_MODERR_START_LIST + FT_MODERR_START_LIST +#endif + + + FT_MODERRDEF( Base, 0x000, "base module" ) + FT_MODERRDEF( Autofit, 0x100, "autofitter module" ) + FT_MODERRDEF( BDF, 0x200, "BDF module" ) + FT_MODERRDEF( Cache, 0x300, "cache module" ) + FT_MODERRDEF( CFF, 0x400, "CFF module" ) + FT_MODERRDEF( CID, 0x500, "CID module" ) + FT_MODERRDEF( Gzip, 0x600, "Gzip module" ) + FT_MODERRDEF( LZW, 0x700, "LZW module" ) + FT_MODERRDEF( OTvalid, 0x800, "OpenType validation module" ) + FT_MODERRDEF( PCF, 0x900, "PCF module" ) + FT_MODERRDEF( PFR, 0xA00, "PFR module" ) + FT_MODERRDEF( PSaux, 0xB00, "PS auxiliary module" ) + FT_MODERRDEF( PShinter, 0xC00, "PS hinter module" ) + FT_MODERRDEF( PSnames, 0xD00, "PS names module" ) + FT_MODERRDEF( Raster, 0xE00, "raster module" ) + FT_MODERRDEF( SFNT, 0xF00, "SFNT module" ) + FT_MODERRDEF( Smooth, 0x1000, "smooth raster module" ) + FT_MODERRDEF( TrueType, 0x1100, "TrueType module" ) + FT_MODERRDEF( Type1, 0x1200, "Type 1 module" ) + FT_MODERRDEF( Type42, 0x1300, "Type 42 module" ) + FT_MODERRDEF( Winfonts, 0x1400, "Windows FON/FNT module" ) + + +#ifdef FT_MODERR_END_LIST + FT_MODERR_END_LIST +#endif + + + /*******************************************************************/ + /*******************************************************************/ + /***** *****/ + /***** CLEANUP *****/ + /***** *****/ + /*******************************************************************/ + /*******************************************************************/ + + +#ifdef FT_NEED_EXTERN_C + } +#endif + +#undef FT_MODERR_START_LIST +#undef FT_MODERR_END_LIST +#undef FT_MODERRDEF +#undef FT_NEED_EXTERN_C + + +#endif /* __FTMODERR_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftotval.h b/utils/openttd/freetype/ftotval.h new file mode 100644 index 00000000000..027f2e88657 --- /dev/null +++ b/utils/openttd/freetype/ftotval.h @@ -0,0 +1,203 @@ +/***************************************************************************/ +/* */ +/* ftotval.h */ +/* */ +/* FreeType API for validating OpenType tables (specification). */ +/* */ +/* Copyright 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +/***************************************************************************/ +/* */ +/* */ +/* Warning: This module might be moved to a different library in the */ +/* future to avoid a tight dependency between FreeType and the */ +/* OpenType specification. */ +/* */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOTVAL_H__ +#define __FTOTVAL_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* ot_validation */ + /* */ + /* <Title> */ + /* OpenType Validation */ + /* */ + /* <Abstract> */ + /* An API to validate OpenType tables. */ + /* */ + /* <Description> */ + /* This section contains the declaration of functions to validate */ + /* some OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @enum: + * FT_VALIDATE_OTXXX + * + * @description: + * A list of bit-field constants used with @FT_OpenType_Validate to + * indicate which OpenType tables should be validated. + * + * @values: + * FT_VALIDATE_BASE :: + * Validate BASE table. + * + * FT_VALIDATE_GDEF :: + * Validate GDEF table. + * + * FT_VALIDATE_GPOS :: + * Validate GPOS table. + * + * FT_VALIDATE_GSUB :: + * Validate GSUB table. + * + * FT_VALIDATE_JSTF :: + * Validate JSTF table. + * + * FT_VALIDATE_MATH :: + * Validate MATH table. + * + * FT_VALIDATE_OT :: + * Validate all OpenType tables (BASE, GDEF, GPOS, GSUB, JSTF, MATH). + * + */ +#define FT_VALIDATE_BASE 0x0100 +#define FT_VALIDATE_GDEF 0x0200 +#define FT_VALIDATE_GPOS 0x0400 +#define FT_VALIDATE_GSUB 0x0800 +#define FT_VALIDATE_JSTF 0x1000 +#define FT_VALIDATE_MATH 0x2000 + +#define FT_VALIDATE_OT FT_VALIDATE_BASE | \ + FT_VALIDATE_GDEF | \ + FT_VALIDATE_GPOS | \ + FT_VALIDATE_GSUB | \ + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH + + /* */ + + /********************************************************************** + * + * @function: + * FT_OpenType_Validate + * + * @description: + * Validate various OpenType tables to assure that all offsets and + * indices are valid. The idea is that a higher-level library which + * actually does the text layout can access those tables without + * error checking (which can be quite time consuming). + * + * @input: + * face :: + * A handle to the input face. + * + * validation_flags :: + * A bit field which specifies the tables to be validated. See + * @FT_VALIDATE_OTXXX for possible values. + * + * @output: + * BASE_table :: + * A pointer to the BASE table. + * + * GDEF_table :: + * A pointer to the GDEF table. + * + * GPOS_table :: + * A pointer to the GPOS table. + * + * GSUB_table :: + * A pointer to the GSUB table. + * + * JSTF_table :: + * A pointer to the JSTF table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with OpenType fonts, returning an error + * otherwise. + * + * After use, the application should deallocate the five tables with + * @FT_OpenType_Free. A NULL value indicates that the table either + * doesn't exist in the font, or the application hasn't asked for + * validation. + */ + FT_EXPORT( FT_Error ) + FT_OpenType_Validate( FT_Face face, + FT_UInt validation_flags, + FT_Bytes *BASE_table, + FT_Bytes *GDEF_table, + FT_Bytes *GPOS_table, + FT_Bytes *GSUB_table, + FT_Bytes *JSTF_table ); + + /* */ + + /********************************************************************** + * + * @function: + * FT_OpenType_Free + * + * @description: + * Free the buffer allocated by OpenType validator. + * + * @input: + * face :: + * A handle to the input face. + * + * table :: + * The pointer to the buffer that is allocated by + * @FT_OpenType_Validate. + * + * @note: + * This function must be used to free the buffer allocated by + * @FT_OpenType_Validate only. + */ + FT_EXPORT( void ) + FT_OpenType_Free( FT_Face face, + FT_Bytes table ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTOTVAL_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftoutln.h b/utils/openttd/freetype/ftoutln.h new file mode 100644 index 00000000000..6a0f95b9145 --- /dev/null +++ b/utils/openttd/freetype/ftoutln.h @@ -0,0 +1,536 @@ +/***************************************************************************/ +/* */ +/* ftoutln.h */ +/* */ +/* Support for the FT_Outline type used to store glyph shapes of */ +/* most scalable font formats (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOUTLN_H__ +#define __FTOUTLN_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* outline_processing */ + /* */ + /* <Title> */ + /* Outline Processing */ + /* */ + /* <Abstract> */ + /* Functions to create, transform, and render vectorial glyph images. */ + /* */ + /* <Description> */ + /* This section contains routines used to create and destroy scalable */ + /* glyph images known as `outlines'. These can also be measured, */ + /* transformed, and converted into bitmaps and pixmaps. */ + /* */ + /* <Order> */ + /* FT_Outline */ + /* FT_OUTLINE_FLAGS */ + /* FT_Outline_New */ + /* FT_Outline_Done */ + /* FT_Outline_Copy */ + /* FT_Outline_Translate */ + /* FT_Outline_Transform */ + /* FT_Outline_Embolden */ + /* FT_Outline_Reverse */ + /* FT_Outline_Check */ + /* */ + /* FT_Outline_Get_CBox */ + /* FT_Outline_Get_BBox */ + /* */ + /* FT_Outline_Get_Bitmap */ + /* FT_Outline_Render */ + /* */ + /* FT_Outline_Decompose */ + /* FT_Outline_Funcs */ + /* FT_Outline_MoveTo_Func */ + /* FT_Outline_LineTo_Func */ + /* FT_Outline_ConicTo_Func */ + /* FT_Outline_CubicTo_Func */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Decompose */ + /* */ + /* <Description> */ + /* Walk over an outline's structure to decompose it into individual */ + /* segments and Bézier arcs. This function is also able to emit */ + /* `move to' and `close to' operations to indicate the start and end */ + /* of new contours in the outline. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source target. */ + /* */ + /* func_interface :: A table of `emitters', i.e,. function pointers */ + /* called during decomposition to indicate path */ + /* operations. */ + /* */ + /* <InOut> */ + /* user :: A typeless pointer which is passed to each */ + /* emitter during the decomposition. It can be */ + /* used to store the state during the */ + /* decomposition. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Decompose( FT_Outline* outline, + const FT_Outline_Funcs* func_interface, + void* user ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_New */ + /* */ + /* <Description> */ + /* Create a new outline of a given size. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object from where the */ + /* outline is allocated. Note however that the new */ + /* outline will *not* necessarily be *freed*, when */ + /* destroying the library, by @FT_Done_FreeType. */ + /* */ + /* numPoints :: The maximal number of points within the outline. */ + /* */ + /* numContours :: The maximal number of contours within the outline. */ + /* */ + /* <Output> */ + /* anoutline :: A handle to the new outline. NULL in case of */ + /* error. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The reason why this function takes a `library' parameter is simply */ + /* to use the library's memory allocator. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_New( FT_Library library, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_New_Internal( FT_Memory memory, + FT_UInt numPoints, + FT_Int numContours, + FT_Outline *anoutline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Done */ + /* */ + /* <Description> */ + /* Destroy an outline created with @FT_Outline_New. */ + /* */ + /* <Input> */ + /* library :: A handle of the library object used to allocate the */ + /* outline. */ + /* */ + /* outline :: A pointer to the outline object to be discarded. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If the outline's `owner' field is not set, only the outline */ + /* descriptor will be released. */ + /* */ + /* The reason why this function takes an `library' parameter is */ + /* simply to use ft_mem_free(). */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Done( FT_Library library, + FT_Outline* outline ); + + + FT_EXPORT( FT_Error ) + FT_Outline_Done_Internal( FT_Memory memory, + FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Check */ + /* */ + /* <Description> */ + /* Check the contents of an outline descriptor. */ + /* */ + /* <Input> */ + /* outline :: A handle to a source outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Check( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Return an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* which contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Translate */ + /* */ + /* <Description> */ + /* Apply a simple translation to the points of an outline. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* xOffset :: The horizontal offset. */ + /* */ + /* yOffset :: The vertical offset. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Translate( const FT_Outline* outline, + FT_Pos xOffset, + FT_Pos yOffset ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Copy */ + /* */ + /* <Description> */ + /* Copy an outline into another one. Both objects must have the */ + /* same sizes (number of points & number of contours) when this */ + /* function is called. */ + /* */ + /* <Input> */ + /* source :: A handle to the source outline. */ + /* */ + /* <Output> */ + /* target :: A handle to the target outline. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Copy( const FT_Outline* source, + FT_Outline *target ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Transform */ + /* */ + /* <Description> */ + /* Apply a simple 2x2 matrix to all of an outline's points. Useful */ + /* for applying rotations, slanting, flipping, etc. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Input> */ + /* matrix :: A pointer to the transformation matrix. */ + /* */ + /* <Note> */ + /* You can use @FT_Outline_Translate if you need to translate the */ + /* outline's points. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Transform( const FT_Outline* outline, + const FT_Matrix* matrix ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Embolden */ + /* */ + /* <Description> */ + /* Embolden an outline. The new outline will be at most 4~times */ + /* `strength' pixels wider and higher. You may think of the left and */ + /* bottom borders as unchanged. */ + /* */ + /* Negative `strength' values to reduce the outline thickness are */ + /* possible also. */ + /* */ + /* <InOut> */ + /* outline :: A handle to the target outline. */ + /* */ + /* <Input> */ + /* strength :: How strong the glyph is emboldened. Expressed in */ + /* 26.6 pixel format. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The used algorithm to increase or decrease the thickness of the */ + /* glyph doesn't change the number of points; this means that certain */ + /* situations like acute angles or intersections are sometimes */ + /* handled incorrectly. */ + /* */ + /* Example call: */ + /* */ + /* { */ + /* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); */ + /* if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE ) */ + /* FT_Outline_Embolden( &face->slot->outline, strength ); */ + /* } */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Embolden( FT_Outline* outline, + FT_Pos strength ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Reverse */ + /* */ + /* <Description> */ + /* Reverse the drawing direction of an outline. This is used to */ + /* ensure consistent fill conventions for mirrored glyphs. */ + /* */ + /* <InOut> */ + /* outline :: A pointer to the target outline descriptor. */ + /* */ + /* <Note> */ + /* This functions toggles the bit flag @FT_OUTLINE_REVERSE_FILL in */ + /* the outline's `flags' field. */ + /* */ + /* It shouldn't be used by a normal client application, unless it */ + /* knows what it is doing. */ + /* */ + FT_EXPORT( void ) + FT_Outline_Reverse( FT_Outline* outline ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_Bitmap */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap. The outline's image is simply */ + /* OR-ed to the target bitmap. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* abitmap :: A pointer to the target bitmap descriptor. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* This function does NOT CREATE the bitmap, it only renders an */ + /* outline image within the one you pass to it! Consequently, the */ + /* various fields in `abitmap' should be set accordingly. */ + /* */ + /* It will use the raster corresponding to the default glyph format. */ + /* */ + /* The value of the `num_grays' field in `abitmap' is ignored. If */ + /* you select the gray-level rasterizer, and you want less than 256 */ + /* gray levels, you have to use @FT_Outline_Render directly. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Get_Bitmap( FT_Library library, + FT_Outline* outline, + const FT_Bitmap *abitmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Render */ + /* */ + /* <Description> */ + /* Render an outline within a bitmap using the current scan-convert. */ + /* This functions uses an @FT_Raster_Params structure as an argument, */ + /* allowing advanced features like direct composition, translucency, */ + /* etc. */ + /* */ + /* <Input> */ + /* library :: A handle to a FreeType library object. */ + /* */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <InOut> */ + /* params :: A pointer to an @FT_Raster_Params structure used to */ + /* describe the rendering operation. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You should know what you are doing and how @FT_Raster_Params works */ + /* to use this function. */ + /* */ + /* The field `params.source' will be set to `outline' before the scan */ + /* converter is called, which means that the value you give to it is */ + /* actually ignored. */ + /* */ + /* The gray-level rasterizer always uses 256 gray levels. If you */ + /* want less gray levels, you have to provide your own span callback. */ + /* See the @FT_RASTER_FLAG_DIRECT value of the `flags' field in the */ + /* @FT_Raster_Params structure for more details. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Outline_Render( FT_Library library, + FT_Outline* outline, + FT_Raster_Params* params ); + + + /************************************************************************** + * + * @enum: + * FT_Orientation + * + * @description: + * A list of values used to describe an outline's contour orientation. + * + * The TrueType and PostScript specifications use different conventions + * to determine whether outline contours should be filled or unfilled. + * + * @values: + * FT_ORIENTATION_TRUETYPE :: + * According to the TrueType specification, clockwise contours must + * be filled, and counter-clockwise ones must be unfilled. + * + * FT_ORIENTATION_POSTSCRIPT :: + * According to the PostScript specification, counter-clockwise contours + * must be filled, and clockwise ones must be unfilled. + * + * FT_ORIENTATION_FILL_RIGHT :: + * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to + * remember that in TrueType, everything that is to the right of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_FILL_LEFT :: + * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to + * remember that in PostScript, everything that is to the left of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_NONE :: + * The orientation cannot be determined. That is, different parts of + * the glyph have different orientation. + * + */ + typedef enum FT_Orientation_ + { + FT_ORIENTATION_TRUETYPE = 0, + FT_ORIENTATION_POSTSCRIPT = 1, + FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE, + FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT, + FT_ORIENTATION_NONE + + } FT_Orientation; + + + /************************************************************************** + * + * @function: + * FT_Outline_Get_Orientation + * + * @description: + * This function analyzes a glyph outline and tries to compute its + * fill orientation (see @FT_Orientation). This is done by computing + * the direction of each global horizontal and/or vertical extrema + * within the outline. + * + * Note that this will return @FT_ORIENTATION_TRUETYPE for empty + * outlines. + * + * @input: + * outline :: + * A handle to the source outline. + * + * @return: + * The orientation. + * + */ + FT_EXPORT( FT_Orientation ) + FT_Outline_Get_Orientation( FT_Outline* outline ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTOUTLN_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/utils/openttd/freetype/ftpfr.h b/utils/openttd/freetype/ftpfr.h new file mode 100644 index 00000000000..8e79a794f1e --- /dev/null +++ b/utils/openttd/freetype/ftpfr.h @@ -0,0 +1,172 @@ +/***************************************************************************/ +/* */ +/* ftpfr.h */ +/* */ +/* FreeType API for accessing PFR-specific data (specification only). */ +/* */ +/* Copyright 2002, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTPFR_H__ +#define __FTPFR_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* pfr_fonts */ + /* */ + /* <Title> */ + /* PFR Fonts */ + /* */ + /* <Abstract> */ + /* PFR/TrueDoc specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of PFR-specific functions. */ + /* */ + /*************************************************************************/ + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Metrics + * + * @description: + * Return the outline and metrics resolutions of a given PFR face. + * + * @input: + * face :: Handle to the input face. It can be a non-PFR face. + * + * @output: + * aoutline_resolution :: + * Outline resolution. This is equivalent to `face->units_per_EM'. + * Optional (parameter can be NULL). + * + * ametrics_resolution :: + * Metrics resolution. This is equivalent to `outline_resolution' + * for non-PFR fonts. Optional (parameter can be NULL). + * + * ametrics_x_scale :: + * A 16.16 fixed-point number used to scale distance expressed + * in metrics units to device sub-pixels. This is equivalent to + * `face->size->x_scale', but for metrics only. Optional (parameter + * can be NULL) + * + * ametrics_y_scale :: + * Same as `ametrics_x_scale' but for the vertical direction. + * optional (parameter can be NULL) + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If the input face is not a PFR, this function will return an error. + * However, in all cases, it will return valid values. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Metrics( FT_Face face, + FT_UInt *aoutline_resolution, + FT_UInt *ametrics_resolution, + FT_Fixed *ametrics_x_scale, + FT_Fixed *ametrics_y_scale ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Kerning + * + * @description: + * Return the kerning pair corresponding to two glyphs in a PFR face. + * The distance is expressed in metrics units, unlike the result of + * @FT_Get_Kerning. + * + * @input: + * face :: A handle to the input face. + * + * left :: Index of the left glyph. + * + * right :: Index of the right glyph. + * + * @output: + * avector :: A kerning vector. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function always return distances in original PFR metrics + * units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED + * mode, which always returns distances converted to outline units. + * + * You can use the value of the `x_scale' and `y_scale' parameters + * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Kerning( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + + /********************************************************************** + * + * @function: + * FT_Get_PFR_Advance + * + * @description: + * Return a given glyph advance, expressed in original metrics units, + * from a PFR font. + * + * @input: + * face :: A handle to the input face. + * + * gindex :: The glyph index. + * + * @output: + * aadvance :: The glyph advance in metrics units. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics + * to convert the advance to device sub-pixels (i.e., 1/64th of pixels). + */ + FT_EXPORT( FT_Error ) + FT_Get_PFR_Advance( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTPFR_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftrender.h b/utils/openttd/freetype/ftrender.h new file mode 100644 index 00000000000..41c31eac48c --- /dev/null +++ b/utils/openttd/freetype/ftrender.h @@ -0,0 +1,234 @@ +/***************************************************************************/ +/* */ +/* ftrender.h */ +/* */ +/* FreeType renderer modules public interface (specification). */ +/* */ +/* Copyright 1996-2001, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTRENDER_H__ +#define __FTRENDER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* module_management */ + /* */ + /*************************************************************************/ + + + /* create a new glyph object */ + typedef FT_Error + (*FT_Glyph_InitFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + + /* destroys a given glyph object */ + typedef void + (*FT_Glyph_DoneFunc)( FT_Glyph glyph ); + + typedef void + (*FT_Glyph_TransformFunc)( FT_Glyph glyph, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + typedef void + (*FT_Glyph_GetBBoxFunc)( FT_Glyph glyph, + FT_BBox* abbox ); + + typedef FT_Error + (*FT_Glyph_CopyFunc)( FT_Glyph source, + FT_Glyph target ); + + typedef FT_Error + (*FT_Glyph_PrepareFunc)( FT_Glyph glyph, + FT_GlyphSlot slot ); + +/* deprecated */ +#define FT_Glyph_Init_Func FT_Glyph_InitFunc +#define FT_Glyph_Done_Func FT_Glyph_DoneFunc +#define FT_Glyph_Transform_Func FT_Glyph_TransformFunc +#define FT_Glyph_BBox_Func FT_Glyph_GetBBoxFunc +#define FT_Glyph_Copy_Func FT_Glyph_CopyFunc +#define FT_Glyph_Prepare_Func FT_Glyph_PrepareFunc + + + struct FT_Glyph_Class_ + { + FT_Long glyph_size; + FT_Glyph_Format glyph_format; + FT_Glyph_InitFunc glyph_init; + FT_Glyph_DoneFunc glyph_done; + FT_Glyph_CopyFunc glyph_copy; + FT_Glyph_TransformFunc glyph_transform; + FT_Glyph_GetBBoxFunc glyph_bbox; + FT_Glyph_PrepareFunc glyph_prepare; + }; + + + typedef FT_Error + (*FT_Renderer_RenderFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_UInt mode, + const FT_Vector* origin ); + + typedef FT_Error + (*FT_Renderer_TransformFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + const FT_Matrix* matrix, + const FT_Vector* delta ); + + + typedef void + (*FT_Renderer_GetCBoxFunc)( FT_Renderer renderer, + FT_GlyphSlot slot, + FT_BBox* cbox ); + + + typedef FT_Error + (*FT_Renderer_SetModeFunc)( FT_Renderer renderer, + FT_ULong mode_tag, + FT_Pointer mode_ptr ); + +/* deprecated identifiers */ +#define FTRenderer_render FT_Renderer_RenderFunc +#define FTRenderer_transform FT_Renderer_TransformFunc +#define FTRenderer_getCBox FT_Renderer_GetCBoxFunc +#define FTRenderer_setMode FT_Renderer_SetModeFunc + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Renderer_Class */ + /* */ + /* <Description> */ + /* The renderer module class descriptor. */ + /* */ + /* <Fields> */ + /* root :: The root @FT_Module_Class fields. */ + /* */ + /* glyph_format :: The glyph image format this renderer handles. */ + /* */ + /* render_glyph :: A method used to render the image that is in a */ + /* given glyph slot into a bitmap. */ + /* */ + /* transform_glyph :: A method used to transform the image that is in */ + /* a given glyph slot. */ + /* */ + /* get_glyph_cbox :: A method used to access the glyph's cbox. */ + /* */ + /* set_mode :: A method used to pass additional parameters. */ + /* */ + /* raster_class :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to its raster's class. */ + /* */ + /* raster :: For @FT_GLYPH_FORMAT_OUTLINE renderers only. */ + /* This is a pointer to the corresponding raster */ + /* object, if any. */ + /* */ + typedef struct FT_Renderer_Class_ + { + FT_Module_Class root; + + FT_Glyph_Format glyph_format; + + FT_Renderer_RenderFunc render_glyph; + FT_Renderer_TransformFunc transform_glyph; + FT_Renderer_GetCBoxFunc get_glyph_cbox; + FT_Renderer_SetModeFunc set_mode; + + FT_Raster_Funcs* raster_class; + + } FT_Renderer_Class; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Renderer */ + /* */ + /* <Description> */ + /* Retrieve the current renderer for a given glyph format. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* format :: The glyph format. */ + /* */ + /* <Return> */ + /* A renderer handle. 0~if none found. */ + /* */ + /* <Note> */ + /* An error will be returned if a module already exists by that name, */ + /* or if the module requires a version of FreeType that is too great. */ + /* */ + /* To add a new renderer, simply use @FT_Add_Module. To retrieve a */ + /* renderer by its name, use @FT_Get_Module. */ + /* */ + FT_EXPORT( FT_Renderer ) + FT_Get_Renderer( FT_Library library, + FT_Glyph_Format format ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Renderer */ + /* */ + /* <Description> */ + /* Set the current renderer to use, and set additional mode. */ + /* */ + /* <InOut> */ + /* library :: A handle to the library object. */ + /* */ + /* <Input> */ + /* renderer :: A handle to the renderer object. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* parameters :: Additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* In case of success, the renderer will be used to convert glyph */ + /* images in the renderer's known format into bitmaps. */ + /* */ + /* This doesn't change the current renderer for other formats. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Renderer( FT_Library library, + FT_Renderer renderer, + FT_UInt num_params, + FT_Parameter* parameters ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FTRENDER_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftsizes.h b/utils/openttd/freetype/ftsizes.h new file mode 100644 index 00000000000..05636c7ae35 --- /dev/null +++ b/utils/openttd/freetype/ftsizes.h @@ -0,0 +1,159 @@ +/***************************************************************************/ +/* */ +/* ftsizes.h */ +/* */ +/* FreeType size objects management (specification). */ +/* */ +/* Copyright 1996-2001, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Typical application would normally not need to use these functions. */ + /* However, they have been placed in a public API for the rare cases */ + /* where they are needed. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSIZES_H__ +#define __FTSIZES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sizes_management */ + /* */ + /* <Title> */ + /* Size Management */ + /* */ + /* <Abstract> */ + /* Managing multiple sizes per face. */ + /* */ + /* <Description> */ + /* When creating a new face object (e.g., with @FT_New_Face), an */ + /* @FT_Size object is automatically created and used to store all */ + /* pixel-size dependent information, available in the `face->size' */ + /* field. */ + /* */ + /* It is however possible to create more sizes for a given face, */ + /* mostly in order to manage several character pixel sizes of the */ + /* same font family and style. See @FT_New_Size and @FT_Done_Size. */ + /* */ + /* Note that @FT_Set_Pixel_Sizes and @FT_Set_Char_Size only */ + /* modify the contents of the current `active' size; you thus need */ + /* to use @FT_Activate_Size to change it. */ + /* */ + /* 99% of applications won't need the functions provided here, */ + /* especially if they use the caching sub-system, so be cautious */ + /* when using these. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Size */ + /* */ + /* <Description> */ + /* Create a new size object from a given face object. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* asize :: A handle to a new size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* You need to call @FT_Activate_Size in order to select the new size */ + /* for upcoming calls to @FT_Set_Pixel_Sizes, @FT_Set_Char_Size, */ + /* @FT_Load_Glyph, @FT_Load_Char, etc. */ + /* */ + FT_EXPORT( FT_Error ) + FT_New_Size( FT_Face face, + FT_Size* size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Size */ + /* */ + /* <Description> */ + /* Discard a given size object. Note that @FT_Done_Face */ + /* automatically discards all size objects allocated with */ + /* @FT_New_Size. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_Size( FT_Size size ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Activate_Size */ + /* */ + /* <Description> */ + /* Even though it is possible to create several size objects for a */ + /* given face (see @FT_New_Size for details), functions like */ + /* @FT_Load_Glyph or @FT_Load_Char only use the last-created one to */ + /* determine the `current character pixel size'. */ + /* */ + /* This function can be used to `activate' a previously created size */ + /* object. */ + /* */ + /* <Input> */ + /* size :: A handle to a target size object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* If `face' is the size's parent face object, this function changes */ + /* the value of `face->size' to the input size handle. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Activate_Size( FT_Size size ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTSIZES_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftsnames.h b/utils/openttd/freetype/ftsnames.h new file mode 100644 index 00000000000..477e1e3ce81 --- /dev/null +++ b/utils/openttd/freetype/ftsnames.h @@ -0,0 +1,170 @@ +/***************************************************************************/ +/* */ +/* ftsnames.h */ +/* */ +/* Simple interface to access SFNT name tables (which are used */ +/* to hold font names, copyright info, notices, etc.) (specification). */ +/* */ +/* This is _not_ used to retrieve glyph names! */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_SFNT_NAMES_H__ +#define __FT_SFNT_NAMES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* sfnt_names */ + /* */ + /* <Title> */ + /* SFNT Names */ + /* */ + /* <Abstract> */ + /* Access the names embedded in TrueType and OpenType files. */ + /* */ + /* <Description> */ + /* The TrueType and OpenType specifications allow the inclusion of */ + /* a special `names table' in font files. This table contains */ + /* textual (and internationalized) information regarding the font, */ + /* like family name, copyright, version, etc. */ + /* */ + /* The definitions below are used to access them if available. */ + /* */ + /* Note that this has nothing to do with glyph names! */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SfntName */ + /* */ + /* <Description> */ + /* A structure used to model an SFNT `name' table entry. */ + /* */ + /* <Fields> */ + /* platform_id :: The platform ID for `string'. */ + /* */ + /* encoding_id :: The encoding ID for `string'. */ + /* */ + /* language_id :: The language ID for `string'. */ + /* */ + /* name_id :: An identifier for `string'. */ + /* */ + /* string :: The `name' string. Note that its format differs */ + /* depending on the (platform,encoding) pair. It can */ + /* be a Pascal String, a UTF-16 one, etc. */ + /* */ + /* Generally speaking, the string is not */ + /* zero-terminated. Please refer to the TrueType */ + /* specification for details. */ + /* */ + /* string_len :: The length of `string' in bytes. */ + /* */ + /* <Note> */ + /* Possible values for `platform_id', `encoding_id', `language_id', */ + /* and `name_id' are given in the file `ttnameid.h'. For details */ + /* please refer to the TrueType or OpenType specification. */ + /* */ + /* See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ + /* @TT_ISO_ID_XXX, and @TT_MS_ID_XXX. */ + /* */ + typedef struct FT_SfntName_ + { + FT_UShort platform_id; + FT_UShort encoding_id; + FT_UShort language_id; + FT_UShort name_id; + + FT_Byte* string; /* this string is *not* null-terminated! */ + FT_UInt string_len; /* in bytes */ + + } FT_SfntName; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name_Count */ + /* */ + /* <Description> */ + /* Retrieve the number of name strings in the SFNT `name' table. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* <Return> */ + /* The number of strings in the `name' table. */ + /* */ + FT_EXPORT( FT_UInt ) + FT_Get_Sfnt_Name_Count( FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Name */ + /* */ + /* <Description> */ + /* Retrieve a string of the SFNT `name' table for a given index. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* idx :: The index of the `name' string. */ + /* */ + /* <Output> */ + /* aname :: The indexed @FT_SfntName structure. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `string' array returned in the `aname' structure is not */ + /* null-terminated. */ + /* */ + /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ + /* `name' table entries, then do a loop until you get the right */ + /* platform, encoding, and name ID. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Sfnt_Name( FT_Face face, + FT_UInt idx, + FT_SfntName *aname ); + + + /* */ + + +FT_END_HEADER + +#endif /* __FT_SFNT_NAMES_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftstroke.h b/utils/openttd/freetype/ftstroke.h new file mode 100644 index 00000000000..38d20553ea0 --- /dev/null +++ b/utils/openttd/freetype/ftstroke.h @@ -0,0 +1,716 @@ +/***************************************************************************/ +/* */ +/* ftstroke.h */ +/* */ +/* FreeType path stroker (specification). */ +/* */ +/* Copyright 2002, 2003, 2004, 2005, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FT_STROKE_H__ +#define __FT_STROKE_H__ + +#include <ft2build.h> +#include FT_OUTLINE_H +#include FT_GLYPH_H + + +FT_BEGIN_HEADER + + + /************************************************************************ + * + * @section: + * glyph_stroker + * + * @title: + * Glyph Stroker + * + * @abstract: + * Generating bordered and stroked glyphs. + * + * @description: + * This component generates stroked outlines of a given vectorial + * glyph. It also allows you to retrieve the `outside' and/or the + * `inside' borders of the stroke. + * + * This can be useful to generate `bordered' glyph, i.e., glyphs + * displayed with a coloured (and anti-aliased) border around their + * shape. + */ + + + /************************************************************** + * + * @type: + * FT_Stroker + * + * @description: + * Opaque handler to a path stroker object. + */ + typedef struct FT_StrokerRec_* FT_Stroker; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineJoin + * + * @description: + * These values determine how two joining lines are rendered + * in a stroker. + * + * @values: + * FT_STROKER_LINEJOIN_ROUND :: + * Used to render rounded line joins. Circular arcs are used + * to join two lines smoothly. + * + * FT_STROKER_LINEJOIN_BEVEL :: + * Used to render beveled line joins; i.e., the two joining lines + * are extended until they intersect. + * + * FT_STROKER_LINEJOIN_MITER :: + * Same as beveled rendering, except that an additional line + * break is added if the angle between the two joining lines + * is too closed (this is useful to avoid unpleasant spikes + * in beveled rendering). + */ + typedef enum FT_Stroker_LineJoin_ + { + FT_STROKER_LINEJOIN_ROUND = 0, + FT_STROKER_LINEJOIN_BEVEL, + FT_STROKER_LINEJOIN_MITER + + } FT_Stroker_LineJoin; + + + /************************************************************** + * + * @enum: + * FT_Stroker_LineCap + * + * @description: + * These values determine how the end of opened sub-paths are + * rendered in a stroke. + * + * @values: + * FT_STROKER_LINECAP_BUTT :: + * The end of lines is rendered as a full stop on the last + * point itself. + * + * FT_STROKER_LINECAP_ROUND :: + * The end of lines is rendered as a half-circle around the + * last point. + * + * FT_STROKER_LINECAP_SQUARE :: + * The end of lines is rendered as a square around the + * last point. + */ + typedef enum FT_Stroker_LineCap_ + { + FT_STROKER_LINECAP_BUTT = 0, + FT_STROKER_LINECAP_ROUND, + FT_STROKER_LINECAP_SQUARE + + } FT_Stroker_LineCap; + + + /************************************************************** + * + * @enum: + * FT_StrokerBorder + * + * @description: + * These values are used to select a given stroke border + * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. + * + * @values: + * FT_STROKER_BORDER_LEFT :: + * Select the left border, relative to the drawing direction. + * + * FT_STROKER_BORDER_RIGHT :: + * Select the right border, relative to the drawing direction. + * + * @note: + * Applications are generally interested in the `inside' and `outside' + * borders. However, there is no direct mapping between these and the + * `left' and `right' ones, since this really depends on the glyph's + * drawing orientation, which varies between font formats. + * + * You can however use @FT_Outline_GetInsideBorder and + * @FT_Outline_GetOutsideBorder to get these. + */ + typedef enum FT_StrokerBorder_ + { + FT_STROKER_BORDER_LEFT = 0, + FT_STROKER_BORDER_RIGHT + + } FT_StrokerBorder; + + + /************************************************************** + * + * @function: + * FT_Outline_GetInsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `inside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetInsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Outline_GetOutsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `outside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + */ + FT_EXPORT( FT_StrokerBorder ) + FT_Outline_GetOutsideBorder( FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_New + * + * @description: + * Create a new stroker object. + * + * @input: + * library :: + * FreeType library handle. + * + * @output: + * astroker :: + * A new stroker object handle. NULL in case of error. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_New( FT_Library library, + FT_Stroker *astroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Set + * + * @description: + * Reset a stroker object's attributes. + * + * @input: + * stroker :: + * The target stroker handle. + * + * radius :: + * The border radius. + * + * line_cap :: + * The line cap style. + * + * line_join :: + * The line join style. + * + * miter_limit :: + * The miter limit for the FT_STROKER_LINEJOIN_MITER style, + * expressed as 16.16 fixed point value. + * + * @note: + * The radius is expressed in the same units that the outline + * coordinates. + */ + FT_EXPORT( void ) + FT_Stroker_Set( FT_Stroker stroker, + FT_Fixed radius, + FT_Stroker_LineCap line_cap, + FT_Stroker_LineJoin line_join, + FT_Fixed miter_limit ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Rewind + * + * @description: + * Reset a stroker object without changing its attributes. + * You should call this function before beginning a new + * series of calls to @FT_Stroker_BeginSubPath or + * @FT_Stroker_EndSubPath. + * + * @input: + * stroker :: + * The target stroker handle. + */ + FT_EXPORT( void ) + FT_Stroker_Rewind( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ParseOutline + * + * @description: + * A convenience function used to parse a whole outline with + * the stroker. The resulting outline(s) can be retrieved + * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The source outline. + * + * opened :: + * A boolean. If~1, the outline is treated as an open path instead + * of a closed one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If `opened' is~0 (the default), the outline is treated as a closed + * path, and the stroker will generate two distinct `border' outlines. + * + * If `opened' is~1, the outline is processed as an open path, and the + * stroker will generate a single `stroke' outline. + * + * This function calls @FT_Stroker_Rewind automatically. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ParseOutline( FT_Stroker stroker, + FT_Outline* outline, + FT_Bool opened ); + + + /************************************************************** + * + * @function: + * FT_Stroker_BeginSubPath + * + * @description: + * Start a new sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the start vector. + * + * open :: + * A boolean. If~1, the sub-path is treated as an open one. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function is useful when you need to stroke a path that is + * not stored as an @FT_Outline object. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_BeginSubPath( FT_Stroker stroker, + FT_Vector* to, + FT_Bool open ); + + + /************************************************************** + * + * @function: + * FT_Stroker_EndSubPath + * + * @description: + * Close the current sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function after @FT_Stroker_BeginSubPath. + * If the subpath was not `opened', this function will `draw' a + * single line segment to the start position when needed. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_EndSubPath( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Stroker_LineTo + * + * @description: + * `Draw' a single line segment in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_LineTo( FT_Stroker stroker, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ConicTo + * + * @description: + * `Draw' a single quadratic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control :: + * A pointer to a Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_ConicTo( FT_Stroker stroker, + FT_Vector* control, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_CubicTo + * + * @description: + * `Draw' a single cubic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control1 :: + * A pointer to the first Bézier control point. + * + * control2 :: + * A pointer to second Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_CubicTo( FT_Stroker stroker, + FT_Vector* control1, + FT_Vector* control2, + FT_Vector* to ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetBorderCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It will return the number of points and + * contours necessary to export one of the `border' or `stroke' + * outlines generated by the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right'. + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_GetCounts instead if you want to + * retrieve the counts associated to both borders. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetBorderCounts( FT_Stroker stroker, + FT_StrokerBorder border, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_ExportBorder + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the corresponding border to your own @FT_Outline + * structure. + * + * Note that this function will append the border points and + * contours to your outline, but will not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * outline :: + * The target outline handle. + * + * @note: + * Always call this function after @FT_Stroker_GetBorderCounts to + * get sure that there is enough room in your @FT_Outline object to + * receive all new data. + * + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right' + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_Export instead if you want to + * retrieve all borders at once. + */ + FT_EXPORT( void ) + FT_Stroker_ExportBorder( FT_Stroker stroker, + FT_StrokerBorder border, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_GetCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export all points/borders from the stroked + * outline/path. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0~means success. + */ + FT_EXPORT( FT_Error ) + FT_Stroker_GetCounts( FT_Stroker stroker, + FT_UInt *anum_points, + FT_UInt *anum_contours ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Export + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the all borders to your own @FT_Outline structure. + * + * Note that this function will append the border points and + * contours to your outline, but will not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The target outline handle. + */ + FT_EXPORT( void ) + FT_Stroker_Export( FT_Stroker stroker, + FT_Outline* outline ); + + + /************************************************************** + * + * @function: + * FT_Stroker_Done + * + * @description: + * Destroy a stroker object. + * + * @input: + * stroker :: + * A stroker handle. Can be NULL. + */ + FT_EXPORT( void ) + FT_Stroker_Done( FT_Stroker stroker ); + + + /************************************************************** + * + * @function: + * FT_Glyph_Stroke + * + * @description: + * Stroke a given outline glyph object with a given stroker. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_Stroke( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool destroy ); + + + /************************************************************** + * + * @function: + * FT_Glyph_StrokeBorder + * + * @description: + * Stroke a given outline glyph object with a given stroker, but + * only return either its inside or outside border. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * inside :: + * A Boolean. If~1, return the inside border, otherwise + * the outside border. + * + * destroy :: + * A Boolean. If~1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The source glyph is untouched in case of error. + */ + FT_EXPORT( FT_Error ) + FT_Glyph_StrokeBorder( FT_Glyph *pglyph, + FT_Stroker stroker, + FT_Bool inside, + FT_Bool destroy ); + + /* */ + +FT_END_HEADER + +#endif /* __FT_STROKE_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/utils/openttd/freetype/ftsynth.h b/utils/openttd/freetype/ftsynth.h new file mode 100644 index 00000000000..36984bf1a7b --- /dev/null +++ b/utils/openttd/freetype/ftsynth.h @@ -0,0 +1,73 @@ +/***************************************************************************/ +/* */ +/* ftsynth.h */ +/* */ +/* FreeType synthesizing code for emboldening and slanting */ +/* (specification). */ +/* */ +/* Copyright 2000-2001, 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********* *********/ + /********* WARNING, THIS IS ALPHA CODE, THIS API *********/ + /********* IS DUE TO CHANGE UNTIL STRICTLY NOTIFIED BY THE *********/ + /********* FREETYPE DEVELOPMENT TEAM *********/ + /********* *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifndef __FTSYNTH_H__ +#define __FTSYNTH_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /* Make sure slot owns slot->bitmap. */ + FT_EXPORT( FT_Error ) + FT_GlyphSlot_Own_Bitmap( FT_GlyphSlot slot ); + + /* Do not use this function directly! Copy the code to */ + /* your application and modify it to suit your need. */ + FT_EXPORT( void ) + FT_GlyphSlot_Embolden( FT_GlyphSlot slot ); + + + FT_EXPORT( void ) + FT_GlyphSlot_Oblique( FT_GlyphSlot slot ); + + /* */ + +FT_END_HEADER + +#endif /* __FTSYNTH_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftsystem.h b/utils/openttd/freetype/ftsystem.h new file mode 100644 index 00000000000..a95b2c76b61 --- /dev/null +++ b/utils/openttd/freetype/ftsystem.h @@ -0,0 +1,346 @@ +/***************************************************************************/ +/* */ +/* ftsystem.h */ +/* */ +/* FreeType low-level system interface definition (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2005 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTSYSTEM_H__ +#define __FTSYSTEM_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* system_interface */ + /* */ + /* <Title> */ + /* System Interface */ + /* */ + /* <Abstract> */ + /* How FreeType manages memory and i/o. */ + /* */ + /* <Description> */ + /* This section contains various definitions related to memory */ + /* management and i/o access. You need to understand this */ + /* information if you want to use a custom memory manager or you own */ + /* i/o streams. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* M E M O R Y M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Memory + * + * @description: + * A handle to a given memory manager object, defined with an + * @FT_MemoryRec structure. + * + */ + typedef struct FT_MemoryRec_* FT_Memory; + + + /************************************************************************* + * + * @functype: + * FT_Alloc_Func + * + * @description: + * A function used to allocate `size' bytes from `memory'. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * size :: + * The size in bytes to allocate. + * + * @return: + * Address of new memory block. 0~in case of failure. + * + */ + typedef void* + (*FT_Alloc_Func)( FT_Memory memory, + long size ); + + + /************************************************************************* + * + * @functype: + * FT_Free_Func + * + * @description: + * A function used to release a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * block :: + * The address of the target memory block. + * + */ + typedef void + (*FT_Free_Func)( FT_Memory memory, + void* block ); + + + /************************************************************************* + * + * @functype: + * FT_Realloc_Func + * + * @description: + * A function used to re-allocate a given block of memory. + * + * @input: + * memory :: + * A handle to the source memory manager. + * + * cur_size :: + * The block's current size in bytes. + * + * new_size :: + * The block's requested new size. + * + * block :: + * The block's current address. + * + * @return: + * New block address. 0~in case of memory shortage. + * + * @note: + * In case of error, the old block must still be available. + * + */ + typedef void* + (*FT_Realloc_Func)( FT_Memory memory, + long cur_size, + long new_size, + void* block ); + + + /************************************************************************* + * + * @struct: + * FT_MemoryRec + * + * @description: + * A structure used to describe a given memory manager to FreeType~2. + * + * @fields: + * user :: + * A generic typeless pointer for user data. + * + * alloc :: + * A pointer type to an allocation function. + * + * free :: + * A pointer type to an memory freeing function. + * + * realloc :: + * A pointer type to a reallocation function. + * + */ + struct FT_MemoryRec_ + { + void* user; + FT_Alloc_Func alloc; + FT_Free_Func free; + FT_Realloc_Func realloc; + }; + + + /*************************************************************************/ + /* */ + /* I / O M A N A G E M E N T */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Stream + * + * @description: + * A handle to an input stream. + * + */ + typedef struct FT_StreamRec_* FT_Stream; + + + /************************************************************************* + * + * @struct: + * FT_StreamDesc + * + * @description: + * A union type used to store either a long or a pointer. This is used + * to store a file descriptor or a `FILE*' in an input stream. + * + */ + typedef union FT_StreamDesc_ + { + long value; + void* pointer; + + } FT_StreamDesc; + + + /************************************************************************* + * + * @functype: + * FT_Stream_IoFunc + * + * @description: + * A function used to seek and read data from a given input stream. + * + * @input: + * stream :: + * A handle to the source stream. + * + * offset :: + * The offset of read in stream (always from start). + * + * buffer :: + * The address of the read buffer. + * + * count :: + * The number of bytes to read from the stream. + * + * @return: + * The number of bytes effectively read by the stream. + * + * @note: + * This function might be called to perform a seek or skip operation + * with a `count' of~0. + * + */ + typedef unsigned long + (*FT_Stream_IoFunc)( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ); + + + /************************************************************************* + * + * @functype: + * FT_Stream_CloseFunc + * + * @description: + * A function used to close a given input stream. + * + * @input: + * stream :: + * A handle to the target stream. + * + */ + typedef void + (*FT_Stream_CloseFunc)( FT_Stream stream ); + + + /************************************************************************* + * + * @struct: + * FT_StreamRec + * + * @description: + * A structure used to describe an input stream. + * + * @input: + * base :: + * For memory-based streams, this is the address of the first stream + * byte in memory. This field should always be set to NULL for + * disk-based streams. + * + * size :: + * The stream size in bytes. + * + * pos :: + * The current position within the stream. + * + * descriptor :: + * This field is a union that can hold an integer or a pointer. It is + * used by stream implementations to store file descriptors or `FILE*' + * pointers. + * + * pathname :: + * This field is completely ignored by FreeType. However, it is often + * useful during debugging to use it to store the stream's filename + * (where available). + * + * read :: + * The stream's input function. + * + * close :: + * The stream;s close function. + * + * memory :: + * The memory manager to use to preload frames. This is set + * internally by FreeType and shouldn't be touched by stream + * implementations. + * + * cursor :: + * This field is set and used internally by FreeType when parsing + * frames. + * + * limit :: + * This field is set and used internally by FreeType when parsing + * frames. + * + */ + typedef struct FT_StreamRec_ + { + unsigned char* base; + unsigned long size; + unsigned long pos; + + FT_StreamDesc descriptor; + FT_StreamDesc pathname; + FT_Stream_IoFunc read; + FT_Stream_CloseFunc close; + + FT_Memory memory; + unsigned char* cursor; + unsigned char* limit; + + } FT_StreamRec; + + + /* */ + + +FT_END_HEADER + +#endif /* __FTSYSTEM_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/fttrigon.h b/utils/openttd/freetype/fttrigon.h new file mode 100644 index 00000000000..6b77d2ee54c --- /dev/null +++ b/utils/openttd/freetype/fttrigon.h @@ -0,0 +1,350 @@ +/***************************************************************************/ +/* */ +/* fttrigon.h */ +/* */ +/* FreeType trigonometric functions (specification). */ +/* */ +/* Copyright 2001, 2003, 2005, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTTRIGON_H__ +#define __FTTRIGON_H__ + +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* computations */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @type: + * FT_Angle + * + * @description: + * This type is used to model angle values in FreeType. Note that the + * angle is a 16.16 fixed float value expressed in degrees. + * + */ + typedef FT_Fixed FT_Angle; + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI + * + * @description: + * The angle pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI ( 180L << 16 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_2PI + * + * @description: + * The angle 2*pi expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_2PI ( FT_ANGLE_PI * 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI2 + * + * @description: + * The angle pi/2 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI2 ( FT_ANGLE_PI / 2 ) + + + /************************************************************************* + * + * @macro: + * FT_ANGLE_PI4 + * + * @description: + * The angle pi/4 expressed in @FT_Angle units. + * + */ +#define FT_ANGLE_PI4 ( FT_ANGLE_PI / 4 ) + + + /************************************************************************* + * + * @function: + * FT_Sin + * + * @description: + * Return the sinus of a given angle in fixed point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The sinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Sin( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Cos + * + * @description: + * Return the cosinus of a given angle in fixed point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The cosinus value. + * + * @note: + * If you need both the sinus and cosinus for a given angle, use the + * function @FT_Vector_Unit. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Cos( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Tan + * + * @description: + * Return the tangent of a given angle in fixed point format. + * + * @input: + * angle :: + * The input angle. + * + * @return: + * The tangent value. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Tan( FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Atan2 + * + * @description: + * Return the arc-tangent corresponding to a given vector (x,y) in + * the 2d plane. + * + * @input: + * x :: + * The horizontal vector coordinate. + * + * y :: + * The vertical vector coordinate. + * + * @return: + * The arc-tangent value (i.e. angle). + * + */ + FT_EXPORT( FT_Angle ) + FT_Atan2( FT_Fixed x, + FT_Fixed y ); + + + /************************************************************************* + * + * @function: + * FT_Angle_Diff + * + * @description: + * Return the difference between two angles. The result is always + * constrained to the ]-PI..PI] interval. + * + * @input: + * angle1 :: + * First angle. + * + * angle2 :: + * Second angle. + * + * @return: + * Constrained value of `value2-value1'. + * + */ + FT_EXPORT( FT_Angle ) + FT_Angle_Diff( FT_Angle angle1, + FT_Angle angle2 ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Unit + * + * @description: + * Return the unit vector corresponding to a given angle. After the + * call, the value of `vec.x' will be `sin(angle)', and the value of + * `vec.y' will be `cos(angle)'. + * + * This function is useful to retrieve both the sinus and cosinus of a + * given angle quickly. + * + * @output: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The address of angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Unit( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Rotate + * + * @description: + * Rotate a vector by a given angle. + * + * @inout: + * vec :: + * The address of target vector. + * + * @input: + * angle :: + * The address of angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Rotate( FT_Vector* vec, + FT_Angle angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Length + * + * @description: + * Return the length of a given vector. + * + * @input: + * vec :: + * The address of target vector. + * + * @return: + * The vector length, expressed in the same units that the original + * vector coordinates. + * + */ + FT_EXPORT( FT_Fixed ) + FT_Vector_Length( FT_Vector* vec ); + + + /************************************************************************* + * + * @function: + * FT_Vector_Polarize + * + * @description: + * Compute both the length and angle of a given vector. + * + * @input: + * vec :: + * The address of source vector. + * + * @output: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_Polarize( FT_Vector* vec, + FT_Fixed *length, + FT_Angle *angle ); + + + /************************************************************************* + * + * @function: + * FT_Vector_From_Polar + * + * @description: + * Compute vector coordinates from a length and angle. + * + * @output: + * vec :: + * The address of source vector. + * + * @input: + * length :: + * The vector length. + * + * angle :: + * The vector angle. + * + */ + FT_EXPORT( void ) + FT_Vector_From_Polar( FT_Vector* vec, + FT_Fixed length, + FT_Angle angle ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTTRIGON_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/fttypes.h b/utils/openttd/freetype/fttypes.h new file mode 100644 index 00000000000..54f08e3e5a2 --- /dev/null +++ b/utils/openttd/freetype/fttypes.h @@ -0,0 +1,587 @@ +/***************************************************************************/ +/* */ +/* fttypes.h */ +/* */ +/* FreeType simple types definitions (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTTYPES_H__ +#define __FTTYPES_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_SYSTEM_H +#include FT_IMAGE_H + +#include <stddef.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /* <Title> */ + /* Basic Data Types */ + /* */ + /* <Abstract> */ + /* The basic data types defined by the library. */ + /* */ + /* <Description> */ + /* This section contains the basic data types defined by FreeType~2, */ + /* ranging from simple scalar types to bitmap descriptors. More */ + /* font-specific structures are defined in a different section. */ + /* */ + /* <Order> */ + /* FT_Byte */ + /* FT_Bytes */ + /* FT_Char */ + /* FT_Int */ + /* FT_UInt */ + /* FT_Int16 */ + /* FT_UInt16 */ + /* FT_Int32 */ + /* FT_UInt32 */ + /* FT_Short */ + /* FT_UShort */ + /* FT_Long */ + /* FT_ULong */ + /* FT_Bool */ + /* FT_Offset */ + /* FT_PtrDist */ + /* FT_String */ + /* FT_Tag */ + /* FT_Error */ + /* FT_Fixed */ + /* FT_Pointer */ + /* FT_Pos */ + /* FT_Vector */ + /* FT_BBox */ + /* FT_Matrix */ + /* FT_FWord */ + /* FT_UFWord */ + /* FT_F2Dot14 */ + /* FT_UnitVector */ + /* FT_F26Dot6 */ + /* */ + /* */ + /* FT_Generic */ + /* FT_Generic_Finalizer */ + /* */ + /* FT_Bitmap */ + /* FT_Pixel_Mode */ + /* FT_Palette_Mode */ + /* FT_Glyph_Format */ + /* FT_IMAGE_TAG */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bool */ + /* */ + /* <Description> */ + /* A typedef of unsigned char, used for simple booleans. As usual, */ + /* values 1 and~0 represent true and false, respectively. */ + /* */ + typedef unsigned char FT_Bool; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_FWord */ + /* */ + /* <Description> */ + /* A signed 16-bit integer used to store a distance in original font */ + /* units. */ + /* */ + typedef signed short FT_FWord; /* distance in FUnits */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UFWord */ + /* */ + /* <Description> */ + /* An unsigned 16-bit integer used to store a distance in original */ + /* font units. */ + /* */ + typedef unsigned short FT_UFWord; /* unsigned distance */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Char */ + /* */ + /* <Description> */ + /* A simple typedef for the _signed_ char type. */ + /* */ + typedef signed char FT_Char; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Byte */ + /* */ + /* <Description> */ + /* A simple typedef for the _unsigned_ char type. */ + /* */ + typedef unsigned char FT_Byte; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bytes */ + /* */ + /* <Description> */ + /* A typedef for constant memory areas. */ + /* */ + typedef const FT_Byte* FT_Bytes; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Tag */ + /* */ + /* <Description> */ + /* A typedef for 32-bit tags (as used in the SFNT format). */ + /* */ + typedef FT_UInt32 FT_Tag; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_String */ + /* */ + /* <Description> */ + /* A simple typedef for the char type, usually used for strings. */ + /* */ + typedef char FT_String; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Short */ + /* */ + /* <Description> */ + /* A typedef for signed short. */ + /* */ + typedef signed short FT_Short; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UShort */ + /* */ + /* <Description> */ + /* A typedef for unsigned short. */ + /* */ + typedef unsigned short FT_UShort; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int */ + /* */ + /* <Description> */ + /* A typedef for the int type. */ + /* */ + typedef signed int FT_Int; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt */ + /* */ + /* <Description> */ + /* A typedef for the unsigned int type. */ + /* */ + typedef unsigned int FT_UInt; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Long */ + /* */ + /* <Description> */ + /* A typedef for signed long. */ + /* */ + typedef signed long FT_Long; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ULong */ + /* */ + /* <Description> */ + /* A typedef for unsigned long. */ + /* */ + typedef unsigned long FT_ULong; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F2Dot14 */ + /* */ + /* <Description> */ + /* A signed 2.14 fixed float type used for unit vectors. */ + /* */ + typedef signed short FT_F2Dot14; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F26Dot6 */ + /* */ + /* <Description> */ + /* A signed 26.6 fixed float type used for vectorial pixel */ + /* coordinates. */ + /* */ + typedef signed long FT_F26Dot6; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Fixed */ + /* */ + /* <Description> */ + /* This type is used to store 16.16 fixed float values, like scaling */ + /* values or matrix coefficients. */ + /* */ + typedef signed long FT_Fixed; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Error */ + /* */ + /* <Description> */ + /* The FreeType error code type. A value of~0 is always interpreted */ + /* as a successful operation. */ + /* */ + typedef int FT_Error; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pointer */ + /* */ + /* <Description> */ + /* A simple typedef for a typeless pointer. */ + /* */ + typedef void* FT_Pointer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Offset */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `size_t' type, i.e., the largest */ + /* _unsigned_ integer type used to express a file size or position, */ + /* or a memory block size. */ + /* */ + typedef size_t FT_Offset; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_PtrDist */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI~C `ptrdiff_t' type, i.e., the */ + /* largest _signed_ integer type used to express the distance */ + /* between two pointers. */ + /* */ + typedef ft_ptrdiff_t FT_PtrDist; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_UnitVector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector unit vector. Uses */ + /* FT_F2Dot14 types. */ + /* */ + /* <Fields> */ + /* x :: Horizontal coordinate. */ + /* */ + /* y :: Vertical coordinate. */ + /* */ + typedef struct FT_UnitVector_ + { + FT_F2Dot14 x; + FT_F2Dot14 y; + + } FT_UnitVector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Matrix */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2x2 matrix. Coefficients are */ + /* in 16.16 fixed float format. The computation performed is: */ + /* */ + /* { */ + /* x' = x*xx + y*xy */ + /* y' = x*yx + y*yy */ + /* } */ + /* */ + /* <Fields> */ + /* xx :: Matrix coefficient. */ + /* */ + /* xy :: Matrix coefficient. */ + /* */ + /* yx :: Matrix coefficient. */ + /* */ + /* yy :: Matrix coefficient. */ + /* */ + typedef struct FT_Matrix_ + { + FT_Fixed xx, xy; + FT_Fixed yx, yy; + + } FT_Matrix; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Data */ + /* */ + /* <Description> */ + /* Read-only binary data represented as a pointer and a length. */ + /* */ + /* <Fields> */ + /* pointer :: The data. */ + /* */ + /* length :: The length of the data in bytes. */ + /* */ + typedef struct FT_Data_ + { + const FT_Byte* pointer; + FT_Int length; + + } FT_Data; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Generic_Finalizer */ + /* */ + /* <Description> */ + /* Describe a function used to destroy the `client' data of any */ + /* FreeType object. See the description of the @FT_Generic type for */ + /* details of usage. */ + /* */ + /* <Input> */ + /* The address of the FreeType object which is under finalization. */ + /* Its client data is accessed through its `generic' field. */ + /* */ + typedef void (*FT_Generic_Finalizer)(void* object); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Generic */ + /* */ + /* <Description> */ + /* Client applications often need to associate their own data to a */ + /* variety of FreeType core objects. For example, a text layout API */ + /* might want to associate a glyph cache to a given size object. */ + /* */ + /* Most FreeType object contains a `generic' field, of type */ + /* FT_Generic, which usage is left to client applications and font */ + /* servers. */ + /* */ + /* It can be used to store a pointer to client-specific data, as well */ + /* as the address of a `finalizer' function, which will be called by */ + /* FreeType when the object is destroyed (for example, the previous */ + /* client example would put the address of the glyph cache destructor */ + /* in the `finalizer' field). */ + /* */ + /* <Fields> */ + /* data :: A typeless pointer to any client-specified data. This */ + /* field is completely ignored by the FreeType library. */ + /* */ + /* finalizer :: A pointer to a `generic finalizer' function, which */ + /* will be called when the object is destroyed. If this */ + /* field is set to NULL, no code will be called. */ + /* */ + typedef struct FT_Generic_ + { + void* data; + FT_Generic_Finalizer finalizer; + + } FT_Generic; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_MAKE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four-letter tags which are used to label */ + /* TrueType tables into an unsigned long to be used within FreeType. */ + /* */ + /* <Note> */ + /* The produced values *must* be 32-bit integers. Don't redefine */ + /* this macro. */ + /* */ +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + ( ( (FT_ULong)_x1 << 24 ) | \ + ( (FT_ULong)_x2 << 16 ) | \ + ( (FT_ULong)_x3 << 8 ) | \ + (FT_ULong)_x4 ) + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* L I S T M A N A G E M E N T */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ListNode */ + /* */ + /* <Description> */ + /* Many elements and objects in FreeType are listed through an */ + /* @FT_List record (see @FT_ListRec). As its name suggests, an */ + /* FT_ListNode is a handle to a single list element. */ + /* */ + typedef struct FT_ListNodeRec_* FT_ListNode; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_List */ + /* */ + /* <Description> */ + /* A handle to a list record (see @FT_ListRec). */ + /* */ + typedef struct FT_ListRec_* FT_List; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListNodeRec */ + /* */ + /* <Description> */ + /* A structure used to hold a single list element. */ + /* */ + /* <Fields> */ + /* prev :: The previous element in the list. NULL if first. */ + /* */ + /* next :: The next element in the list. NULL if last. */ + /* */ + /* data :: A typeless pointer to the listed object. */ + /* */ + typedef struct FT_ListNodeRec_ + { + FT_ListNode prev; + FT_ListNode next; + void* data; + + } FT_ListNodeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListRec */ + /* */ + /* <Description> */ + /* A structure used to hold a simple doubly-linked list. These are */ + /* used in many parts of FreeType. */ + /* */ + /* <Fields> */ + /* head :: The head (first element) of doubly-linked list. */ + /* */ + /* tail :: The tail (last element) of doubly-linked list. */ + /* */ + typedef struct FT_ListRec_ + { + FT_ListNode head; + FT_ListNode tail; + + } FT_ListRec; + + + /* */ + +#define FT_IS_EMPTY( list ) ( (list).head == 0 ) + + /* return base error code (without module-specific prefix) */ +#define FT_ERROR_BASE( x ) ( (x) & 0xFF ) + + /* return module error code */ +#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) + +#define FT_BOOL( x ) ( (FT_Bool)( x ) ) + +FT_END_HEADER + +#endif /* __FTTYPES_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ftwinfnt.h b/utils/openttd/freetype/ftwinfnt.h new file mode 100644 index 00000000000..ea33353536e --- /dev/null +++ b/utils/openttd/freetype/ftwinfnt.h @@ -0,0 +1,274 @@ +/***************************************************************************/ +/* */ +/* ftwinfnt.h */ +/* */ +/* FreeType API for accessing Windows fnt-specific data. */ +/* */ +/* Copyright 2003, 2004, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTWINFNT_H__ +#define __FTWINFNT_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* winfnt_fonts */ + /* */ + /* <Title> */ + /* Window FNT Files */ + /* */ + /* <Abstract> */ + /* Windows FNT specific API. */ + /* */ + /* <Description> */ + /* This section contains the declaration of Windows FNT specific */ + /* functions. */ + /* */ + /*************************************************************************/ + + + /************************************************************************* + * + * @enum: + * FT_WinFNT_ID_XXX + * + * @description: + * A list of valid values for the `charset' byte in + * @FT_WinFNT_HeaderRec. Exact mapping tables for the various cpXXXX + * encodings (except for cp1361) can be found at ftp://ftp.unicode.org + * in the MAPPINGS/VENDORS/MICSFT/WINDOWS subdirectory. cp1361 is + * roughly a superset of MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT. + * + * @values: + * FT_WinFNT_ID_DEFAULT :: + * This is used for font enumeration and font creation as a + * `don't care' value. Valid font files don't contain this value. + * When querying for information about the character set of the font + * that is currently selected into a specified device context, this + * return value (of the related Windows API) simply denotes failure. + * + * FT_WinFNT_ID_SYMBOL :: + * There is no known mapping table available. + * + * FT_WinFNT_ID_MAC :: + * Mac Roman encoding. + * + * FT_WinFNT_ID_OEM :: + * From Michael Pöttgen <michael@poettgen.de>: + * + * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM + * is used for the charset of vector fonts, like `modern.fon', + * `roman.fon', and `script.fon' on Windows. + * + * The `CreateFont' documentation says: The FT_WinFNT_ID_OEM value + * specifies a character set that is operating-system dependent. + * + * The `IFIMETRICS' documentation from the `Windows Driver + * Development Kit' says: This font supports an OEM-specific + * character set. The OEM character set is system dependent. + * + * In general OEM, as opposed to ANSI (i.e., cp1252), denotes the + * second default codepage that most international versions of + * Windows have. It is one of the OEM codepages from + * + * http://www.microsoft.com/globaldev/reference/cphome.mspx, + * + * and is used for the `DOS boxes', to support legacy applications. + * A German Windows version for example usually uses ANSI codepage + * 1252 and OEM codepage 850. + * + * FT_WinFNT_ID_CP874 :: + * A superset of Thai TIS 620 and ISO 8859-11. + * + * FT_WinFNT_ID_CP932 :: + * A superset of Japanese Shift-JIS (with minor deviations). + * + * FT_WinFNT_ID_CP936 :: + * A superset of simplified Chinese GB 2312-1980 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP949 :: + * A superset of Korean Hangul KS~C 5601-1987 (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP950 :: + * A superset of traditional Chinese Big~5 ETen (with different + * ordering and minor deviations). + * + * FT_WinFNT_ID_CP1250 :: + * A superset of East European ISO 8859-2 (with slightly different + * ordering). + * + * FT_WinFNT_ID_CP1251 :: + * A superset of Russian ISO 8859-5 (with different ordering). + * + * FT_WinFNT_ID_CP1252 :: + * ANSI encoding. A superset of ISO 8859-1. + * + * FT_WinFNT_ID_CP1253 :: + * A superset of Greek ISO 8859-7 (with minor modifications). + * + * FT_WinFNT_ID_CP1254 :: + * A superset of Turkish ISO 8859-9. + * + * FT_WinFNT_ID_CP1255 :: + * A superset of Hebrew ISO 8859-8 (with some modifications). + * + * FT_WinFNT_ID_CP1256 :: + * A superset of Arabic ISO 8859-6 (with different ordering). + * + * FT_WinFNT_ID_CP1257 :: + * A superset of Baltic ISO 8859-13 (with some deviations). + * + * FT_WinFNT_ID_CP1258 :: + * For Vietnamese. This encoding doesn't cover all necessary + * characters. + * + * FT_WinFNT_ID_CP1361 :: + * Korean (Johab). + */ + +#define FT_WinFNT_ID_CP1252 0 +#define FT_WinFNT_ID_DEFAULT 1 +#define FT_WinFNT_ID_SYMBOL 2 +#define FT_WinFNT_ID_MAC 77 +#define FT_WinFNT_ID_CP932 128 +#define FT_WinFNT_ID_CP949 129 +#define FT_WinFNT_ID_CP1361 130 +#define FT_WinFNT_ID_CP936 134 +#define FT_WinFNT_ID_CP950 136 +#define FT_WinFNT_ID_CP1253 161 +#define FT_WinFNT_ID_CP1254 162 +#define FT_WinFNT_ID_CP1258 163 +#define FT_WinFNT_ID_CP1255 177 +#define FT_WinFNT_ID_CP1256 178 +#define FT_WinFNT_ID_CP1257 186 +#define FT_WinFNT_ID_CP1251 204 +#define FT_WinFNT_ID_CP874 222 +#define FT_WinFNT_ID_CP1250 238 +#define FT_WinFNT_ID_OEM 255 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_HeaderRec */ + /* */ + /* <Description> */ + /* Windows FNT Header info. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_ + { + FT_UShort version; + FT_ULong file_size; + FT_Byte copyright[60]; + FT_UShort file_type; + FT_UShort nominal_point_size; + FT_UShort vertical_resolution; + FT_UShort horizontal_resolution; + FT_UShort ascent; + FT_UShort internal_leading; + FT_UShort external_leading; + FT_Byte italic; + FT_Byte underline; + FT_Byte strike_out; + FT_UShort weight; + FT_Byte charset; + FT_UShort pixel_width; + FT_UShort pixel_height; + FT_Byte pitch_and_family; + FT_UShort avg_width; + FT_UShort max_width; + FT_Byte first_char; + FT_Byte last_char; + FT_Byte default_char; + FT_Byte break_char; + FT_UShort bytes_per_row; + FT_ULong device_offset; + FT_ULong face_name_offset; + FT_ULong bits_pointer; + FT_ULong bits_offset; + FT_Byte reserved; + FT_ULong flags; + FT_UShort A_space; + FT_UShort B_space; + FT_UShort C_space; + FT_UShort color_table_offset; + FT_ULong reserved1[4]; + + } FT_WinFNT_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_WinFNT_Header */ + /* */ + /* <Description> */ + /* A handle to an @FT_WinFNT_HeaderRec structure. */ + /* */ + typedef struct FT_WinFNT_HeaderRec_* FT_WinFNT_Header; + + + /********************************************************************** + * + * @function: + * FT_Get_WinFNT_Header + * + * @description: + * Retrieve a Windows FNT font info header. + * + * @input: + * face :: A handle to the input face. + * + * @output: + * aheader :: The WinFNT header. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with Windows FNT faces, returning an error + * otherwise. + */ + FT_EXPORT( FT_Error ) + FT_Get_WinFNT_Header( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + + /* */ + +FT_END_HEADER + +#endif /* __FTWINFNT_H__ */ + + +/* END */ + + +/* Local Variables: */ +/* coding: utf-8 */ +/* End: */ diff --git a/utils/openttd/freetype/ftxf86.h b/utils/openttd/freetype/ftxf86.h new file mode 100644 index 00000000000..ae9ff076fab --- /dev/null +++ b/utils/openttd/freetype/ftxf86.h @@ -0,0 +1,80 @@ +/***************************************************************************/ +/* */ +/* ftxf86.h */ +/* */ +/* Support functions for X11. */ +/* */ +/* Copyright 2002, 2003, 2004, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTXF86_H__ +#define __FTXF86_H__ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* font_formats */ + /* */ + /* <Title> */ + /* Font Formats */ + /* */ + /* <Abstract> */ + /* Getting the font format. */ + /* */ + /* <Description> */ + /* The single function in this section can be used to get the font */ + /* format. Note that this information is not needed normally; */ + /* however, there are special cases (like in PDF devices) where it is */ + /* important to differentiate, in spite of FreeType's uniform API. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_X11_Font_Format */ + /* */ + /* <Description> */ + /* Return a string describing the format of a given face, using values */ + /* which can be used as an X11 FONT_PROPERTY. Possible values are */ + /* `TrueType', `Type~1', `BDF', `PCF', `Type~42', `CID~Type~1', `CFF', */ + /* `PFR', and `Windows~FNT'. */ + /* */ + /* <Input> */ + /* face :: */ + /* Input face handle. */ + /* */ + /* <Return> */ + /* Font format string. NULL in case of error. */ + /* */ + FT_EXPORT( const char* ) + FT_Get_X11_Font_Format( FT_Face face ); + + /* */ + +FT_END_HEADER + +#endif /* __FTXF86_H__ */ diff --git a/utils/openttd/freetype/internal/autohint.h b/utils/openttd/freetype/internal/autohint.h new file mode 100644 index 00000000000..ee004022f9d --- /dev/null +++ b/utils/openttd/freetype/internal/autohint.h @@ -0,0 +1,205 @@ +/***************************************************************************/ +/* */ +/* autohint.h */ +/* */ +/* High-level `autohint' module-specific interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The auto-hinter is used to load and automatically hint glyphs if a */ + /* format-specific hinter isn't available. */ + /* */ + /*************************************************************************/ + + +#ifndef __AUTOHINT_H__ +#define __AUTOHINT_H__ + + + /*************************************************************************/ + /* */ + /* A small technical note regarding automatic hinting in order to */ + /* clarify this module interface. */ + /* */ + /* An automatic hinter might compute two kinds of data for a given face: */ + /* */ + /* - global hints: Usually some metrics that describe global properties */ + /* of the face. It is computed by scanning more or less */ + /* aggressively the glyphs in the face, and thus can be */ + /* very slow to compute (even if the size of global */ + /* hints is really small). */ + /* */ + /* - glyph hints: These describe some important features of the glyph */ + /* outline, as well as how to align them. They are */ + /* generally much faster to compute than global hints. */ + /* */ + /* The current FreeType auto-hinter does a pretty good job while */ + /* performing fast computations for both global and glyph hints. */ + /* However, we might be interested in introducing more complex and */ + /* powerful algorithms in the future, like the one described in the John */ + /* D. Hobby paper, which unfortunately requires a lot more horsepower. */ + /* */ + /* Because a sufficiently sophisticated font management system would */ + /* typically implement an LRU cache of opened face objects to reduce */ + /* memory usage, it is a good idea to be able to avoid recomputing */ + /* global hints every time the same face is re-opened. */ + /* */ + /* We thus provide the ability to cache global hints outside of the face */ + /* object, in order to speed up font re-opening time. Of course, this */ + /* feature is purely optional, so most client programs won't even notice */ + /* it. */ + /* */ + /* I initially thought that it would be a good idea to cache the glyph */ + /* hints too. However, my general idea now is that if you really need */ + /* to cache these too, you are simply in need of a new font format, */ + /* where all this information could be stored within the font file and */ + /* decoded on the fly. */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef struct FT_AutoHinterRec_ *FT_AutoHinter; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalGetFunc */ + /* */ + /* <Description> */ + /* Retrieves the global hints computed for a given face object the */ + /* resulting data is dissociated from the face and will survive a */ + /* call to FT_Done_Face(). It must be discarded through the API */ + /* FT_AutoHinter_GlobalDoneFunc(). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the source face object. */ + /* */ + /* <Output> */ + /* global_hints :: A typeless pointer to the global hints. */ + /* */ + /* global_len :: The size in bytes of the global hints. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalGetFunc)( FT_AutoHinter hinter, + FT_Face face, + void** global_hints, + long* global_len ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalDoneFunc */ + /* */ + /* <Description> */ + /* Discards the global hints retrieved through */ + /* FT_AutoHinter_GlobalGetFunc(). This is the only way these hints */ + /* are freed from memory. */ + /* */ + /* <Input> */ + /* hinter :: A handle to the auto-hinter module. */ + /* */ + /* global :: A pointer to retrieved global hints to discard. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalDoneFunc)( FT_AutoHinter hinter, + void* global ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlobalResetFunc */ + /* */ + /* <Description> */ + /* This function is used to recompute the global metrics in a given */ + /* font. This is useful when global font data changes (e.g. Multiple */ + /* Masters fonts where blend coordinates change). */ + /* */ + /* <Input> */ + /* hinter :: A handle to the source auto-hinter. */ + /* */ + /* face :: A handle to the face. */ + /* */ + typedef void + (*FT_AutoHinter_GlobalResetFunc)( FT_AutoHinter hinter, + FT_Face face ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_AutoHinter_GlyphLoadFunc */ + /* */ + /* <Description> */ + /* This function is used to load, scale, and automatically hint a */ + /* glyph from a given face. */ + /* */ + /* <Input> */ + /* face :: A handle to the face. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* load_flags :: The load flags. */ + /* */ + /* <Note> */ + /* This function is capable of loading composite glyphs by hinting */ + /* each sub-glyph independently (which improves quality). */ + /* */ + /* It will call the font driver with FT_Load_Glyph(), with */ + /* FT_LOAD_NO_SCALE set. */ + /* */ + typedef FT_Error + (*FT_AutoHinter_GlyphLoadFunc)( FT_AutoHinter hinter, + FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_AutoHinter_ServiceRec */ + /* */ + /* <Description> */ + /* The auto-hinter module's interface. */ + /* */ + typedef struct FT_AutoHinter_ServiceRec_ + { + FT_AutoHinter_GlobalResetFunc reset_face; + FT_AutoHinter_GlobalGetFunc get_global_hints; + FT_AutoHinter_GlobalDoneFunc done_global_hints; + FT_AutoHinter_GlyphLoadFunc load_glyph; + + } FT_AutoHinter_ServiceRec, *FT_AutoHinter_Service; + + +FT_END_HEADER + +#endif /* __AUTOHINT_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftcalc.h b/utils/openttd/freetype/internal/ftcalc.h new file mode 100644 index 00000000000..58def34cab2 --- /dev/null +++ b/utils/openttd/freetype/internal/ftcalc.h @@ -0,0 +1,178 @@ +/***************************************************************************/ +/* */ +/* ftcalc.h */ +/* */ +/* Arithmetic computations (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTCALC_H__ +#define __FTCALC_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_FixedSqrt */ + /* */ + /* <Description> */ + /* Computes the square root of a 16.16 fixed point value. */ + /* */ + /* <Input> */ + /* x :: The value to compute the root for. */ + /* */ + /* <Return> */ + /* The result of `sqrt(x)'. */ + /* */ + /* <Note> */ + /* This function is not very fast. */ + /* */ + FT_BASE( FT_Int32 ) + FT_SqrtFixed( FT_Int32 x ); + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Sqrt32 */ + /* */ + /* <Description> */ + /* Computes the square root of an Int32 integer (which will be */ + /* handled as an unsigned long value). */ + /* */ + /* <Input> */ + /* x :: The value to compute the root for. */ + /* */ + /* <Return> */ + /* The result of `sqrt(x)'. */ + /* */ + FT_EXPORT( FT_Int32 ) + FT_Sqrt32( FT_Int32 x ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /*************************************************************************/ + /* */ + /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */ + /* */ + /*************************************************************************/ + + +#ifdef TT_USE_BYTECODE_INTERPRETER + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_MulDiv_No_Round */ + /* */ + /* <Description> */ + /* A very simple function used to perform the computation `(a*b)/c' */ + /* (without rounding) with maximal accuracy (it uses a 64-bit */ + /* intermediate integer whenever necessary). */ + /* */ + /* This function isn't necessarily as fast as some processor specific */ + /* operations, but is at least completely portable. */ + /* */ + /* <Input> */ + /* a :: The first multiplier. */ + /* b :: The second multiplier. */ + /* c :: The divisor. */ + /* */ + /* <Return> */ + /* The result of `(a*b)/c'. This function never traps when trying to */ + /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */ + /* on the signs of `a' and `b'. */ + /* */ + FT_BASE( FT_Long ) + FT_MulDiv_No_Round( FT_Long a, + FT_Long b, + FT_Long c ); + +#endif /* TT_USE_BYTECODE_INTERPRETER */ + + + /* + * A variant of FT_Matrix_Multiply which scales its result afterwards. + * The idea is that both `a' and `b' are scaled by factors of 10 so that + * the values are as precise as possible to get a correct result during + * the 64bit multiplication. Let `sa' and `sb' be the scaling factors of + * `a' and `b', respectively, then the scaling factor of the result is + * `sa*sb'. + */ + FT_BASE( void ) + FT_Matrix_Multiply_Scaled( const FT_Matrix* a, + FT_Matrix *b, + FT_Long scaling ); + + + /* + * A variant of FT_Vector_Transform. See comments for + * FT_Matrix_Multiply_Scaled. + */ + + FT_BASE( void ) + FT_Vector_Transform_Scaled( FT_Vector* vector, + const FT_Matrix* matrix, + FT_Long scaling ); + + + /* + * Return -1, 0, or +1, depending on the orientation of a given corner. + * We use the Cartesian coordinate system, with positive vertical values + * going upwards. The function returns +1 if the corner turns to the + * left, -1 to the right, and 0 for undecidable cases. + */ + FT_BASE( FT_Int ) + ft_corner_orientation( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ); + + /* + * Return TRUE if a corner is flat or nearly flat. This is equivalent to + * saying that the angle difference between the `in' and `out' vectors is + * very small. + */ + FT_BASE( FT_Int ) + ft_corner_is_flat( FT_Pos in_x, + FT_Pos in_y, + FT_Pos out_x, + FT_Pos out_y ); + + +#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) +#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) +#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) +#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) +#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) + +#define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ + : ( -( ( 32 - (x) ) & -64 ) ) ) + + +FT_END_HEADER + +#endif /* __FTCALC_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftdebug.h b/utils/openttd/freetype/internal/ftdebug.h new file mode 100644 index 00000000000..d40af4fe1e5 --- /dev/null +++ b/utils/openttd/freetype/internal/ftdebug.h @@ -0,0 +1,250 @@ +/***************************************************************************/ +/* */ +/* ftdebug.h */ +/* */ +/* Debugging and logging component (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/* */ +/* IMPORTANT: A description of FreeType's debugging support can be */ +/* found in `docs/DEBUG.TXT'. Read it if you need to use or */ +/* understand this code. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTDEBUG_H__ +#define __FTDEBUG_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /* force the definition of FT_DEBUG_LEVEL_ERROR if FT_DEBUG_LEVEL_TRACE */ + /* is already defined; this simplifies the following #ifdefs */ + /* */ +#ifdef FT_DEBUG_LEVEL_TRACE +#undef FT_DEBUG_LEVEL_ERROR +#define FT_DEBUG_LEVEL_ERROR +#endif + + + /*************************************************************************/ + /* */ + /* Define the trace enums as well as the trace levels array when they */ + /* are needed. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define FT_TRACE_DEF( x ) trace_ ## x , + + /* defining the enumeration */ + typedef enum FT_Trace_ + { +#include FT_INTERNAL_TRACE_H + trace_count + + } FT_Trace; + + + /* defining the array of trace levels, provided by `src/base/ftdebug.c' */ + extern int ft_trace_levels[trace_count]; + +#undef FT_TRACE_DEF + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Define the FT_TRACE macro */ + /* */ + /* IMPORTANT! */ + /* */ + /* Each component must define the macro FT_COMPONENT to a valid FT_Trace */ + /* value before using any TRACE macro. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_TRACE + +#define FT_TRACE( level, varformat ) \ + do \ + { \ + if ( ft_trace_levels[FT_COMPONENT] >= level ) \ + FT_Message varformat; \ + } while ( 0 ) + +#else /* !FT_DEBUG_LEVEL_TRACE */ + +#define FT_TRACE( level, varformat ) do ; while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Trace_Get_Count */ + /* */ + /* <Description> */ + /* Return the number of available trace components. */ + /* */ + /* <Return> */ + /* The number of trace components. 0 if FreeType 2 is not built with */ + /* FT_DEBUG_LEVEL_TRACE definition. */ + /* */ + /* <Note> */ + /* This function may be useful if you want to access elements of */ + /* the internal `ft_trace_levels' array by an index. */ + /* */ + FT_BASE( FT_Int ) + FT_Trace_Get_Count( void ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Trace_Get_Name */ + /* */ + /* <Description> */ + /* Return the name of a trace component. */ + /* */ + /* <Input> */ + /* The index of the trace component. */ + /* */ + /* <Return> */ + /* The name of the trace component. This is a statically allocated */ + /* C string, so do not free it after use. NULL if FreeType 2 is not */ + /* built with FT_DEBUG_LEVEL_TRACE definition. */ + /* */ + /* <Note> */ + /* Use @FT_Trace_Get_Count to get the number of available trace */ + /* components. */ + /* */ + /* This function may be useful if you want to control FreeType 2's */ + /* debug level in your application. */ + /* */ + FT_BASE( const char * ) + FT_Trace_Get_Name( FT_Int idx ); + + + /*************************************************************************/ + /* */ + /* You need two opening and closing parentheses! */ + /* */ + /* Example: FT_TRACE0(( "Value is %i", foo )) */ + /* */ + /* Output of the FT_TRACEX macros is sent to stderr. */ + /* */ + /*************************************************************************/ + +#define FT_TRACE0( varformat ) FT_TRACE( 0, varformat ) +#define FT_TRACE1( varformat ) FT_TRACE( 1, varformat ) +#define FT_TRACE2( varformat ) FT_TRACE( 2, varformat ) +#define FT_TRACE3( varformat ) FT_TRACE( 3, varformat ) +#define FT_TRACE4( varformat ) FT_TRACE( 4, varformat ) +#define FT_TRACE5( varformat ) FT_TRACE( 5, varformat ) +#define FT_TRACE6( varformat ) FT_TRACE( 6, varformat ) +#define FT_TRACE7( varformat ) FT_TRACE( 7, varformat ) + + + /*************************************************************************/ + /* */ + /* Define the FT_ERROR macro. */ + /* */ + /* Output of this macro is sent to stderr. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#define FT_ERROR( varformat ) FT_Message varformat + +#else /* !FT_DEBUG_LEVEL_ERROR */ + +#define FT_ERROR( varformat ) do ; while ( 0 ) /* nothing */ + +#endif /* !FT_DEBUG_LEVEL_ERROR */ + + + /*************************************************************************/ + /* */ + /* Define the FT_ASSERT macro. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#define FT_ASSERT( condition ) \ + do \ + { \ + if ( !( condition ) ) \ + FT_Panic( "assertion failed on line %d of file %s\n", \ + __LINE__, __FILE__ ); \ + } while ( 0 ) + +#else /* !FT_DEBUG_LEVEL_ERROR */ + +#define FT_ASSERT( condition ) do ; while ( 0 ) + +#endif /* !FT_DEBUG_LEVEL_ERROR */ + + + /*************************************************************************/ + /* */ + /* Define `FT_Message' and `FT_Panic' when needed. */ + /* */ + /*************************************************************************/ + +#ifdef FT_DEBUG_LEVEL_ERROR + +#include "stdio.h" /* for vfprintf() */ + + /* print a message */ + FT_BASE( void ) + FT_Message( const char* fmt, + ... ); + + /* print a message and exit */ + FT_BASE( void ) + FT_Panic( const char* fmt, + ... ); + +#endif /* FT_DEBUG_LEVEL_ERROR */ + + + FT_BASE( void ) + ft_debug_init( void ); + + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + + /* We disable the warning `conditional expression is constant' here */ + /* in order to compile cleanly with the maximum level of warnings. */ +#pragma warning( disable : 4127 ) + +#endif /* _MSC_VER */ + + +FT_END_HEADER + +#endif /* __FTDEBUG_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftdriver.h b/utils/openttd/freetype/internal/ftdriver.h new file mode 100644 index 00000000000..e433e78da06 --- /dev/null +++ b/utils/openttd/freetype/internal/ftdriver.h @@ -0,0 +1,248 @@ +/***************************************************************************/ +/* */ +/* ftdriver.h */ +/* */ +/* FreeType font driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTDRIVER_H__ +#define __FTDRIVER_H__ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + typedef FT_Error + (*FT_Face_InitFunc)( FT_Stream stream, + FT_Face face, + FT_Int typeface_index, + FT_Int num_params, + FT_Parameter* parameters ); + + typedef void + (*FT_Face_DoneFunc)( FT_Face face ); + + + typedef FT_Error + (*FT_Size_InitFunc)( FT_Size size ); + + typedef void + (*FT_Size_DoneFunc)( FT_Size size ); + + + typedef FT_Error + (*FT_Slot_InitFunc)( FT_GlyphSlot slot ); + + typedef void + (*FT_Slot_DoneFunc)( FT_GlyphSlot slot ); + + + typedef FT_Error + (*FT_Size_RequestFunc)( FT_Size size, + FT_Size_Request req ); + + typedef FT_Error + (*FT_Size_SelectFunc)( FT_Size size, + FT_ULong size_index ); + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + typedef FT_Error + (*FT_Size_ResetPointsFunc)( FT_Size size, + FT_F26Dot6 char_width, + FT_F26Dot6 char_height, + FT_UInt horz_resolution, + FT_UInt vert_resolution ); + + typedef FT_Error + (*FT_Size_ResetPixelsFunc)( FT_Size size, + FT_UInt pixel_width, + FT_UInt pixel_height ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + typedef FT_Error + (*FT_Slot_LoadFunc)( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + typedef FT_UInt + (*FT_CharMap_CharIndexFunc)( FT_CharMap charmap, + FT_Long charcode ); + + typedef FT_Long + (*FT_CharMap_CharNextFunc)( FT_CharMap charmap, + FT_Long charcode ); + + typedef FT_Error + (*FT_Face_GetKerningFunc)( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ); + + + typedef FT_Error + (*FT_Face_AttachFunc)( FT_Face face, + FT_Stream stream ); + + + typedef FT_Error + (*FT_Face_GetAdvancesFunc)( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Bool vertical, + FT_UShort* advances ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Driver_ClassRec */ + /* */ + /* <Description> */ + /* The font driver class. This structure mostly contains pointers to */ + /* driver methods. */ + /* */ + /* <Fields> */ + /* root :: The parent module. */ + /* */ + /* face_object_size :: The size of a face object in bytes. */ + /* */ + /* size_object_size :: The size of a size object in bytes. */ + /* */ + /* slot_object_size :: The size of a glyph object in bytes. */ + /* */ + /* init_face :: The format-specific face constructor. */ + /* */ + /* done_face :: The format-specific face destructor. */ + /* */ + /* init_size :: The format-specific size constructor. */ + /* */ + /* done_size :: The format-specific size destructor. */ + /* */ + /* init_slot :: The format-specific slot constructor. */ + /* */ + /* done_slot :: The format-specific slot destructor. */ + /* */ + /* */ + /* load_glyph :: A function handle to load a glyph to a slot. */ + /* This field is mandatory! */ + /* */ + /* get_kerning :: A function handle to return the unscaled */ + /* kerning for a given pair of glyphs. Can be */ + /* set to 0 if the format doesn't support */ + /* kerning. */ + /* */ + /* attach_file :: This function handle is used to read */ + /* additional data for a face from another */ + /* file/stream. For example, this can be used to */ + /* add data from AFM or PFM files on a Type 1 */ + /* face, or a CIDMap on a CID-keyed face. */ + /* */ + /* get_advances :: A function handle used to return advance */ + /* widths of `count' glyphs (in font units), */ + /* starting at `first'. The `vertical' flag must */ + /* be set to get vertical advance heights. The */ + /* `advances' buffer is caller-allocated. */ + /* Currently not implemented. The idea of this */ + /* function is to be able to perform */ + /* device-independent text layout without loading */ + /* a single glyph image. */ + /* */ + /* request_size :: A handle to a function used to request the new */ + /* character size. Can be set to 0 if the */ + /* scaling done in the base layer suffices. */ + /* */ + /* select_size :: A handle to a function used to select a new */ + /* fixed size. It is used only if */ + /* @FT_FACE_FLAG_FIXED_SIZES is set. Can be set */ + /* to 0 if the scaling done in the base layer */ + /* suffices. */ + /* <Note> */ + /* Most function pointers, with the exception of `load_glyph', can be */ + /* set to 0 to indicate a default behaviour. */ + /* */ + typedef struct FT_Driver_ClassRec_ + { + FT_Module_Class root; + + FT_Long face_object_size; + FT_Long size_object_size; + FT_Long slot_object_size; + + FT_Face_InitFunc init_face; + FT_Face_DoneFunc done_face; + + FT_Size_InitFunc init_size; + FT_Size_DoneFunc done_size; + + FT_Slot_InitFunc init_slot; + FT_Slot_DoneFunc done_slot; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_Size_ResetPointsFunc set_char_sizes; + FT_Size_ResetPixelsFunc set_pixel_sizes; + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + FT_Slot_LoadFunc load_glyph; + + FT_Face_GetKerningFunc get_kerning; + FT_Face_AttachFunc attach_file; + FT_Face_GetAdvancesFunc get_advances; + + /* since version 2.2 */ + FT_Size_RequestFunc request_size; + FT_Size_SelectFunc select_size; + + } FT_Driver_ClassRec, *FT_Driver_Class; + + + /* + * The following functions are used as stubs for `set_char_sizes' and + * `set_pixel_sizes'; the code uses `request_size' and `select_size' + * functions instead. + * + * Implementation is in `src/base/ftobjs.c'. + */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_BASE( FT_Error ) + ft_stub_set_char_sizes( FT_Size size, + FT_F26Dot6 width, + FT_F26Dot6 height, + FT_UInt horz_res, + FT_UInt vert_res ); + + FT_BASE( FT_Error ) + ft_stub_set_pixel_sizes( FT_Size size, + FT_UInt width, + FT_UInt height ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + +FT_END_HEADER + +#endif /* __FTDRIVER_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftgloadr.h b/utils/openttd/freetype/internal/ftgloadr.h new file mode 100644 index 00000000000..548481ac800 --- /dev/null +++ b/utils/openttd/freetype/internal/ftgloadr.h @@ -0,0 +1,168 @@ +/***************************************************************************/ +/* */ +/* ftgloadr.h */ +/* */ +/* The FreeType glyph loader (specification). */ +/* */ +/* Copyright 2002, 2003, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTGLOADR_H__ +#define __FTGLOADR_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_GlyphLoader */ + /* */ + /* <Description> */ + /* The glyph loader is an internal object used to load several glyphs */ + /* together (for example, in the case of composites). */ + /* */ + /* <Note> */ + /* The glyph loader implementation is not part of the high-level API, */ + /* hence the forward structure declaration. */ + /* */ + typedef struct FT_GlyphLoaderRec_* FT_GlyphLoader ; + + +#if 0 /* moved to freetype.h in version 2.2 */ +#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 +#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 +#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 +#define FT_SUBGLYPH_FLAG_SCALE 8 +#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 +#define FT_SUBGLYPH_FLAG_2X2 0x80 +#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 +#endif + + + typedef struct FT_SubGlyphRec_ + { + FT_Int index; + FT_UShort flags; + FT_Int arg1; + FT_Int arg2; + FT_Matrix transform; + + } FT_SubGlyphRec; + + + typedef struct FT_GlyphLoadRec_ + { + FT_Outline outline; /* outline */ + FT_Vector* extra_points; /* extra points table */ + FT_Vector* extra_points2; /* second extra points table */ + FT_UInt num_subglyphs; /* number of subglyphs */ + FT_SubGlyph subglyphs; /* subglyphs */ + + } FT_GlyphLoadRec, *FT_GlyphLoad; + + + typedef struct FT_GlyphLoaderRec_ + { + FT_Memory memory; + FT_UInt max_points; + FT_UInt max_contours; + FT_UInt max_subglyphs; + FT_Bool use_extra; + + FT_GlyphLoadRec base; + FT_GlyphLoadRec current; + + void* other; /* for possible future extension? */ + + } FT_GlyphLoaderRec; + + + /* create new empty glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_New( FT_Memory memory, + FT_GlyphLoader *aloader ); + + /* add an extra points table to a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CreateExtra( FT_GlyphLoader loader ); + + /* destroy a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Done( FT_GlyphLoader loader ); + + /* reset a glyph loader (frees everything int it) */ + FT_BASE( void ) + FT_GlyphLoader_Reset( FT_GlyphLoader loader ); + + /* rewind a glyph loader */ + FT_BASE( void ) + FT_GlyphLoader_Rewind( FT_GlyphLoader loader ); + + /* check that there is enough space to add `n_points' and `n_contours' */ + /* to the glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckPoints( FT_GlyphLoader loader, + FT_UInt n_points, + FT_UInt n_contours ); + + +#define FT_GLYPHLOADER_CHECK_P( _loader, _count ) \ + ( (_count) == 0 || (int)((_loader)->base.outline.n_points + \ + (_loader)->current.outline.n_points + \ + (_count)) <= (int)(_loader)->max_points ) + +#define FT_GLYPHLOADER_CHECK_C( _loader, _count ) \ + ( (_count) == 0 || (int)((_loader)->base.outline.n_contours + \ + (_loader)->current.outline.n_contours + \ + (_count)) <= (int)(_loader)->max_contours ) + +#define FT_GLYPHLOADER_CHECK_POINTS( _loader, _points,_contours ) \ + ( ( FT_GLYPHLOADER_CHECK_P( _loader, _points ) && \ + FT_GLYPHLOADER_CHECK_C( _loader, _contours ) ) \ + ? 0 \ + : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) ) + + + /* check that there is enough space to add `n_subs' sub-glyphs to */ + /* a glyph loader */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CheckSubGlyphs( FT_GlyphLoader loader, + FT_UInt n_subs ); + + /* prepare a glyph loader, i.e. empty the current glyph */ + FT_BASE( void ) + FT_GlyphLoader_Prepare( FT_GlyphLoader loader ); + + /* add the current glyph to the base glyph */ + FT_BASE( void ) + FT_GlyphLoader_Add( FT_GlyphLoader loader ); + + /* copy points from one glyph loader to another */ + FT_BASE( FT_Error ) + FT_GlyphLoader_CopyPoints( FT_GlyphLoader target, + FT_GlyphLoader source ); + + /* */ + + +FT_END_HEADER + +#endif /* __FTGLOADR_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftmemory.h b/utils/openttd/freetype/internal/ftmemory.h new file mode 100644 index 00000000000..2010ca90d7e --- /dev/null +++ b/utils/openttd/freetype/internal/ftmemory.h @@ -0,0 +1,368 @@ +/***************************************************************************/ +/* */ +/* ftmemory.h */ +/* */ +/* The FreeType memory management macros (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTMEMORY_H__ +#define __FTMEMORY_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_SET_ERROR */ + /* */ + /* <Description> */ + /* This macro is used to set an implicit `error' variable to a given */ + /* expression's value (usually a function call), and convert it to a */ + /* boolean which is set whenever the value is != 0. */ + /* */ +#undef FT_SET_ERROR +#define FT_SET_ERROR( expression ) \ + ( ( error = (expression) ) != 0 ) + + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M E M O R Y ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* + * C++ refuses to handle statements like p = (void*)anything; where `p' + * is a typed pointer. Since we don't have a `typeof' operator in + * standard C++, we have to use ugly casts. + */ + +#ifdef __cplusplus +#define FT_ASSIGNP( p, val ) *((void**)&(p)) = (val) +#else +#define FT_ASSIGNP( p, val ) (p) = (val) +#endif + + + +#ifdef FT_DEBUG_MEMORY + + FT_BASE( const char* ) _ft_debug_file; + FT_BASE( long ) _ft_debug_lineno; + +#define FT_DEBUG_INNER( exp ) ( _ft_debug_file = __FILE__, \ + _ft_debug_lineno = __LINE__, \ + (exp) ) + +#define FT_ASSIGNP_INNER( p, exp ) ( _ft_debug_file = __FILE__, \ + _ft_debug_lineno = __LINE__, \ + FT_ASSIGNP( p, exp ) ) + +#else /* !FT_DEBUG_MEMORY */ + +#define FT_DEBUG_INNER( exp ) (exp) +#define FT_ASSIGNP_INNER( p, exp ) FT_ASSIGNP( p, exp ) + +#endif /* !FT_DEBUG_MEMORY */ + + + /* + * The allocation functions return a pointer, and the error code + * is written to through the `p_error' parameter. See below for + * for documentation. + */ + + FT_BASE( FT_Pointer ) + ft_mem_alloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_qalloc( FT_Memory memory, + FT_Long size, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_realloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_qrealloc( FT_Memory memory, + FT_Long item_size, + FT_Long cur_count, + FT_Long new_count, + void* block, + FT_Error *p_error ); + + FT_BASE( void ) + ft_mem_free( FT_Memory memory, + const void* P ); + + +#define FT_MEM_ALLOC( ptr, size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, (size), &error ) ) + +#define FT_MEM_FREE( ptr ) \ + FT_BEGIN_STMNT \ + ft_mem_free( memory, (ptr) ); \ + (ptr) = NULL; \ + FT_END_STMNT + +#define FT_MEM_NEW( ptr ) \ + FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) ) + +#define FT_MEM_REALLOC( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, 1, \ + (cursz), (newsz), \ + (ptr), &error ) ) + +#define FT_MEM_QALLOC( ptr, size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, (size), &error ) ) + +#define FT_MEM_QNEW( ptr ) \ + FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) ) + +#define FT_MEM_QREALLOC( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, 1, \ + (cursz), (newsz), \ + (ptr), &error ) ) + +#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ + (cursz), (newsz), \ + (ptr), &error ) ) + +#define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (item_size), \ + 0, (count), \ + NULL, &error ) ) + +#define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, (itmsz), \ + (oldcnt), (newcnt), \ + (ptr), &error ) ) + +#define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (item_size), \ + 0, (count), \ + NULL, &error ) ) + +#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, (itmsz), \ + (oldcnt), (newcnt), \ + (ptr), &error ) ) + + +#define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 ) + + +#define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) + +#define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count ) + +#define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) + + +#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) + +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) + + +#define FT_ARRAY_ZERO( dest, count ) \ + FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) ) + +#define FT_ARRAY_COPY( dest, source, count ) \ + FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) ) + +#define FT_ARRAY_MOVE( dest, source, count ) \ + FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) ) + + + /* + * Return the maximum number of addressable elements in an array. + * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid + * any problems. + */ +#define FT_ARRAY_MAX( ptr ) ( FT_INT_MAX / sizeof ( *(ptr) ) ) + +#define FT_ARRAY_CHECK( ptr, count ) ( (count) <= FT_ARRAY_MAX( ptr ) ) + + + /*************************************************************************/ + /* */ + /* The following functions macros expect that their pointer argument is */ + /* _typed_ in order to automatically compute array element sizes. */ + /* */ + +#define FT_MEM_NEW_ARRAY( ptr, count ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \ + 0, (count), \ + NULL, &error ) ) + +#define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \ + (cursz), (newsz), \ + (ptr), &error ) ) + +#define FT_MEM_QNEW_ARRAY( ptr, count ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ + 0, (count), \ + NULL, &error ) ) + +#define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ + FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ + (cursz), (newsz), \ + (ptr), &error ) ) + + +#define FT_ALLOC( ptr, size ) \ + FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) ) + +#define FT_REALLOC( ptr, cursz, newsz ) \ + FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) ) + +#define FT_ALLOC_MULT( ptr, count, item_size ) \ + FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) ) + +#define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt, \ + newcnt, itmsz ) ) + +#define FT_QALLOC( ptr, size ) \ + FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) ) + +#define FT_QREALLOC( ptr, cursz, newsz ) \ + FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) ) + +#define FT_QALLOC_MULT( ptr, count, item_size ) \ + FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) ) + +#define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ + FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt, \ + newcnt, itmsz ) ) + +#define FT_FREE( ptr ) FT_MEM_FREE( ptr ) + +#define FT_NEW( ptr ) FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) ) + +#define FT_NEW_ARRAY( ptr, count ) \ + FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) + +#define FT_RENEW_ARRAY( ptr, curcnt, newcnt ) \ + FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) + +#define FT_QNEW( ptr ) \ + FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) ) + +#define FT_QNEW_ARRAY( ptr, count ) \ + FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) + +#define FT_QRENEW_ARRAY( ptr, curcnt, newcnt ) \ + FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + FT_BASE( FT_Error ) + FT_Alloc( FT_Memory memory, + FT_Long size, + void* *P ); + + FT_BASE( FT_Error ) + FT_QAlloc( FT_Memory memory, + FT_Long size, + void* *p ); + + FT_BASE( FT_Error ) + FT_Realloc( FT_Memory memory, + FT_Long current, + FT_Long size, + void* *P ); + + FT_BASE( FT_Error ) + FT_QRealloc( FT_Memory memory, + FT_Long current, + FT_Long size, + void* *p ); + + FT_BASE( void ) + FT_Free( FT_Memory memory, + void* *P ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + FT_BASE( FT_Pointer ) + ft_mem_strdup( FT_Memory memory, + const char* str, + FT_Error *p_error ); + + FT_BASE( FT_Pointer ) + ft_mem_dup( FT_Memory memory, + const void* address, + FT_ULong size, + FT_Error *p_error ); + +#define FT_MEM_STRDUP( dst, str ) \ + (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error ) + +#define FT_STRDUP( dst, str ) \ + FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) + +#define FT_MEM_DUP( dst, address, size ) \ + (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error ) + +#define FT_DUP( dst, address, size ) \ + FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) ) + + + /* Return >= 1 if a truncation occurs. */ + /* Return 0 if the source string fits the buffer. */ + /* This is *not* the same as strlcpy(). */ + FT_BASE( FT_Int ) + ft_mem_strcpyn( char* dst, + const char* src, + FT_ULong size ); + +#define FT_STRCPYN( dst, src, size ) \ + ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) ) + + /* */ + + +FT_END_HEADER + +#endif /* __FTMEMORY_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftobjs.h b/utils/openttd/freetype/internal/ftobjs.h new file mode 100644 index 00000000000..1f22343a59c --- /dev/null +++ b/utils/openttd/freetype/internal/ftobjs.h @@ -0,0 +1,875 @@ +/***************************************************************************/ +/* */ +/* ftobjs.h */ +/* */ +/* The FreeType private base classes (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file contains the definition of all internal FreeType classes. */ + /* */ + /*************************************************************************/ + + +#ifndef __FTOBJS_H__ +#define __FTOBJS_H__ + +#include <ft2build.h> +#include FT_RENDER_H +#include FT_SIZES_H +#include FT_LCD_FILTER_H +#include FT_INTERNAL_MEMORY_H +#include FT_INTERNAL_GLYPH_LOADER_H +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_AUTOHINT_H +#include FT_INTERNAL_SERVICE_H + +#ifdef FT_CONFIG_OPTION_INCREMENTAL +#include FT_INCREMENTAL_H +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* Some generic definitions. */ + /* */ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL (void*)0 +#endif + + + /*************************************************************************/ + /* */ + /* The min and max functions missing in C. As usual, be careful not to */ + /* write things like FT_MIN( a++, b++ ) to avoid side effects. */ + /* */ +#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) +#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) + +#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) + + +#define FT_PAD_FLOOR( x, n ) ( (x) & ~((n)-1) ) +#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) +#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) + +#define FT_PIX_FLOOR( x ) ( (x) & ~63 ) +#define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) +#define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) + + + /* + * Return the highest power of 2 that is <= value; this correspond to + * the highest bit in a given 32-bit value. + */ + FT_BASE( FT_UInt32 ) + ft_highpow2( FT_UInt32 value ); + + + /* + * character classification functions -- since these are used to parse + * font files, we must not use those in <ctypes.h> which are + * locale-dependent + */ +#define ft_isdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U ) + +#define ft_isxdigit( x ) ( ( (unsigned)(x) - '0' ) < 10U || \ + ( (unsigned)(x) - 'a' ) < 6U || \ + ( (unsigned)(x) - 'A' ) < 6U ) + + /* the next two macros assume ASCII representation */ +#define ft_isupper( x ) ( ( (unsigned)(x) - 'A' ) < 26U ) +#define ft_islower( x ) ( ( (unsigned)(x) - 'a' ) < 26U ) + +#define ft_isalpha( x ) ( ft_isupper( x ) || ft_islower( x ) ) +#define ft_isalnum( x ) ( ft_isdigit( x ) || ft_isalpha( x ) ) + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** C H A R M A P S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to internal charmap object */ + typedef struct FT_CMapRec_* FT_CMap; + + /* handle to charmap class structure */ + typedef const struct FT_CMap_ClassRec_* FT_CMap_Class; + + /* internal charmap object structure */ + typedef struct FT_CMapRec_ + { + FT_CharMapRec charmap; + FT_CMap_Class clazz; + + } FT_CMapRec; + + /* typecase any pointer to a charmap handle */ +#define FT_CMAP( x ) ((FT_CMap)( x )) + + /* obvious macros */ +#define FT_CMAP_PLATFORM_ID( x ) FT_CMAP( x )->charmap.platform_id +#define FT_CMAP_ENCODING_ID( x ) FT_CMAP( x )->charmap.encoding_id +#define FT_CMAP_ENCODING( x ) FT_CMAP( x )->charmap.encoding +#define FT_CMAP_FACE( x ) FT_CMAP( x )->charmap.face + + + /* class method definitions */ + typedef FT_Error + (*FT_CMap_InitFunc)( FT_CMap cmap, + FT_Pointer init_data ); + + typedef void + (*FT_CMap_DoneFunc)( FT_CMap cmap ); + + typedef FT_UInt + (*FT_CMap_CharIndexFunc)( FT_CMap cmap, + FT_UInt32 char_code ); + + typedef FT_UInt + (*FT_CMap_CharNextFunc)( FT_CMap cmap, + FT_UInt32 *achar_code ); + + typedef FT_UInt + (*FT_CMap_CharVarIndexFunc)( FT_CMap cmap, + FT_CMap unicode_cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_Bool + (*FT_CMap_CharVarIsDefaultFunc)( FT_CMap cmap, + FT_UInt32 char_code, + FT_UInt32 variant_selector ); + + typedef FT_UInt32 * + (*FT_CMap_VariantListFunc)( FT_CMap cmap, + FT_Memory mem ); + + typedef FT_UInt32 * + (*FT_CMap_CharVariantListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 char_code ); + + typedef FT_UInt32 * + (*FT_CMap_VariantCharListFunc)( FT_CMap cmap, + FT_Memory mem, + FT_UInt32 variant_selector ); + + + typedef struct FT_CMap_ClassRec_ + { + FT_ULong size; + FT_CMap_InitFunc init; + FT_CMap_DoneFunc done; + FT_CMap_CharIndexFunc char_index; + FT_CMap_CharNextFunc char_next; + + /* Subsequent entries are special ones for format 14 -- the variant */ + /* selector subtable which behaves like no other */ + + FT_CMap_CharVarIndexFunc char_var_index; + FT_CMap_CharVarIsDefaultFunc char_var_default; + FT_CMap_VariantListFunc variant_list; + FT_CMap_CharVariantListFunc charvariant_list; + FT_CMap_VariantCharListFunc variantchar_list; + + } FT_CMap_ClassRec; + + + /* create a new charmap and add it to charmap->face */ + FT_BASE( FT_Error ) + FT_CMap_New( FT_CMap_Class clazz, + FT_Pointer init_data, + FT_CharMap charmap, + FT_CMap *acmap ); + + /* destroy a charmap and remove it from face's list */ + FT_BASE( void ) + FT_CMap_Done( FT_CMap cmap ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Face_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Face */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* max_points :: */ + /* The maximal number of points used to store the vectorial outline */ + /* of any glyph in this face. If this value cannot be known in */ + /* advance, or if the face isn't scalable, this should be set to 0. */ + /* Only relevant for scalable formats. */ + /* */ + /* max_contours :: */ + /* The maximal number of contours used to store the vectorial */ + /* outline of any glyph in this face. If this value cannot be */ + /* known in advance, or if the face isn't scalable, this should be */ + /* set to 0. Only relevant for scalable formats. */ + /* */ + /* transform_matrix :: */ + /* A 2x2 matrix of 16.16 coefficients used to transform glyph */ + /* outlines after they are loaded from the font. Only used by the */ + /* convenience functions. */ + /* */ + /* transform_delta :: */ + /* A translation vector used to transform glyph outlines after they */ + /* are loaded from the font. Only used by the convenience */ + /* functions. */ + /* */ + /* transform_flags :: */ + /* Some flags used to classify the transform. Only used by the */ + /* convenience functions. */ + /* */ + /* services :: */ + /* A cache for frequently used services. It should be only */ + /* accessed with the macro `FT_FACE_LOOKUP_SERVICE'. */ + /* */ + /* incremental_interface :: */ + /* If non-null, the interface through which glyph data and metrics */ + /* are loaded incrementally for faces that do not provide all of */ + /* this data when first opened. This field exists only if */ + /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ + /* */ + /* ignore_unpatented_hinter :: */ + /* This boolean flag instructs the glyph loader to ignore the */ + /* native font hinter, if one is found. This is exclusively used */ + /* in the case when the unpatented hinter is compiled within the */ + /* library. */ + /* */ + typedef struct FT_Face_InternalRec_ + { +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_UShort reserved1; + FT_Short reserved2; +#endif + FT_Matrix transform_matrix; + FT_Vector transform_delta; + FT_Int transform_flags; + + FT_ServiceCacheRec services; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec* incremental_interface; +#endif + + FT_Bool ignore_unpatented_hinter; + + } FT_Face_InternalRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Slot_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_GlyphSlot */ + /* object. These fields may change between different releases of */ + /* FreeType. */ + /* */ + /* <Fields> */ + /* loader :: The glyph loader object used to load outlines */ + /* into the glyph slot. */ + /* */ + /* flags :: Possible values are zero or */ + /* FT_GLYPH_OWN_BITMAP. The latter indicates */ + /* that the FT_GlyphSlot structure owns the */ + /* bitmap buffer. */ + /* */ + /* glyph_transformed :: Boolean. Set to TRUE when the loaded glyph */ + /* must be transformed through a specific */ + /* font transformation. This is _not_ the same */ + /* as the face transform set through */ + /* FT_Set_Transform(). */ + /* */ + /* glyph_matrix :: The 2x2 matrix corresponding to the glyph */ + /* transformation, if necessary. */ + /* */ + /* glyph_delta :: The 2d translation vector corresponding to */ + /* the glyph transformation, if necessary. */ + /* */ + /* glyph_hints :: Format-specific glyph hints management. */ + /* */ + +#define FT_GLYPH_OWN_BITMAP 0x1 + + typedef struct FT_Slot_InternalRec_ + { + FT_GlyphLoader loader; + FT_UInt flags; + FT_Bool glyph_transformed; + FT_Matrix glyph_matrix; + FT_Vector glyph_delta; + void* glyph_hints; + + } FT_GlyphSlot_InternalRec; + + +#if 0 + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Size_InternalRec */ + /* */ + /* <Description> */ + /* This structure contains the internal fields of each FT_Size */ + /* object. Currently, it's empty. */ + /* */ + /*************************************************************************/ + + typedef struct FT_Size_InternalRec_ + { + /* empty */ + + } FT_Size_InternalRec; + +#endif + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** M O D U L E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ModuleRec */ + /* */ + /* <Description> */ + /* A module object instance. */ + /* */ + /* <Fields> */ + /* clazz :: A pointer to the module's class. */ + /* */ + /* library :: A handle to the parent library object. */ + /* */ + /* memory :: A handle to the memory manager. */ + /* */ + /* generic :: A generic structure for user-level extensibility (?). */ + /* */ + typedef struct FT_ModuleRec_ + { + FT_Module_Class* clazz; + FT_Library library; + FT_Memory memory; + FT_Generic generic; + + } FT_ModuleRec; + + + /* typecast an object to a FT_Module */ +#define FT_MODULE( x ) ((FT_Module)( x )) +#define FT_MODULE_CLASS( x ) FT_MODULE( x )->clazz +#define FT_MODULE_LIBRARY( x ) FT_MODULE( x )->library +#define FT_MODULE_MEMORY( x ) FT_MODULE( x )->memory + + +#define FT_MODULE_IS_DRIVER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_FONT_DRIVER ) + +#define FT_MODULE_IS_RENDERER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_RENDERER ) + +#define FT_MODULE_IS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_HINTER ) + +#define FT_MODULE_IS_STYLER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_STYLER ) + +#define FT_DRIVER_IS_SCALABLE( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_SCALABLE ) + +#define FT_DRIVER_USES_OUTLINES( x ) !( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_NO_OUTLINES ) + +#define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_HAS_HINTER ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Module_Interface */ + /* */ + /* <Description> */ + /* Finds a module and returns its specific interface as a typeless */ + /* pointer. */ + /* */ + /* <Input> */ + /* library :: A handle to the library object. */ + /* */ + /* module_name :: The module's name (as an ASCII string). */ + /* */ + /* <Return> */ + /* A module-specific interface if available, 0 otherwise. */ + /* */ + /* <Note> */ + /* You should better be familiar with FreeType internals to know */ + /* which module to look for, and what its interface is :-) */ + /* */ + FT_BASE( const void* ) + FT_Get_Module_Interface( FT_Library library, + const char* mod_name ); + + FT_BASE( FT_Pointer ) + ft_module_get_service( FT_Module module, + const char* service_id ); + + /* */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** FACE, SIZE & GLYPH SLOT OBJECTS ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* a few macros used to perform easy typecasts with minimal brain damage */ + +#define FT_FACE( x ) ((FT_Face)(x)) +#define FT_SIZE( x ) ((FT_Size)(x)) +#define FT_SLOT( x ) ((FT_GlyphSlot)(x)) + +#define FT_FACE_DRIVER( x ) FT_FACE( x )->driver +#define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library +#define FT_FACE_MEMORY( x ) FT_FACE( x )->memory +#define FT_FACE_STREAM( x ) FT_FACE( x )->stream + +#define FT_SIZE_FACE( x ) FT_SIZE( x )->face +#define FT_SLOT_FACE( x ) FT_SLOT( x )->face + +#define FT_FACE_SLOT( x ) FT_FACE( x )->glyph +#define FT_FACE_SIZE( x ) FT_FACE( x )->size + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_GlyphSlot */ + /* */ + /* <Description> */ + /* It is sometimes useful to have more than one glyph slot for a */ + /* given face object. This function is used to create additional */ + /* slots. All of them are automatically discarded when the face is */ + /* destroyed. */ + /* */ + /* <Input> */ + /* face :: A handle to a parent face object. */ + /* */ + /* <Output> */ + /* aslot :: A handle to a new glyph slot object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_BASE( FT_Error ) + FT_New_GlyphSlot( FT_Face face, + FT_GlyphSlot *aslot ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_GlyphSlot */ + /* */ + /* <Description> */ + /* Destroys a given glyph slot. Remember however that all slots are */ + /* automatically destroyed with its parent. Using this function is */ + /* not always mandatory. */ + /* */ + /* <Input> */ + /* slot :: A handle to a target glyph slot. */ + /* */ + FT_BASE( void ) + FT_Done_GlyphSlot( FT_GlyphSlot slot ); + + /* */ + +#define FT_REQUEST_WIDTH( req ) \ + ( (req)->horiResolution \ + ? (FT_Pos)( (req)->width * (req)->horiResolution + 36 ) / 72 \ + : (req)->width ) + +#define FT_REQUEST_HEIGHT( req ) \ + ( (req)->vertResolution \ + ? (FT_Pos)( (req)->height * (req)->vertResolution + 36 ) / 72 \ + : (req)->height ) + + + /* Set the metrics according to a bitmap strike. */ + FT_BASE( void ) + FT_Select_Metrics( FT_Face face, + FT_ULong strike_index ); + + + /* Set the metrics according to a size request. */ + FT_BASE( void ) + FT_Request_Metrics( FT_Face face, + FT_Size_Request req ); + + + /* Match a size request against `available_sizes'. */ + FT_BASE( FT_Error ) + FT_Match_Size( FT_Face face, + FT_Size_Request req, + FT_Bool ignore_width, + FT_ULong* size_index ); + + + /* Use the horizontal metrics to synthesize the vertical metrics. */ + /* If `advance' is zero, it is also synthesized. */ + FT_BASE( void ) + ft_synthesize_vertical_metrics( FT_Glyph_Metrics* metrics, + FT_Pos advance ); + + + /* Free the bitmap of a given glyphslot when needed (i.e., only when it */ + /* was allocated with ft_glyphslot_alloc_bitmap). */ + FT_BASE( void ) + ft_glyphslot_free_bitmap( FT_GlyphSlot slot ); + + + /* Allocate a new bitmap buffer in a glyph slot. */ + FT_BASE( FT_Error ) + ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, + FT_ULong size ); + + + /* Set the bitmap buffer in a glyph slot to a given pointer. The buffer */ + /* will not be freed by a later call to ft_glyphslot_free_bitmap. */ + FT_BASE( void ) + ft_glyphslot_set_bitmap( FT_GlyphSlot slot, + FT_Byte* buffer ); + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** R E N D E R E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#define FT_RENDERER( x ) ((FT_Renderer)( x )) +#define FT_GLYPH( x ) ((FT_Glyph)( x )) +#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x )) +#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x )) + + + typedef struct FT_RendererRec_ + { + FT_ModuleRec root; + FT_Renderer_Class* clazz; + FT_Glyph_Format glyph_format; + FT_Glyph_Class glyph_class; + + FT_Raster raster; + FT_Raster_Render_Func raster_render; + FT_Renderer_RenderFunc render; + + } FT_RendererRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** F O N T D R I V E R S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* typecast a module into a driver easily */ +#define FT_DRIVER( x ) ((FT_Driver)(x)) + + /* typecast a module as a driver, and get its driver class */ +#define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_DriverRec */ + /* */ + /* <Description> */ + /* The root font driver class. A font driver is responsible for */ + /* managing and loading font files of a given format. */ + /* */ + /* <Fields> */ + /* root :: Contains the fields of the root module class. */ + /* */ + /* clazz :: A pointer to the font driver's class. Note that */ + /* this is NOT root.clazz. `class' wasn't used */ + /* as it is a reserved word in C++. */ + /* */ + /* faces_list :: The list of faces currently opened by this */ + /* driver. */ + /* */ + /* extensions :: A typeless pointer to the driver's extensions */ + /* registry, if they are supported through the */ + /* configuration macro FT_CONFIG_OPTION_EXTENSIONS. */ + /* */ + /* glyph_loader :: The glyph loader for all faces managed by this */ + /* driver. This object isn't defined for unscalable */ + /* formats. */ + /* */ + typedef struct FT_DriverRec_ + { + FT_ModuleRec root; + FT_Driver_Class clazz; + + FT_ListRec faces_list; + void* extensions; + + FT_GlyphLoader glyph_loader; + + } FT_DriverRec; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** L I B R A R I E S ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /* This hook is used by the TrueType debugger. It must be set to an */ + /* alternate truetype bytecode interpreter function. */ +#define FT_DEBUG_HOOK_TRUETYPE 0 + + + /* Set this debug hook to a non-null pointer to force unpatented hinting */ + /* for all faces when both TT_USE_BYTECODE_INTERPRETER and */ + /* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. This is only used */ + /* during debugging. */ +#define FT_DEBUG_HOOK_UNPATENTED_HINTING 1 + + + typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap, + FT_Render_Mode render_mode, + FT_Library library ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_LibraryRec */ + /* */ + /* <Description> */ + /* The FreeType library class. This is the root of all FreeType */ + /* data. Use FT_New_Library() to create a library object, and */ + /* FT_Done_Library() to discard it and all child objects. */ + /* */ + /* <Fields> */ + /* memory :: The library's memory object. Manages memory */ + /* allocation. */ + /* */ + /* generic :: Client data variable. Used to extend the */ + /* Library class by higher levels and clients. */ + /* */ + /* version_major :: The major version number of the library. */ + /* */ + /* version_minor :: The minor version number of the library. */ + /* */ + /* version_patch :: The current patch level of the library. */ + /* */ + /* num_modules :: The number of modules currently registered */ + /* within this library. This is set to 0 for new */ + /* libraries. New modules are added through the */ + /* FT_Add_Module() API function. */ + /* */ + /* modules :: A table used to store handles to the currently */ + /* registered modules. Note that each font driver */ + /* contains a list of its opened faces. */ + /* */ + /* renderers :: The list of renderers currently registered */ + /* within the library. */ + /* */ + /* cur_renderer :: The current outline renderer. This is a */ + /* shortcut used to avoid parsing the list on */ + /* each call to FT_Outline_Render(). It is a */ + /* handle to the current renderer for the */ + /* FT_GLYPH_FORMAT_OUTLINE format. */ + /* */ + /* auto_hinter :: XXX */ + /* */ + /* raster_pool :: The raster object's render pool. This can */ + /* ideally be changed dynamically at run-time. */ + /* */ + /* raster_pool_size :: The size of the render pool in bytes. */ + /* */ + /* debug_hooks :: XXX */ + /* */ + typedef struct FT_LibraryRec_ + { + FT_Memory memory; /* library's memory manager */ + + FT_Generic generic; + + FT_Int version_major; + FT_Int version_minor; + FT_Int version_patch; + + FT_UInt num_modules; + FT_Module modules[FT_MAX_MODULES]; /* module objects */ + + FT_ListRec renderers; /* list of renderers */ + FT_Renderer cur_renderer; /* current outline renderer */ + FT_Module auto_hinter; + + FT_Byte* raster_pool; /* scan-line conversion */ + /* render pool */ + FT_ULong raster_pool_size; /* size of render pool in bytes */ + + FT_DebugHook_Func debug_hooks[4]; + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + FT_LcdFilter lcd_filter; + FT_Int lcd_extra; /* number of extra pixels */ + FT_Byte lcd_weights[7]; /* filter weights, if any */ + FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ +#endif + + } FT_LibraryRec; + + + FT_BASE( FT_Renderer ) + FT_Lookup_Renderer( FT_Library library, + FT_Glyph_Format format, + FT_ListNode* node ); + + FT_BASE( FT_Error ) + FT_Render_Glyph_Internal( FT_Library library, + FT_GlyphSlot slot, + FT_Render_Mode render_mode ); + + typedef const char* + (*FT_Face_GetPostscriptNameFunc)( FT_Face face ); + + typedef FT_Error + (*FT_Face_GetGlyphNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_Face_GetGlyphNameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_New_Memory */ + /* */ + /* <Description> */ + /* Creates a new memory object. */ + /* */ + /* <Return> */ + /* A pointer to the new memory object. 0 in case of error. */ + /* */ + FT_BASE( FT_Memory ) + FT_New_Memory( void ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_Memory */ + /* */ + /* <Description> */ + /* Discards memory manager. */ + /* */ + /* <Input> */ + /* memory :: A handle to the memory manager. */ + /* */ + FT_BASE( void ) + FT_Done_Memory( FT_Memory memory ); + +#endif /* !FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* Define default raster's interface. The default raster is located in */ + /* `src/base/ftraster.c'. */ + /* */ + /* Client applications can register new rasters through the */ + /* FT_Set_Raster() API. */ + +#ifndef FT_NO_DEFAULT_RASTER + FT_EXPORT_VAR( FT_Raster_Funcs ) ft_default_raster; +#endif + + +FT_END_HEADER + +#endif /* __FTOBJS_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftrfork.h b/utils/openttd/freetype/internal/ftrfork.h new file mode 100644 index 00000000000..aa573c87054 --- /dev/null +++ b/utils/openttd/freetype/internal/ftrfork.h @@ -0,0 +1,196 @@ +/***************************************************************************/ +/* */ +/* ftrfork.h */ +/* */ +/* Embedded resource forks accessor (specification). */ +/* */ +/* Copyright 2004, 2006, 2007 by */ +/* Masatake YAMATO and Redhat K.K. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* Development of the code in this file is support of */ +/* Information-technology Promotion Agency, Japan. */ +/***************************************************************************/ + + +#ifndef __FTRFORK_H__ +#define __FTRFORK_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* Number of guessing rules supported in `FT_Raccess_Guess'. */ + /* Don't forget to increment the number if you add a new guessing rule. */ +#define FT_RACCESS_N_RULES 9 + + + /* A structure to describe a reference in a resource by its resource ID */ + /* and internal offset. The `POST' resource expects to be concatenated */ + /* by the order of resource IDs instead of its appearance in the file. */ + + typedef struct FT_RFork_Ref_ + { + FT_UShort res_id; + FT_ULong offset; + + } FT_RFork_Ref; + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Guess */ + /* */ + /* <Description> */ + /* Guess a file name and offset where the actual resource fork is */ + /* stored. The macro FT_RACCESS_N_RULES holds the number of */ + /* guessing rules; the guessed result for the Nth rule is */ + /* represented as a triplet: a new file name (new_names[N]), a file */ + /* offset (offsets[N]), and an error code (errors[N]). */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* base_name :: */ + /* The (base) file name of the resource fork used for some */ + /* guessing rules. */ + /* */ + /* <Output> */ + /* new_names :: */ + /* An array of guessed file names in which the resource forks may */ + /* exist. If `new_names[N]' is NULL, the guessed file name is */ + /* equal to `base_name'. */ + /* */ + /* offsets :: */ + /* An array of guessed file offsets. `offsets[N]' holds the file */ + /* offset of the possible start of the resource fork in file */ + /* `new_names[N]'. */ + /* */ + /* errors :: */ + /* An array of FreeType error codes. `errors[N]' is the error */ + /* code of Nth guessing rule function. If `errors[N]' is not */ + /* FT_Err_Ok, `new_names[N]' and `offsets[N]' are meaningless. */ + /* */ + FT_BASE( void ) + FT_Raccess_Guess( FT_Library library, + FT_Stream stream, + char* base_name, + char** new_names, + FT_Long* offsets, + FT_Error* errors ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_HeaderInfo */ + /* */ + /* <Description> */ + /* Get the information from the header of resource fork. The */ + /* information includes the file offset where the resource map */ + /* starts, and the file offset where the resource data starts. */ + /* `FT_Raccess_Get_DataOffsets' requires these two data. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* rfork_offset :: */ + /* The file offset where the resource fork starts. */ + /* */ + /* <Output> */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_HeaderInfo( FT_Library library, + FT_Stream stream, + FT_Long rfork_offset, + FT_Long *map_offset, + FT_Long *rdata_pos ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Raccess_Get_DataOffsets */ + /* */ + /* <Description> */ + /* Get the data offsets for a tag in a resource fork. Offsets are */ + /* stored in an array because, in some cases, resources in a resource */ + /* fork have the same tag. */ + /* */ + /* <Input> */ + /* library :: */ + /* A FreeType library instance. */ + /* */ + /* stream :: */ + /* A file stream containing the resource fork. */ + /* */ + /* map_offset :: */ + /* The file offset where the resource map starts. */ + /* */ + /* rdata_pos :: */ + /* The file offset where the resource data starts. */ + /* */ + /* tag :: */ + /* The resource tag. */ + /* */ + /* <Output> */ + /* offsets :: */ + /* The stream offsets for the resource data specified by `tag'. */ + /* This array is allocated by the function, so you have to call */ + /* @ft_mem_free after use. */ + /* */ + /* count :: */ + /* The length of offsets array. */ + /* */ + /* <Return> */ + /* FreeType error code. FT_Err_Ok means success. */ + /* */ + /* <Note> */ + /* Normally you should use `FT_Raccess_Get_HeaderInfo' to get the */ + /* value for `map_offset' and `rdata_pos'. */ + /* */ + FT_BASE( FT_Error ) + FT_Raccess_Get_DataOffsets( FT_Library library, + FT_Stream stream, + FT_Long map_offset, + FT_Long rdata_pos, + FT_Long tag, + FT_Long **offsets, + FT_Long *count ); + + +FT_END_HEADER + +#endif /* __FTRFORK_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftserv.h b/utils/openttd/freetype/internal/ftserv.h new file mode 100644 index 00000000000..2db3e8790dd --- /dev/null +++ b/utils/openttd/freetype/internal/ftserv.h @@ -0,0 +1,328 @@ +/***************************************************************************/ +/* */ +/* ftserv.h */ +/* */ +/* The FreeType services (specification only). */ +/* */ +/* Copyright 2003, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + /*************************************************************************/ + /* */ + /* Each module can export one or more `services'. Each service is */ + /* identified by a constant string and modeled by a pointer; the latter */ + /* generally corresponds to a structure containing function pointers. */ + /* */ + /* Note that a service's data cannot be a mere function pointer because */ + /* in C it is possible that function pointers might be implemented */ + /* differently than data pointers (e.g. 48 bits instead of 32). */ + /* */ + /*************************************************************************/ + + +#ifndef __FTSERV_H__ +#define __FTSERV_H__ + + +FT_BEGIN_HEADER + +#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ + + /* we disable the warning `conditional expression is constant' here */ + /* in order to compile cleanly with the maximum level of warnings */ +#pragma warning( disable : 4127 ) + +#endif /* _MSC_VER */ + + /* + * @macro: + * FT_FACE_FIND_SERVICE + * + * @description: + * This macro is used to look up a service from a face's driver module. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#ifdef __cplusplus + +#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_ = NULL; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + if ( module->clazz->get_interface ) \ + _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ + *_pptr_ = _tmp_; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_FIND_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_ = NULL; \ + \ + if ( module->clazz->get_interface ) \ + _tmp_ = module->clazz->get_interface( module, FT_SERVICE_ID_ ## id ); \ + ptr = _tmp_; \ + FT_END_STMNT + +#endif /* !C++ */ + + /* + * @macro: + * FT_FACE_FIND_GLOBAL_SERVICE + * + * @description: + * This macro is used to look up a service from all modules. + * + * @input: + * face :: + * The source face handle. + * + * id :: + * A string describing the service as defined in the service's + * header files (e.g. FT_SERVICE_ID_MULTI_MASTERS which expands to + * `multi-masters'). It is automatically prefixed with + * `FT_SERVICE_ID_'. + * + * @output: + * ptr :: + * A variable that receives the service pointer. Will be NULL + * if not found. + */ +#ifdef __cplusplus + +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ + *_pptr_ = _tmp_; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ + ptr = _tmp_; \ + FT_END_STMNT + +#endif /* !C++ */ + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E D E S C R I P T O R S *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * The following structure is used to _describe_ a given service + * to the library. This is useful to build simple static service lists. + */ + typedef struct FT_ServiceDescRec_ + { + const char* serv_id; /* service name */ + const void* serv_data; /* service pointer/data */ + + } FT_ServiceDescRec; + + typedef const FT_ServiceDescRec* FT_ServiceDesc; + + + /* + * Parse a list of FT_ServiceDescRec descriptors and look for + * a specific service by ID. Note that the last element in the + * array must be { NULL, NULL }, and that the function should + * return NULL if the service isn't available. + * + * This function can be used by modules to implement their + * `get_service' method. + */ + FT_BASE( FT_Pointer ) + ft_service_list_lookup( FT_ServiceDesc service_descriptors, + const char* service_id ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** S E R V I C E S C A C H E *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * This structure is used to store a cache for several frequently used + * services. It is the type of `face->internal->services'. You + * should only use FT_FACE_LOOKUP_SERVICE to access it. + * + * All fields should have the type FT_Pointer to relax compilation + * dependencies. We assume the developer isn't completely stupid. + * + * Each field must be named `service_XXXX' where `XXX' corresponds to + * the correct FT_SERVICE_ID_XXXX macro. See the definition of + * FT_FACE_LOOKUP_SERVICE below how this is implemented. + * + */ + typedef struct FT_ServiceCacheRec_ + { + FT_Pointer service_POSTSCRIPT_FONT_NAME; + FT_Pointer service_MULTI_MASTERS; + FT_Pointer service_GLYPH_DICT; + FT_Pointer service_PFR_METRICS; + FT_Pointer service_WINFNT; + + } FT_ServiceCacheRec, *FT_ServiceCache; + + + /* + * A magic number used within the services cache. + */ +#define FT_SERVICE_UNAVAILABLE ((FT_Pointer)-2) /* magic number */ + + + /* + * @macro: + * FT_FACE_LOOKUP_SERVICE + * + * @description: + * This macro is used to lookup a service from a face's driver module + * using its cache. + * + * @input: + * face:: + * The source face handle containing the cache. + * + * field :: + * The field name in the cache. + * + * id :: + * The service ID. + * + * @output: + * ptr :: + * A variable receiving the service data. NULL if not available. + */ +#ifdef __cplusplus + +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Pointer svc; \ + FT_Pointer* Pptr = (FT_Pointer*)&(ptr); \ + \ + \ + svc = FT_FACE( face )->internal->services. service_ ## id; \ + if ( svc == FT_SERVICE_UNAVAILABLE ) \ + svc = NULL; \ + else if ( svc == NULL ) \ + { \ + FT_FACE_FIND_SERVICE( face, svc, id ); \ + \ + FT_FACE( face )->internal->services. service_ ## id = \ + (FT_Pointer)( svc != NULL ? svc \ + : FT_SERVICE_UNAVAILABLE ); \ + } \ + *Pptr = svc; \ + FT_END_STMNT + +#else /* !C++ */ + +#define FT_FACE_LOOKUP_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Pointer svc; \ + \ + \ + svc = FT_FACE( face )->internal->services. service_ ## id; \ + if ( svc == FT_SERVICE_UNAVAILABLE ) \ + svc = NULL; \ + else if ( svc == NULL ) \ + { \ + FT_FACE_FIND_SERVICE( face, svc, id ); \ + \ + FT_FACE( face )->internal->services. service_ ## id = \ + (FT_Pointer)( svc != NULL ? svc \ + : FT_SERVICE_UNAVAILABLE ); \ + } \ + ptr = svc; \ + FT_END_STMNT + +#endif /* !C++ */ + + /* + * A macro used to define new service structure types. + */ + +#define FT_DEFINE_SERVICE( name ) \ + typedef struct FT_Service_ ## name ## Rec_ \ + FT_Service_ ## name ## Rec ; \ + typedef struct FT_Service_ ## name ## Rec_ \ + const * FT_Service_ ## name ; \ + struct FT_Service_ ## name ## Rec_ + + /* */ + + /* + * The header files containing the services. + */ + +#define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> +#define FT_SERVICE_CID_H <freetype/internal/services/svcid.h> +#define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> +#define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h> +#define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h> +#define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h> +#define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h> +#define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h> +#define FT_SERVICE_POSTSCRIPT_CMAPS_H <freetype/internal/services/svpscmap.h> +#define FT_SERVICE_POSTSCRIPT_INFO_H <freetype/internal/services/svpsinfo.h> +#define FT_SERVICE_POSTSCRIPT_NAME_H <freetype/internal/services/svpostnm.h> +#define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h> +#define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h> +#define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> +#define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> +#define FT_SERVICE_XFREE86_NAME_H <freetype/internal/services/svxf86nm.h> +#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h> + + /* */ + +FT_END_HEADER + +#endif /* __FTSERV_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftstream.h b/utils/openttd/freetype/internal/ftstream.h new file mode 100644 index 00000000000..a91eb72d968 --- /dev/null +++ b/utils/openttd/freetype/internal/ftstream.h @@ -0,0 +1,539 @@ +/***************************************************************************/ +/* */ +/* ftstream.h */ +/* */ +/* Stream handling (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTSTREAM_H__ +#define __FTSTREAM_H__ + + +#include <ft2build.h> +#include FT_SYSTEM_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /* format of an 8-bit frame_op value: */ + /* */ + /* bit 76543210 */ + /* xxxxxxes */ + /* */ + /* s is set to 1 if the value is signed. */ + /* e is set to 1 if the value is little-endian. */ + /* xxx is a command. */ + +#define FT_FRAME_OP_SHIFT 2 +#define FT_FRAME_OP_SIGNED 1 +#define FT_FRAME_OP_LITTLE 2 +#define FT_FRAME_OP_COMMAND( x ) ( x >> FT_FRAME_OP_SHIFT ) + +#define FT_MAKE_FRAME_OP( command, little, sign ) \ + ( ( command << FT_FRAME_OP_SHIFT ) | ( little << 1 ) | sign ) + +#define FT_FRAME_OP_END 0 +#define FT_FRAME_OP_START 1 /* start a new frame */ +#define FT_FRAME_OP_BYTE 2 /* read 1-byte value */ +#define FT_FRAME_OP_SHORT 3 /* read 2-byte value */ +#define FT_FRAME_OP_LONG 4 /* read 4-byte value */ +#define FT_FRAME_OP_OFF3 5 /* read 3-byte value */ +#define FT_FRAME_OP_BYTES 6 /* read a bytes sequence */ + + + typedef enum FT_Frame_Op_ + { + ft_frame_end = 0, + ft_frame_start = FT_MAKE_FRAME_OP( FT_FRAME_OP_START, 0, 0 ), + + ft_frame_byte = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 0 ), + ft_frame_schar = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTE, 0, 1 ), + + ft_frame_ushort_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 0 ), + ft_frame_short_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 0, 1 ), + ft_frame_ushort_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 0 ), + ft_frame_short_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_SHORT, 1, 1 ), + + ft_frame_ulong_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 0 ), + ft_frame_long_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 0, 1 ), + ft_frame_ulong_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 0 ), + ft_frame_long_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_LONG, 1, 1 ), + + ft_frame_uoff3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 0 ), + ft_frame_off3_be = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 0, 1 ), + ft_frame_uoff3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 0 ), + ft_frame_off3_le = FT_MAKE_FRAME_OP( FT_FRAME_OP_OFF3, 1, 1 ), + + ft_frame_bytes = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 0 ), + ft_frame_skip = FT_MAKE_FRAME_OP( FT_FRAME_OP_BYTES, 0, 1 ) + + } FT_Frame_Op; + + + typedef struct FT_Frame_Field_ + { + FT_Byte value; + FT_Byte size; + FT_UShort offset; + + } FT_Frame_Field; + + + /* Construct an FT_Frame_Field out of a structure type and a field name. */ + /* The structure type must be set in the FT_STRUCTURE macro before */ + /* calling the FT_FRAME_START() macro. */ + /* */ +#define FT_FIELD_SIZE( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f ) + +#define FT_FIELD_SIZE_DELTA( f ) \ + (FT_Byte)sizeof ( ((FT_STRUCTURE*)0)->f[0] ) + +#define FT_FIELD_OFFSET( f ) \ + (FT_UShort)( offsetof( FT_STRUCTURE, f ) ) + +#define FT_FRAME_FIELD( frame_op, field ) \ + { \ + frame_op, \ + FT_FIELD_SIZE( field ), \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_MAKE_EMPTY_FIELD( frame_op ) { frame_op, 0, 0 } + +#define FT_FRAME_START( size ) { ft_frame_start, 0, size } +#define FT_FRAME_END { ft_frame_end, 0, 0 } + +#define FT_FRAME_LONG( f ) FT_FRAME_FIELD( ft_frame_long_be, f ) +#define FT_FRAME_ULONG( f ) FT_FRAME_FIELD( ft_frame_ulong_be, f ) +#define FT_FRAME_SHORT( f ) FT_FRAME_FIELD( ft_frame_short_be, f ) +#define FT_FRAME_USHORT( f ) FT_FRAME_FIELD( ft_frame_ushort_be, f ) +#define FT_FRAME_OFF3( f ) FT_FRAME_FIELD( ft_frame_off3_be, f ) +#define FT_FRAME_UOFF3( f ) FT_FRAME_FIELD( ft_frame_uoff3_be, f ) +#define FT_FRAME_BYTE( f ) FT_FRAME_FIELD( ft_frame_byte, f ) +#define FT_FRAME_CHAR( f ) FT_FRAME_FIELD( ft_frame_schar, f ) + +#define FT_FRAME_LONG_LE( f ) FT_FRAME_FIELD( ft_frame_long_le, f ) +#define FT_FRAME_ULONG_LE( f ) FT_FRAME_FIELD( ft_frame_ulong_le, f ) +#define FT_FRAME_SHORT_LE( f ) FT_FRAME_FIELD( ft_frame_short_le, f ) +#define FT_FRAME_USHORT_LE( f ) FT_FRAME_FIELD( ft_frame_ushort_le, f ) +#define FT_FRAME_OFF3_LE( f ) FT_FRAME_FIELD( ft_frame_off3_le, f ) +#define FT_FRAME_UOFF3_LE( f ) FT_FRAME_FIELD( ft_frame_uoff3_le, f ) + +#define FT_FRAME_SKIP_LONG { ft_frame_long_be, 0, 0 } +#define FT_FRAME_SKIP_SHORT { ft_frame_short_be, 0, 0 } +#define FT_FRAME_SKIP_BYTE { ft_frame_byte, 0, 0 } + +#define FT_FRAME_BYTES( field, count ) \ + { \ + ft_frame_bytes, \ + count, \ + FT_FIELD_OFFSET( field ) \ + } + +#define FT_FRAME_SKIP_BYTES( count ) { ft_frame_skip, count, 0 } + + + /*************************************************************************/ + /* */ + /* Integer extraction macros -- the `buffer' parameter must ALWAYS be of */ + /* type `char*' or equivalent (1-byte elements). */ + /* */ + +#define FT_BYTE_( p, i ) ( ((const FT_Byte*)(p))[(i)] ) +#define FT_INT8_( p, i ) ( ((const FT_Char*)(p))[(i)] ) + +#define FT_INT16( x ) ( (FT_Int16)(x) ) +#define FT_UINT16( x ) ( (FT_UInt16)(x) ) +#define FT_INT32( x ) ( (FT_Int32)(x) ) +#define FT_UINT32( x ) ( (FT_UInt32)(x) ) + +#define FT_BYTE_I16( p, i, s ) ( FT_INT16( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_U16( p, i, s ) ( FT_UINT16( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_I32( p, i, s ) ( FT_INT32( FT_BYTE_( p, i ) ) << (s) ) +#define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) ) + +#define FT_INT8_I16( p, i, s ) ( FT_INT16( FT_INT8_( p, i ) ) << (s) ) +#define FT_INT8_U16( p, i, s ) ( FT_UINT16( FT_INT8_( p, i ) ) << (s) ) +#define FT_INT8_I32( p, i, s ) ( FT_INT32( FT_INT8_( p, i ) ) << (s) ) +#define FT_INT8_U32( p, i, s ) ( FT_UINT32( FT_INT8_( p, i ) ) << (s) ) + + +#define FT_PEEK_SHORT( p ) FT_INT16( FT_INT8_I16( p, 0, 8) | \ + FT_BYTE_I16( p, 1, 0) ) + +#define FT_PEEK_USHORT( p ) FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \ + FT_BYTE_U16( p, 1, 0 ) ) + +#define FT_PEEK_LONG( p ) FT_INT32( FT_INT8_I32( p, 0, 24 ) | \ + FT_BYTE_I32( p, 1, 16 ) | \ + FT_BYTE_I32( p, 2, 8 ) | \ + FT_BYTE_I32( p, 3, 0 ) ) + +#define FT_PEEK_ULONG( p ) FT_UINT32( FT_BYTE_U32( p, 0, 24 ) | \ + FT_BYTE_U32( p, 1, 16 ) | \ + FT_BYTE_U32( p, 2, 8 ) | \ + FT_BYTE_U32( p, 3, 0 ) ) + +#define FT_PEEK_OFF3( p ) FT_INT32( FT_INT8_I32( p, 0, 16 ) | \ + FT_BYTE_I32( p, 1, 8 ) | \ + FT_BYTE_I32( p, 2, 0 ) ) + +#define FT_PEEK_UOFF3( p ) FT_UINT32( FT_BYTE_U32( p, 0, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 2, 0 ) ) + +#define FT_PEEK_SHORT_LE( p ) FT_INT16( FT_INT8_I16( p, 1, 8 ) | \ + FT_BYTE_I16( p, 0, 0 ) ) + +#define FT_PEEK_USHORT_LE( p ) FT_UINT16( FT_BYTE_U16( p, 1, 8 ) | \ + FT_BYTE_U16( p, 0, 0 ) ) + +#define FT_PEEK_LONG_LE( p ) FT_INT32( FT_INT8_I32( p, 3, 24 ) | \ + FT_BYTE_I32( p, 2, 16 ) | \ + FT_BYTE_I32( p, 1, 8 ) | \ + FT_BYTE_I32( p, 0, 0 ) ) + +#define FT_PEEK_ULONG_LE( p ) FT_UINT32( FT_BYTE_U32( p, 3, 24 ) | \ + FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + +#define FT_PEEK_OFF3_LE( p ) FT_INT32( FT_INT8_I32( p, 2, 16 ) | \ + FT_BYTE_I32( p, 1, 8 ) | \ + FT_BYTE_I32( p, 0, 0 ) ) + +#define FT_PEEK_UOFF3_LE( p ) FT_UINT32( FT_BYTE_U32( p, 2, 16 ) | \ + FT_BYTE_U32( p, 1, 8 ) | \ + FT_BYTE_U32( p, 0, 0 ) ) + + +#define FT_NEXT_CHAR( buffer ) \ + ( (signed char)*buffer++ ) + +#define FT_NEXT_BYTE( buffer ) \ + ( (unsigned char)*buffer++ ) + +#define FT_NEXT_SHORT( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) ) + +#define FT_NEXT_LONG( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) ) + + +#define FT_NEXT_SHORT_LE( buffer ) \ + ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_USHORT_LE( buffer ) \ + ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) ) + +#define FT_NEXT_OFF3_LE( buffer ) \ + ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_UOFF3_LE( buffer ) \ + ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) ) + +#define FT_NEXT_LONG_LE( buffer ) \ + ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) ) + +#define FT_NEXT_ULONG_LE( buffer ) \ + ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) ) + + + /*************************************************************************/ + /* */ + /* Each GET_xxxx() macro uses an implicit `stream' variable. */ + /* */ +#if 0 +#define FT_GET_MACRO( type ) FT_NEXT_ ## type ( stream->cursor ) + +#define FT_GET_CHAR() FT_GET_MACRO( CHAR ) +#define FT_GET_BYTE() FT_GET_MACRO( BYTE ) +#define FT_GET_SHORT() FT_GET_MACRO( SHORT ) +#define FT_GET_USHORT() FT_GET_MACRO( USHORT ) +#define FT_GET_OFF3() FT_GET_MACRO( OFF3 ) +#define FT_GET_UOFF3() FT_GET_MACRO( UOFF3 ) +#define FT_GET_LONG() FT_GET_MACRO( LONG ) +#define FT_GET_ULONG() FT_GET_MACRO( ULONG ) +#define FT_GET_TAG4() FT_GET_MACRO( ULONG ) + +#define FT_GET_SHORT_LE() FT_GET_MACRO( SHORT_LE ) +#define FT_GET_USHORT_LE() FT_GET_MACRO( USHORT_LE ) +#define FT_GET_LONG_LE() FT_GET_MACRO( LONG_LE ) +#define FT_GET_ULONG_LE() FT_GET_MACRO( ULONG_LE ) + +#else +#define FT_GET_MACRO( func, type ) ( (type)func( stream ) ) + +#define FT_GET_CHAR() FT_GET_MACRO( FT_Stream_GetChar, FT_Char ) +#define FT_GET_BYTE() FT_GET_MACRO( FT_Stream_GetChar, FT_Byte ) +#define FT_GET_SHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_Short ) +#define FT_GET_USHORT() FT_GET_MACRO( FT_Stream_GetShort, FT_UShort ) +#define FT_GET_OFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_Long ) +#define FT_GET_UOFF3() FT_GET_MACRO( FT_Stream_GetOffset, FT_ULong ) +#define FT_GET_LONG() FT_GET_MACRO( FT_Stream_GetLong, FT_Long ) +#define FT_GET_ULONG() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong ) +#define FT_GET_TAG4() FT_GET_MACRO( FT_Stream_GetLong, FT_ULong ) + +#define FT_GET_SHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_Short ) +#define FT_GET_USHORT_LE() FT_GET_MACRO( FT_Stream_GetShortLE, FT_UShort ) +#define FT_GET_LONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_Long ) +#define FT_GET_ULONG_LE() FT_GET_MACRO( FT_Stream_GetLongLE, FT_ULong ) +#endif + +#define FT_READ_MACRO( func, type, var ) \ + ( var = (type)func( stream, &error ), \ + error != FT_Err_Ok ) + +#define FT_READ_BYTE( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, var ) +#define FT_READ_CHAR( var ) FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, var ) +#define FT_READ_SHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_Short, var ) +#define FT_READ_USHORT( var ) FT_READ_MACRO( FT_Stream_ReadShort, FT_UShort, var ) +#define FT_READ_OFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_Long, var ) +#define FT_READ_UOFF3( var ) FT_READ_MACRO( FT_Stream_ReadOffset, FT_ULong, var ) +#define FT_READ_LONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_Long, var ) +#define FT_READ_ULONG( var ) FT_READ_MACRO( FT_Stream_ReadLong, FT_ULong, var ) + +#define FT_READ_SHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_Short, var ) +#define FT_READ_USHORT_LE( var ) FT_READ_MACRO( FT_Stream_ReadShortLE, FT_UShort, var ) +#define FT_READ_LONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_Long, var ) +#define FT_READ_ULONG_LE( var ) FT_READ_MACRO( FT_Stream_ReadLongLE, FT_ULong, var ) + + +#ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM + + /* initialize a stream for reading a regular system stream */ + FT_BASE( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ); + +#endif /* FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM */ + + + /* create a new (input) stream from an FT_Open_Args structure */ + FT_BASE( FT_Error ) + FT_Stream_New( FT_Library library, + const FT_Open_Args* args, + FT_Stream *astream ); + + /* free a stream */ + FT_BASE( void ) + FT_Stream_Free( FT_Stream stream, + FT_Int external ); + + /* initialize a stream for reading in-memory data */ + FT_BASE( void ) + FT_Stream_OpenMemory( FT_Stream stream, + const FT_Byte* base, + FT_ULong size ); + + /* close a stream (does not destroy the stream structure) */ + FT_BASE( void ) + FT_Stream_Close( FT_Stream stream ); + + + /* seek within a stream. position is relative to start of stream */ + FT_BASE( FT_Error ) + FT_Stream_Seek( FT_Stream stream, + FT_ULong pos ); + + /* skip bytes in a stream */ + FT_BASE( FT_Error ) + FT_Stream_Skip( FT_Stream stream, + FT_Long distance ); + + /* return current stream position */ + FT_BASE( FT_Long ) + FT_Stream_Pos( FT_Stream stream ); + + /* read bytes from a stream into a user-allocated buffer, returns an */ + /* error if not all bytes could be read. */ + FT_BASE( FT_Error ) + FT_Stream_Read( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + + /* read bytes from a stream at a given position */ + FT_BASE( FT_Error ) + FT_Stream_ReadAt( FT_Stream stream, + FT_ULong pos, + FT_Byte* buffer, + FT_ULong count ); + + /* try to read bytes at the end of a stream; return number of bytes */ + /* really available */ + FT_BASE( FT_ULong ) + FT_Stream_TryRead( FT_Stream stream, + FT_Byte* buffer, + FT_ULong count ); + + /* Enter a frame of `count' consecutive bytes in a stream. Returns an */ + /* error if the frame could not be read/accessed. The caller can use */ + /* the FT_Stream_Get_XXX functions to retrieve frame data without */ + /* error checks. */ + /* */ + /* You must _always_ call FT_Stream_ExitFrame() once you have entered */ + /* a stream frame! */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_EnterFrame( FT_Stream stream, + FT_ULong count ); + + /* exit a stream frame */ + FT_BASE( void ) + FT_Stream_ExitFrame( FT_Stream stream ); + + /* Extract a stream frame. If the stream is disk-based, a heap block */ + /* is allocated and the frame bytes are read into it. If the stream */ + /* is memory-based, this function simply set a pointer to the data. */ + /* */ + /* Useful to optimize access to memory-based streams transparently. */ + /* */ + /* All extracted frames must be `freed' with a call to the function */ + /* FT_Stream_ReleaseFrame(). */ + /* */ + FT_BASE( FT_Error ) + FT_Stream_ExtractFrame( FT_Stream stream, + FT_ULong count, + FT_Byte** pbytes ); + + /* release an extract frame (see FT_Stream_ExtractFrame) */ + FT_BASE( void ) + FT_Stream_ReleaseFrame( FT_Stream stream, + FT_Byte** pbytes ); + + /* read a byte from an entered frame */ + FT_BASE( FT_Char ) + FT_Stream_GetChar( FT_Stream stream ); + + /* read a 16-bit big-endian integer from an entered frame */ + FT_BASE( FT_Short ) + FT_Stream_GetShort( FT_Stream stream ); + + /* read a 24-bit big-endian integer from an entered frame */ + FT_BASE( FT_Long ) + FT_Stream_GetOffset( FT_Stream stream ); + + /* read a 32-bit big-endian integer from an entered frame */ + FT_BASE( FT_Long ) + FT_Stream_GetLong( FT_Stream stream ); + + /* read a 16-bit little-endian integer from an entered frame */ + FT_BASE( FT_Short ) + FT_Stream_GetShortLE( FT_Stream stream ); + + /* read a 32-bit little-endian integer from an entered frame */ + FT_BASE( FT_Long ) + FT_Stream_GetLongLE( FT_Stream stream ); + + + /* read a byte from a stream */ + FT_BASE( FT_Char ) + FT_Stream_ReadChar( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit big-endian integer from a stream */ + FT_BASE( FT_Short ) + FT_Stream_ReadShort( FT_Stream stream, + FT_Error* error ); + + /* read a 24-bit big-endian integer from a stream */ + FT_BASE( FT_Long ) + FT_Stream_ReadOffset( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit big-endian integer from a stream */ + FT_BASE( FT_Long ) + FT_Stream_ReadLong( FT_Stream stream, + FT_Error* error ); + + /* read a 16-bit little-endian integer from a stream */ + FT_BASE( FT_Short ) + FT_Stream_ReadShortLE( FT_Stream stream, + FT_Error* error ); + + /* read a 32-bit little-endian integer from a stream */ + FT_BASE( FT_Long ) + FT_Stream_ReadLongLE( FT_Stream stream, + FT_Error* error ); + + /* Read a structure from a stream. The structure must be described */ + /* by an array of FT_Frame_Field records. */ + FT_BASE( FT_Error ) + FT_Stream_ReadFields( FT_Stream stream, + const FT_Frame_Field* fields, + void* structure ); + + +#define FT_STREAM_POS() \ + FT_Stream_Pos( stream ) + +#define FT_STREAM_SEEK( position ) \ + FT_SET_ERROR( FT_Stream_Seek( stream, position ) ) + +#define FT_STREAM_SKIP( distance ) \ + FT_SET_ERROR( FT_Stream_Skip( stream, distance ) ) + +#define FT_STREAM_READ( buffer, count ) \ + FT_SET_ERROR( FT_Stream_Read( stream, \ + (FT_Byte*)buffer, \ + count ) ) + +#define FT_STREAM_READ_AT( position, buffer, count ) \ + FT_SET_ERROR( FT_Stream_ReadAt( stream, \ + position, \ + (FT_Byte*)buffer, \ + count ) ) + +#define FT_STREAM_READ_FIELDS( fields, object ) \ + FT_SET_ERROR( FT_Stream_ReadFields( stream, fields, object ) ) + + +#define FT_FRAME_ENTER( size ) \ + FT_SET_ERROR( \ + FT_DEBUG_INNER( FT_Stream_EnterFrame( stream, size ) ) ) + +#define FT_FRAME_EXIT() \ + FT_DEBUG_INNER( FT_Stream_ExitFrame( stream ) ) + +#define FT_FRAME_EXTRACT( size, bytes ) \ + FT_SET_ERROR( \ + FT_DEBUG_INNER( FT_Stream_ExtractFrame( stream, size, \ + (FT_Byte**)&(bytes) ) ) ) + +#define FT_FRAME_RELEASE( bytes ) \ + FT_DEBUG_INNER( FT_Stream_ReleaseFrame( stream, \ + (FT_Byte**)&(bytes) ) ) + + +FT_END_HEADER + +#endif /* __FTSTREAM_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/fttrace.h b/utils/openttd/freetype/internal/fttrace.h new file mode 100644 index 00000000000..4d38a4628a7 --- /dev/null +++ b/utils/openttd/freetype/internal/fttrace.h @@ -0,0 +1,134 @@ +/***************************************************************************/ +/* */ +/* fttrace.h */ +/* */ +/* Tracing handling (specification only). */ +/* */ +/* Copyright 2002, 2004, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /* definitions of trace levels for FreeType 2 */ + + /* the first level must always be `trace_any' */ +FT_TRACE_DEF( any ) + + /* base components */ +FT_TRACE_DEF( calc ) /* calculations (ftcalc.c) */ +FT_TRACE_DEF( memory ) /* memory manager (ftobjs.c) */ +FT_TRACE_DEF( stream ) /* stream manager (ftstream.c) */ +FT_TRACE_DEF( io ) /* i/o interface (ftsystem.c) */ +FT_TRACE_DEF( list ) /* list management (ftlist.c) */ +FT_TRACE_DEF( init ) /* initialization (ftinit.c) */ +FT_TRACE_DEF( objs ) /* base objects (ftobjs.c) */ +FT_TRACE_DEF( outline ) /* outline management (ftoutln.c) */ +FT_TRACE_DEF( glyph ) /* glyph management (ftglyph.c) */ + +FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ +FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ +FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ +FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ + + /* Cache sub-system */ +FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ + + /* SFNT driver components */ +FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ +FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ +FT_TRACE_DEF( ttkern ) /* kerning handler (ttkern.c) */ +FT_TRACE_DEF( ttload ) /* basic TrueType tables (ttload.c) */ +FT_TRACE_DEF( ttmtx ) /* metrics-related tables (ttmtx.c) */ +FT_TRACE_DEF( ttpost ) /* PS table processing (ttpost.c) */ +FT_TRACE_DEF( ttsbit ) /* TrueType sbit handling (ttsbit.c) */ + + /* TrueType driver components */ +FT_TRACE_DEF( ttdriver ) /* TT font driver (ttdriver.c) */ +FT_TRACE_DEF( ttgload ) /* TT glyph loader (ttgload.c) */ +FT_TRACE_DEF( ttinterp ) /* bytecode interpreter (ttinterp.c) */ +FT_TRACE_DEF( ttobjs ) /* TT objects manager (ttobjs.c) */ +FT_TRACE_DEF( ttpload ) /* TT data/program loader (ttpload.c) */ +FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ + + /* Type 1 driver components */ +FT_TRACE_DEF( t1driver ) +FT_TRACE_DEF( t1gload ) +FT_TRACE_DEF( t1hint ) +FT_TRACE_DEF( t1load ) +FT_TRACE_DEF( t1objs ) +FT_TRACE_DEF( t1parse ) + + /* PostScript helper module `psaux' */ +FT_TRACE_DEF( t1decode ) +FT_TRACE_DEF( psobjs ) + + /* PostScript hinting module `pshinter' */ +FT_TRACE_DEF( pshrec ) +FT_TRACE_DEF( pshalgo1 ) +FT_TRACE_DEF( pshalgo2 ) + + /* Type 2 driver components */ +FT_TRACE_DEF( cffdriver ) +FT_TRACE_DEF( cffgload ) +FT_TRACE_DEF( cffload ) +FT_TRACE_DEF( cffobjs ) +FT_TRACE_DEF( cffparse ) + + /* Type 42 driver component */ +FT_TRACE_DEF( t42 ) + + /* CID driver components */ +FT_TRACE_DEF( cidafm ) +FT_TRACE_DEF( ciddriver ) +FT_TRACE_DEF( cidgload ) +FT_TRACE_DEF( cidload ) +FT_TRACE_DEF( cidobjs ) +FT_TRACE_DEF( cidparse ) + + /* Windows font component */ +FT_TRACE_DEF( winfnt ) + + /* PCF font components */ +FT_TRACE_DEF( pcfdriver ) +FT_TRACE_DEF( pcfread ) + + /* BDF font components */ +FT_TRACE_DEF( bdfdriver ) +FT_TRACE_DEF( bdflib ) + + /* PFR font component */ +FT_TRACE_DEF( pfr ) + + /* OpenType validation components */ +FT_TRACE_DEF( otvmodule ) +FT_TRACE_DEF( otvcommon ) +FT_TRACE_DEF( otvbase ) +FT_TRACE_DEF( otvgdef ) +FT_TRACE_DEF( otvgpos ) +FT_TRACE_DEF( otvgsub ) +FT_TRACE_DEF( otvjstf ) +FT_TRACE_DEF( otvmath ) + + /* TrueTypeGX/AAT validation components */ +FT_TRACE_DEF( gxvmodule ) +FT_TRACE_DEF( gxvcommon ) +FT_TRACE_DEF( gxvfeat ) +FT_TRACE_DEF( gxvmort ) +FT_TRACE_DEF( gxvmorx ) +FT_TRACE_DEF( gxvbsln ) +FT_TRACE_DEF( gxvjust ) +FT_TRACE_DEF( gxvkern ) +FT_TRACE_DEF( gxvopbd ) +FT_TRACE_DEF( gxvtrak ) +FT_TRACE_DEF( gxvprop ) +FT_TRACE_DEF( gxvlcar ) + + +/* END */ diff --git a/utils/openttd/freetype/internal/ftvalid.h b/utils/openttd/freetype/internal/ftvalid.h new file mode 100644 index 00000000000..00cd85e7bb6 --- /dev/null +++ b/utils/openttd/freetype/internal/ftvalid.h @@ -0,0 +1,150 @@ +/***************************************************************************/ +/* */ +/* ftvalid.h */ +/* */ +/* FreeType validation support (specification). */ +/* */ +/* Copyright 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTVALID_H__ +#define __FTVALID_H__ + +#include <ft2build.h> +#include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** ****/ + /**** V A L I D A T I O N ****/ + /**** ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* handle to a validation object */ + typedef struct FT_ValidatorRec_ volatile* FT_Validator; + + + /*************************************************************************/ + /* */ + /* There are three distinct validation levels defined here: */ + /* */ + /* FT_VALIDATE_DEFAULT :: */ + /* A table that passes this validation level can be used reliably by */ + /* FreeType. It generally means that all offsets have been checked to */ + /* prevent out-of-bound reads, that array counts are correct, etc. */ + /* */ + /* FT_VALIDATE_TIGHT :: */ + /* A table that passes this validation level can be used reliably and */ + /* doesn't contain invalid data. For example, a charmap table that */ + /* returns invalid glyph indices will not pass, even though it can */ + /* be used with FreeType in default mode (the library will simply */ + /* return an error later when trying to load the glyph). */ + /* */ + /* It also checks that fields which must be a multiple of 2, 4, or 8, */ + /* don't have incorrect values, etc. */ + /* */ + /* FT_VALIDATE_PARANOID :: */ + /* Only for font debugging. Checks that a table follows the */ + /* specification by 100%. Very few fonts will be able to pass this */ + /* level anyway but it can be useful for certain tools like font */ + /* editors/converters. */ + /* */ + typedef enum FT_ValidationLevel_ + { + FT_VALIDATE_DEFAULT = 0, + FT_VALIDATE_TIGHT, + FT_VALIDATE_PARANOID + + } FT_ValidationLevel; + + + /* validator structure */ + typedef struct FT_ValidatorRec_ + { + const FT_Byte* base; /* address of table in memory */ + const FT_Byte* limit; /* `base' + sizeof(table) in memory */ + FT_ValidationLevel level; /* validation level */ + FT_Error error; /* error returned. 0 means success */ + + ft_jmp_buf jump_buffer; /* used for exception handling */ + + } FT_ValidatorRec; + + +#define FT_VALIDATOR( x ) ((FT_Validator)( x )) + + + FT_BASE( void ) + ft_validator_init( FT_Validator valid, + const FT_Byte* base, + const FT_Byte* limit, + FT_ValidationLevel level ); + + /* Do not use this. It's broken and will cause your validator to crash */ + /* if you run it on an invalid font. */ + FT_BASE( FT_Int ) + ft_validator_run( FT_Validator valid ); + + /* Sets the error field in a validator, then calls `longjmp' to return */ + /* to high-level caller. Using `setjmp/longjmp' avoids many stupid */ + /* error checks within the validation routines. */ + /* */ + FT_BASE( void ) + ft_validator_error( FT_Validator valid, + FT_Error error ); + + + /* Calls ft_validate_error. Assumes that the `valid' local variable */ + /* holds a pointer to the current validator object. */ + /* */ + /* Use preprocessor prescan to pass FT_ERR_PREFIX. */ + /* */ +#define FT_INVALID( _prefix, _error ) FT_INVALID_( _prefix, _error ) +#define FT_INVALID_( _prefix, _error ) \ + ft_validator_error( valid, _prefix ## _error ) + + /* called when a broken table is detected */ +#define FT_INVALID_TOO_SHORT \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + + /* called when an invalid offset is detected */ +#define FT_INVALID_OFFSET \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Offset ) + + /* called when an invalid format/value is detected */ +#define FT_INVALID_FORMAT \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + + /* called when an invalid glyph index is detected */ +#define FT_INVALID_GLYPH_ID \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Glyph_Index ) + + /* called when an invalid field value is detected */ +#define FT_INVALID_DATA \ + FT_INVALID( FT_ERR_PREFIX, Invalid_Table ) + + +FT_END_HEADER + +#endif /* __FTVALID_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/internal.h b/utils/openttd/freetype/internal/internal.h new file mode 100644 index 00000000000..27d5dc585d3 --- /dev/null +++ b/utils/openttd/freetype/internal/internal.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* internal.h */ +/* */ +/* Internal header files (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file is automatically included by `ft2build.h'. */ + /* Do not include it manually! */ + /* */ + /*************************************************************************/ + + +#define FT_INTERNAL_OBJECTS_H <freetype/internal/ftobjs.h> +#define FT_INTERNAL_STREAM_H <freetype/internal/ftstream.h> +#define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> +#define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> +#define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> +#define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> +#define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> +#define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> +#define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h> +#define FT_INTERNAL_SERVICE_H <freetype/internal/ftserv.h> +#define FT_INTERNAL_RFORK_H <freetype/internal/ftrfork.h> +#define FT_INTERNAL_VALIDATE_H <freetype/internal/ftvalid.h> + +#define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h> +#define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h> + +#define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> +#define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> +#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> + +#define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> + + +/* END */ diff --git a/utils/openttd/freetype/internal/pcftypes.h b/utils/openttd/freetype/internal/pcftypes.h new file mode 100644 index 00000000000..382796ffb48 --- /dev/null +++ b/utils/openttd/freetype/internal/pcftypes.h @@ -0,0 +1,56 @@ +/* pcftypes.h + + FreeType font driver for pcf fonts + + Copyright (C) 2000, 2001, 2002 by + Francesco Zappa Nardelli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +#ifndef __PCFTYPES_H__ +#define __PCFTYPES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef struct PCF_Public_FaceRec_ + { + FT_FaceRec root; + FT_StreamRec gzip_stream; + FT_Stream gzip_source; + + char* charset_encoding; + char* charset_registry; + + } PCF_Public_FaceRec, *PCF_Public_Face; + + +FT_END_HEADER + +#endif /* __PCFTYPES_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/psaux.h b/utils/openttd/freetype/internal/psaux.h new file mode 100644 index 00000000000..67b7a420cb2 --- /dev/null +++ b/utils/openttd/freetype/internal/psaux.h @@ -0,0 +1,871 @@ +/***************************************************************************/ +/* */ +/* psaux.h */ +/* */ +/* Auxiliary functions and data structures related to PostScript fonts */ +/* (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSAUX_H__ +#define __PSAUX_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_TYPE1_TYPES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1_TABLE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct PS_TableRec_* PS_Table; + typedef const struct PS_Table_FuncsRec_* PS_Table_Funcs; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Table_FuncsRec */ + /* */ + /* <Description> */ + /* A set of function pointers to manage PS_Table objects. */ + /* */ + /* <Fields> */ + /* table_init :: Used to initialize a table. */ + /* */ + /* table_done :: Finalizes resp. destroy a given table. */ + /* */ + /* table_add :: Adds a new object to a table. */ + /* */ + /* table_release :: Releases table data, then finalizes it. */ + /* */ + typedef struct PS_Table_FuncsRec_ + { + FT_Error + (*init)( PS_Table table, + FT_Int count, + FT_Memory memory ); + + void + (*done)( PS_Table table ); + + FT_Error + (*add)( PS_Table table, + FT_Int idx, + void* object, + FT_PtrDist length ); + + void + (*release)( PS_Table table ); + + } PS_Table_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_TableRec */ + /* */ + /* <Description> */ + /* A PS_Table is a simple object used to store an array of objects in */ + /* a single memory block. */ + /* */ + /* <Fields> */ + /* block :: The address in memory of the growheap's block. This */ + /* can change between two object adds, due to */ + /* reallocation. */ + /* */ + /* cursor :: The current top of the grow heap within its block. */ + /* */ + /* capacity :: The current size of the heap block. Increments by */ + /* 1kByte chunks. */ + /* */ + /* max_elems :: The maximum number of elements in table. */ + /* */ + /* num_elems :: The current number of elements in table. */ + /* */ + /* elements :: A table of element addresses within the block. */ + /* */ + /* lengths :: A table of element sizes within the block. */ + /* */ + /* memory :: The object used for memory operations */ + /* (alloc/realloc). */ + /* */ + /* funcs :: A table of method pointers for this object. */ + /* */ + typedef struct PS_TableRec_ + { + FT_Byte* block; /* current memory block */ + FT_Offset cursor; /* current cursor in memory block */ + FT_Offset capacity; /* current size of memory block */ + FT_Long init; + + FT_Int max_elems; + FT_Int num_elems; + FT_Byte** elements; /* addresses of table elements */ + FT_PtrDist* lengths; /* lengths of table elements */ + + FT_Memory memory; + PS_Table_FuncsRec funcs; + + } PS_TableRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 FIELDS & TOKENS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PS_ParserRec_* PS_Parser; + + typedef struct T1_TokenRec_* T1_Token; + + typedef struct T1_FieldRec_* T1_Field; + + + /* simple enumeration type used to identify token types */ + typedef enum T1_TokenType_ + { + T1_TOKEN_TYPE_NONE = 0, + T1_TOKEN_TYPE_ANY, + T1_TOKEN_TYPE_STRING, + T1_TOKEN_TYPE_ARRAY, + T1_TOKEN_TYPE_KEY, /* aka `name' */ + + /* do not remove */ + T1_TOKEN_TYPE_MAX + + } T1_TokenType; + + + /* a simple structure used to identify tokens */ + typedef struct T1_TokenRec_ + { + FT_Byte* start; /* first character of token in input stream */ + FT_Byte* limit; /* first character after the token */ + T1_TokenType type; /* type of token */ + + } T1_TokenRec; + + + /* enumeration type used to identify object fields */ + typedef enum T1_FieldType_ + { + T1_FIELD_TYPE_NONE = 0, + T1_FIELD_TYPE_BOOL, + T1_FIELD_TYPE_INTEGER, + T1_FIELD_TYPE_FIXED, + T1_FIELD_TYPE_FIXED_1000, + T1_FIELD_TYPE_STRING, + T1_FIELD_TYPE_KEY, + T1_FIELD_TYPE_BBOX, + T1_FIELD_TYPE_INTEGER_ARRAY, + T1_FIELD_TYPE_FIXED_ARRAY, + T1_FIELD_TYPE_CALLBACK, + + /* do not remove */ + T1_FIELD_TYPE_MAX + + } T1_FieldType; + + + typedef enum T1_FieldLocation_ + { + T1_FIELD_LOCATION_CID_INFO, + T1_FIELD_LOCATION_FONT_DICT, + T1_FIELD_LOCATION_FONT_INFO, + T1_FIELD_LOCATION_PRIVATE, + T1_FIELD_LOCATION_BBOX, + T1_FIELD_LOCATION_LOADER, + T1_FIELD_LOCATION_FACE, + T1_FIELD_LOCATION_BLEND, + + /* do not remove */ + T1_FIELD_LOCATION_MAX + + } T1_FieldLocation; + + + typedef void + (*T1_Field_ParseFunc)( FT_Face face, + FT_Pointer parser ); + + + /* structure type used to model object fields */ + typedef struct T1_FieldRec_ + { + const char* ident; /* field identifier */ + T1_FieldLocation location; + T1_FieldType type; /* type of field */ + T1_Field_ParseFunc reader; + FT_UInt offset; /* offset of field in object */ + FT_Byte size; /* size of field in bytes */ + FT_UInt array_max; /* maximal number of elements for */ + /* array */ + FT_UInt count_offset; /* offset of element count for */ + /* arrays */ + FT_UInt dict; /* where we expect it */ + } T1_FieldRec; + +#define T1_FIELD_DICT_FONTDICT ( 1 << 0 ) /* also FontInfo and FDArray */ +#define T1_FIELD_DICT_PRIVATE ( 1 << 1 ) + + + +#define T1_NEW_SIMPLE_FIELD( _ident, _type, _fname, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE( _fname ), \ + 0, 0, \ + _dict \ + }, + +#define T1_NEW_CALLBACK_FIELD( _ident, _reader, _dict ) \ + { \ + _ident, T1CODE, T1_FIELD_TYPE_CALLBACK, \ + (T1_Field_ParseFunc)_reader, \ + 0, 0, \ + 0, 0, \ + _dict \ + }, + +#define T1_NEW_TABLE_FIELD( _ident, _type, _fname, _max, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, \ + FT_FIELD_OFFSET( num_ ## _fname ), \ + _dict \ + }, + +#define T1_NEW_TABLE_FIELD2( _ident, _type, _fname, _max, _dict ) \ + { \ + _ident, T1CODE, _type, \ + 0, \ + FT_FIELD_OFFSET( _fname ), \ + FT_FIELD_SIZE_DELTA( _fname ), \ + _max, 0, \ + _dict \ + }, + + +#define T1_FIELD_BOOL( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BOOL, _fname, _dict ) + +#define T1_FIELD_NUM( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER, _fname, _dict ) + +#define T1_FIELD_FIXED( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED, _fname, _dict ) + +#define T1_FIELD_FIXED_1000( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_1000, _fname, \ + _dict ) + +#define T1_FIELD_STRING( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_STRING, _fname, _dict ) + +#define T1_FIELD_KEY( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_KEY, _fname, _dict ) + +#define T1_FIELD_BBOX( _ident, _fname, _dict ) \ + T1_NEW_SIMPLE_FIELD( _ident, T1_FIELD_TYPE_BBOX, _fname, _dict ) + + +#define T1_FIELD_NUM_TABLE( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_FIXED_TABLE( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_NUM_TABLE2( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_INTEGER_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_FIXED_TABLE2( _ident, _fname, _fmax, _dict ) \ + T1_NEW_TABLE_FIELD2( _ident, T1_FIELD_TYPE_FIXED_ARRAY, \ + _fname, _fmax, _dict ) + +#define T1_FIELD_CALLBACK( _ident, _name, _dict ) \ + T1_NEW_CALLBACK_FIELD( _ident, _name, _dict ) + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct PS_Parser_FuncsRec_* PS_Parser_Funcs; + + typedef struct PS_Parser_FuncsRec_ + { + void + (*init)( PS_Parser parser, + FT_Byte* base, + FT_Byte* limit, + FT_Memory memory ); + + void + (*done)( PS_Parser parser ); + + void + (*skip_spaces)( PS_Parser parser ); + void + (*skip_PS_token)( PS_Parser parser ); + + FT_Long + (*to_int)( PS_Parser parser ); + FT_Fixed + (*to_fixed)( PS_Parser parser, + FT_Int power_ten ); + + FT_Error + (*to_bytes)( PS_Parser parser, + FT_Byte* bytes, + FT_Long max_bytes, + FT_Long* pnum_bytes, + FT_Bool delimiters ); + + FT_Int + (*to_coord_array)( PS_Parser parser, + FT_Int max_coords, + FT_Short* coords ); + FT_Int + (*to_fixed_array)( PS_Parser parser, + FT_Int max_values, + FT_Fixed* values, + FT_Int power_ten ); + + void + (*to_token)( PS_Parser parser, + T1_Token token ); + void + (*to_token_array)( PS_Parser parser, + T1_Token tokens, + FT_UInt max_tokens, + FT_Int* pnum_tokens ); + + FT_Error + (*load_field)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + FT_Error + (*load_field_table)( PS_Parser parser, + const T1_Field field, + void** objects, + FT_UInt max_objects, + FT_ULong* pflags ); + + } PS_Parser_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_ParserRec */ + /* */ + /* <Description> */ + /* A PS_Parser is an object used to parse a Type 1 font very quickly. */ + /* */ + /* <Fields> */ + /* cursor :: The current position in the text. */ + /* */ + /* base :: Start of the processed text. */ + /* */ + /* limit :: End of the processed text. */ + /* */ + /* error :: The last error returned. */ + /* */ + /* memory :: The object used for memory operations (alloc/realloc). */ + /* */ + /* funcs :: A table of functions for the parser. */ + /* */ + typedef struct PS_ParserRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + FT_Error error; + FT_Memory memory; + + PS_Parser_FuncsRec funcs; + + } PS_ParserRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct T1_BuilderRec_* T1_Builder; + + + typedef FT_Error + (*T1_Builder_Check_Points_Func)( T1_Builder builder, + FT_Int count ); + + typedef void + (*T1_Builder_Add_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + typedef FT_Error + (*T1_Builder_Add_Point1_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef FT_Error + (*T1_Builder_Add_Contour_Func)( T1_Builder builder ); + + typedef FT_Error + (*T1_Builder_Start_Point_Func)( T1_Builder builder, + FT_Pos x, + FT_Pos y ); + + typedef void + (*T1_Builder_Close_Contour_Func)( T1_Builder builder ); + + + typedef const struct T1_Builder_FuncsRec_* T1_Builder_Funcs; + + typedef struct T1_Builder_FuncsRec_ + { + void + (*init)( T1_Builder builder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Bool hinting ); + + void + (*done)( T1_Builder builder ); + + T1_Builder_Check_Points_Func check_points; + T1_Builder_Add_Point_Func add_point; + T1_Builder_Add_Point1_Func add_point1; + T1_Builder_Add_Contour_Func add_contour; + T1_Builder_Start_Point_Func start_point; + T1_Builder_Close_Contour_Func close_contour; + + } T1_Builder_FuncsRec; + + + /* an enumeration type to handle charstring parsing states */ + typedef enum T1_ParseState_ + { + T1_Parse_Start, + T1_Parse_Have_Width, + T1_Parse_Have_Moveto, + T1_Parse_Have_Path + + } T1_ParseState; + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* T1_BuilderRec */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: XXX */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* max_points :: maximum points in builder outline */ + /* */ + /* max_contours :: Maximal number of contours in builder outline. */ + /* */ + /* last :: The last point position. */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* parse_state :: An enumeration which controls the charstring */ + /* parsing state. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* funcs :: An array of function pointers for the builder. */ + /* */ + typedef struct T1_BuilderRec_ + { + FT_Memory memory; + FT_Face face; + FT_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Vector last; + + FT_Pos pos_x; + FT_Pos pos_y; + + FT_Vector left_bearing; + FT_Vector advance; + + FT_BBox bbox; /* bounding box */ + T1_ParseState parse_state; + FT_Bool load_points; + FT_Bool no_recurse; + FT_Bool shift; + + FT_Bool metrics_only; + + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ + + T1_Builder_FuncsRec funcs; + + } T1_BuilderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** T1 DECODER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#if 0 + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 8 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 32 + +#endif /* 0 */ + + + typedef struct T1_Decoder_ZoneRec_ + { + FT_Byte* cursor; + FT_Byte* base; + FT_Byte* limit; + + } T1_Decoder_ZoneRec, *T1_Decoder_Zone; + + + typedef struct T1_DecoderRec_* T1_Decoder; + typedef const struct T1_Decoder_FuncsRec_* T1_Decoder_Funcs; + + + typedef FT_Error + (*T1_Decoder_Callback)( T1_Decoder decoder, + FT_UInt glyph_index ); + + + typedef struct T1_Decoder_FuncsRec_ + { + FT_Error + (*init)( T1_Decoder decoder, + FT_Face face, + FT_Size size, + FT_GlyphSlot slot, + FT_Byte** glyph_names, + PS_Blend blend, + FT_Bool hinting, + FT_Render_Mode hint_mode, + T1_Decoder_Callback callback ); + + void + (*done)( T1_Decoder decoder ); + + FT_Error + (*parse_charstrings)( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); + + } T1_Decoder_FuncsRec; + + + typedef struct T1_DecoderRec_ + { + T1_BuilderRec builder; + + FT_Long stack[T1_MAX_CHARSTRINGS_OPERANDS]; + FT_Long* top; + + T1_Decoder_ZoneRec zones[T1_MAX_SUBRS_CALLS + 1]; + T1_Decoder_Zone zone; + + FT_Service_PsCMaps psnames; /* for seac */ + FT_UInt num_glyphs; + FT_Byte** glyph_names; + + FT_Int lenIV; /* internal for sub routine calls */ + FT_UInt num_subrs; + FT_Byte** subrs; + FT_PtrDist* subrs_len; /* array of subrs length (optional) */ + + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + PS_Blend blend; /* for multiple master support */ + + FT_Render_Mode hint_mode; + + T1_Decoder_Callback parse_callback; + T1_Decoder_FuncsRec funcs; + + FT_Int* buildchar; + FT_UInt len_buildchar; + + } T1_DecoderRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** AFM PARSER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AFM_ParserRec_* AFM_Parser; + + typedef struct AFM_Parser_FuncsRec_ + { + FT_Error + (*init)( AFM_Parser parser, + FT_Memory memory, + FT_Byte* base, + FT_Byte* limit ); + + void + (*done)( AFM_Parser parser ); + + FT_Error + (*parse)( AFM_Parser parser ); + + } AFM_Parser_FuncsRec; + + + typedef struct AFM_StreamRec_* AFM_Stream; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* AFM_ParserRec */ + /* */ + /* <Description> */ + /* An AFM_Parser is a parser for the AFM files. */ + /* */ + /* <Fields> */ + /* memory :: The object used for memory operations (alloc and */ + /* realloc). */ + /* */ + /* stream :: This is an opaque object. */ + /* */ + /* FontInfo :: The result will be stored here. */ + /* */ + /* get_index :: A user provided function to get a glyph index by its */ + /* name. */ + /* */ + typedef struct AFM_ParserRec_ + { + FT_Memory memory; + AFM_Stream stream; + + AFM_FontInfo FontInfo; + + FT_Int + (*get_index)( const char* name, + FT_UInt len, + void* user_data ); + + void* user_data; + + } AFM_ParserRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** TYPE1 CHARMAPS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef const struct T1_CMap_ClassesRec_* T1_CMap_Classes; + + typedef struct T1_CMap_ClassesRec_ + { + FT_CMap_Class standard; + FT_CMap_Class expert; + FT_CMap_Class custom; + FT_CMap_Class unicode; + + } T1_CMap_ClassesRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PSAux Module Interface *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSAux_ServiceRec_ + { + /* don't use `PS_Table_Funcs' and friends to avoid compiler warnings */ + const PS_Table_FuncsRec* ps_table_funcs; + const PS_Parser_FuncsRec* ps_parser_funcs; + const T1_Builder_FuncsRec* t1_builder_funcs; + const T1_Decoder_FuncsRec* t1_decoder_funcs; + + void + (*t1_decrypt)( FT_Byte* buffer, + FT_Offset length, + FT_UShort seed ); + + T1_CMap_Classes t1_cmap_classes; + + /* fields after this comment line were added after version 2.1.10 */ + const AFM_Parser_FuncsRec* afm_parser_funcs; + + } PSAux_ServiceRec, *PSAux_Service; + + /* backwards-compatible type definition */ + typedef PSAux_ServiceRec PSAux_Interface; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** Some convenience functions *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define IS_PS_NEWLINE( ch ) \ + ( (ch) == '\r' || \ + (ch) == '\n' ) + +#define IS_PS_SPACE( ch ) \ + ( (ch) == ' ' || \ + IS_PS_NEWLINE( ch ) || \ + (ch) == '\t' || \ + (ch) == '\f' || \ + (ch) == '\0' ) + +#define IS_PS_SPECIAL( ch ) \ + ( (ch) == '/' || \ + (ch) == '(' || (ch) == ')' || \ + (ch) == '<' || (ch) == '>' || \ + (ch) == '[' || (ch) == ']' || \ + (ch) == '{' || (ch) == '}' || \ + (ch) == '%' ) + +#define IS_PS_DELIM( ch ) \ + ( IS_PS_SPACE( ch ) || \ + IS_PS_SPECIAL( ch ) ) + +#define IS_PS_DIGIT( ch ) \ + ( (ch) >= '0' && (ch) <= '9' ) + +#define IS_PS_XDIGIT( ch ) \ + ( IS_PS_DIGIT( ch ) || \ + ( (ch) >= 'A' && (ch) <= 'F' ) || \ + ( (ch) >= 'a' && (ch) <= 'f' ) ) + +#define IS_PS_BASE85( ch ) \ + ( (ch) >= '!' && (ch) <= 'u' ) + +#define IS_PS_TOKEN( cur, limit, token ) \ + ( (char)(cur)[0] == (token)[0] && \ + ( (cur) + sizeof ( (token) ) == (limit) || \ + ( (cur) + sizeof( (token) ) < (limit) && \ + IS_PS_DELIM( (cur)[sizeof ( (token) ) - 1] ) ) ) && \ + ft_strncmp( (char*)(cur), (token), sizeof ( (token) ) - 1 ) == 0 ) + + +FT_END_HEADER + +#endif /* __PSAUX_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/pshints.h b/utils/openttd/freetype/internal/pshints.h new file mode 100644 index 00000000000..48452c0cf3e --- /dev/null +++ b/utils/openttd/freetype/internal/pshints.h @@ -0,0 +1,687 @@ +/***************************************************************************/ +/* */ +/* pshints.h */ +/* */ +/* Interface to Postscript-specific (Type 1 and Type 2) hints */ +/* recorders (specification only). These are used to support native */ +/* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ +/* */ +/* Copyright 2001, 2002, 2003, 2005, 2006, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __PSHINTS_H__ +#define __PSHINTS_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** INTERNAL REPRESENTATION OF GLOBALS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct PSH_GlobalsRec_* PSH_Globals; + + typedef FT_Error + (*PSH_Globals_NewFunc)( FT_Memory memory, + T1_Private* private_dict, + PSH_Globals* aglobals ); + + typedef FT_Error + (*PSH_Globals_SetScaleFunc)( PSH_Globals globals, + FT_Fixed x_scale, + FT_Fixed y_scale, + FT_Fixed x_delta, + FT_Fixed y_delta ); + + typedef void + (*PSH_Globals_DestroyFunc)( PSH_Globals globals ); + + + typedef struct PSH_Globals_FuncsRec_ + { + PSH_Globals_NewFunc create; + PSH_Globals_SetScaleFunc set_scale; + PSH_Globals_DestroyFunc destroy; + + } PSH_Globals_FuncsRec, *PSH_Globals_Funcs; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 1 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * T1_Hints + * + * @description: + * This is a handle to an opaque structure used to record glyph hints + * from a Type 1 character glyph character string. + * + * The methods used to operate on this object are defined by the + * @T1_Hints_FuncsRec structure. Recording glyph hints is normally + * achieved through the following scheme: + * + * - Open a new hint recording session by calling the `open' method. + * This rewinds the recorder and prepare it for new input. + * + * - For each hint found in the glyph charstring, call the corresponding + * method (`stem', `stem3', or `reset'). Note that these functions do + * not return an error code. + * + * - Close the recording session by calling the `close' method. It + * returns an error code if the hints were invalid or something + * strange happened (e.g., memory shortage). + * + * The hints accumulated in the object can later be used by the + * PostScript hinter. + * + */ + typedef struct T1_HintsRec_* T1_Hints; + + + /************************************************************************* + * + * @type: + * T1_Hints_Funcs + * + * @description: + * A pointer to the @T1_Hints_FuncsRec structure that defines the API of + * a given @T1_Hints object. + * + */ + typedef const struct T1_Hints_FuncsRec_* T1_Hints_Funcs; + + + /************************************************************************* + * + * @functype: + * T1_Hints_OpenFunc + * + * @description: + * A method of the @T1_Hints class used to prepare it for a new Type 1 + * hints recording session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * @note: + * You should always call the @T1_Hints_CloseFunc method in order to + * close an opened recording session. + * + */ + typedef void + (*T1_Hints_OpenFunc)( T1_Hints hints ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_SetStemFunc + * + * @description: + * A method of the @T1_Hints class used to record a new horizontal or + * vertical stem. This corresponds to the Type 1 `hstem' and `vstem' + * operators. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * dimension :: + * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). + * + * coords :: + * Array of 2 integers, used as (position,length) stem descriptor. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * `coords[0]' is the absolute stem position (lowest coordinate); + * `coords[1]' is the length. + * + * The length can be negative, in which case it must be either -20 or + * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * specification. + * + * If the length is -21 (corresponding to a bottom ghost stem), then + * the real stem position is `coords[0]+coords[1]'. + * + */ + typedef void + (*T1_Hints_SetStemFunc)( T1_Hints hints, + FT_UInt dimension, + FT_Long* coords ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_SetStem3Func + * + * @description: + * A method of the @T1_Hints class used to record three + * counter-controlled horizontal or vertical stems at once. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * dimension :: + * 0 for horizontal stems, 1 for vertical ones. + * + * coords :: + * An array of 6 integers, holding 3 (position,length) pairs for the + * counter-controlled stems. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * The lengths cannot be negative (ghost stems are never + * counter-controlled). + * + */ + typedef void + (*T1_Hints_SetStem3Func)( T1_Hints hints, + FT_UInt dimension, + FT_Long* coords ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_ResetFunc + * + * @description: + * A method of the @T1_Hints class used to reset the stems hints in a + * recording session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph in which the + * previously defined hints apply. + * + */ + typedef void + (*T1_Hints_ResetFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_CloseFunc + * + * @description: + * A method of the @T1_Hints class used to close a hint recording + * session. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The error code is set to indicate that an error occurred during the + * recording session. + * + */ + typedef FT_Error + (*T1_Hints_CloseFunc)( T1_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T1_Hints_ApplyFunc + * + * @description: + * A method of the @T1_Hints class used to apply hints to the + * corresponding glyph outline. Must be called once all hints have been + * recorded. + * + * @input: + * hints :: + * A handle to the Type 1 hints recorder. + * + * outline :: + * A pointer to the target outline descriptor. + * + * globals :: + * The hinter globals for this font. + * + * hint_mode :: + * Hinting information. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * On input, all points within the outline are in font coordinates. On + * output, they are in 1/64th of pixels. + * + * The scaling transformation is taken from the `globals' object which + * must correspond to the same font as the glyph. + * + */ + typedef FT_Error + (*T1_Hints_ApplyFunc)( T1_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /************************************************************************* + * + * @struct: + * T1_Hints_FuncsRec + * + * @description: + * The structure used to provide the API to @T1_Hints objects. + * + * @fields: + * hints :: + * A handle to the T1 Hints recorder. + * + * open :: + * The function to open a recording session. + * + * close :: + * The function to close a recording session. + * + * stem :: + * The function to set a simple stem. + * + * stem3 :: + * The function to set counter-controlled stems. + * + * reset :: + * The function to reset stem hints. + * + * apply :: + * The function to apply the hints to the corresponding glyph outline. + * + */ + typedef struct T1_Hints_FuncsRec_ + { + T1_Hints hints; + T1_Hints_OpenFunc open; + T1_Hints_CloseFunc close; + T1_Hints_SetStemFunc stem; + T1_Hints_SetStem3Func stem3; + T1_Hints_ResetFunc reset; + T1_Hints_ApplyFunc apply; + + } T1_Hints_FuncsRec; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PUBLIC TYPE 2 HINTS RECORDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /************************************************************************* + * + * @type: + * T2_Hints + * + * @description: + * This is a handle to an opaque structure used to record glyph hints + * from a Type 2 character glyph character string. + * + * The methods used to operate on this object are defined by the + * @T2_Hints_FuncsRec structure. Recording glyph hints is normally + * achieved through the following scheme: + * + * - Open a new hint recording session by calling the `open' method. + * This rewinds the recorder and prepare it for new input. + * + * - For each hint found in the glyph charstring, call the corresponding + * method (`stems', `hintmask', `counters'). Note that these + * functions do not return an error code. + * + * - Close the recording session by calling the `close' method. It + * returns an error code if the hints were invalid or something + * strange happened (e.g., memory shortage). + * + * The hints accumulated in the object can later be used by the + * Postscript hinter. + * + */ + typedef struct T2_HintsRec_* T2_Hints; + + + /************************************************************************* + * + * @type: + * T2_Hints_Funcs + * + * @description: + * A pointer to the @T2_Hints_FuncsRec structure that defines the API of + * a given @T2_Hints object. + * + */ + typedef const struct T2_Hints_FuncsRec_* T2_Hints_Funcs; + + + /************************************************************************* + * + * @functype: + * T2_Hints_OpenFunc + * + * @description: + * A method of the @T2_Hints class used to prepare it for a new Type 2 + * hints recording session. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * @note: + * You should always call the @T2_Hints_CloseFunc method in order to + * close an opened recording session. + * + */ + typedef void + (*T2_Hints_OpenFunc)( T2_Hints hints ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_StemsFunc + * + * @description: + * A method of the @T2_Hints class used to set the table of stems in + * either the vertical or horizontal dimension. Equivalent to the + * `hstem', `vstem', `hstemhm', and `vstemhm' Type 2 operators. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * dimension :: + * 0 for horizontal stems (hstem), 1 for vertical ones (vstem). + * + * count :: + * The number of stems. + * + * coords :: + * An array of `count' (position,length) pairs. + * + * @note: + * Use vertical coordinates (y) for horizontal stems (dim=0). Use + * horizontal coordinates (x) for vertical stems (dim=1). + * + * There are `2*count' elements in the `coords' array. Each even + * element is an absolute position in font units, each odd element is a + * length in font units. + * + * A length can be negative, in which case it must be either -20 or + * -21. It is interpreted as a `ghost' stem, according to the Type 1 + * specification. + * + */ + typedef void + (*T2_Hints_StemsFunc)( T2_Hints hints, + FT_UInt dimension, + FT_UInt count, + FT_Fixed* coordinates ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_MaskFunc + * + * @description: + * A method of the @T2_Hints class used to set a given hintmask (this + * corresponds to the `hintmask' Type 2 operator). + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * The glyph index of the last point to which the previously defined + * or activated hints apply. + * + * bit_count :: + * The number of bits in the hint mask. + * + * bytes :: + * An array of bytes modelling the hint mask. + * + * @note: + * If the hintmask starts the charstring (before any glyph point + * definition), the value of `end_point' should be 0. + * + * `bit_count' is the number of meaningful bits in the `bytes' array; it + * must be equal to the total number of hints defined so far (i.e., + * horizontal+verticals). + * + * The `bytes' array can come directly from the Type 2 charstring and + * respects the same format. + * + */ + typedef void + (*T2_Hints_MaskFunc)( T2_Hints hints, + FT_UInt end_point, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_CounterFunc + * + * @description: + * A method of the @T2_Hints class used to set a given counter mask + * (this corresponds to the `hintmask' Type 2 operator). + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * A glyph index of the last point to which the previously defined or + * active hints apply. + * + * bit_count :: + * The number of bits in the hint mask. + * + * bytes :: + * An array of bytes modelling the hint mask. + * + * @note: + * If the hintmask starts the charstring (before any glyph point + * definition), the value of `end_point' should be 0. + * + * `bit_count' is the number of meaningful bits in the `bytes' array; it + * must be equal to the total number of hints defined so far (i.e., + * horizontal+verticals). + * + * The `bytes' array can come directly from the Type 2 charstring and + * respects the same format. + * + */ + typedef void + (*T2_Hints_CounterFunc)( T2_Hints hints, + FT_UInt bit_count, + const FT_Byte* bytes ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_CloseFunc + * + * @description: + * A method of the @T2_Hints class used to close a hint recording + * session. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * end_point :: + * The index of the last point in the input glyph. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The error code is set to indicate that an error occurred during the + * recording session. + * + */ + typedef FT_Error + (*T2_Hints_CloseFunc)( T2_Hints hints, + FT_UInt end_point ); + + + /************************************************************************* + * + * @functype: + * T2_Hints_ApplyFunc + * + * @description: + * A method of the @T2_Hints class used to apply hints to the + * corresponding glyph outline. Must be called after the `close' + * method. + * + * @input: + * hints :: + * A handle to the Type 2 hints recorder. + * + * outline :: + * A pointer to the target outline descriptor. + * + * globals :: + * The hinter globals for this font. + * + * hint_mode :: + * Hinting information. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * On input, all points within the outline are in font coordinates. On + * output, they are in 1/64th of pixels. + * + * The scaling transformation is taken from the `globals' object which + * must correspond to the same font than the glyph. + * + */ + typedef FT_Error + (*T2_Hints_ApplyFunc)( T2_Hints hints, + FT_Outline* outline, + PSH_Globals globals, + FT_Render_Mode hint_mode ); + + + /************************************************************************* + * + * @struct: + * T2_Hints_FuncsRec + * + * @description: + * The structure used to provide the API to @T2_Hints objects. + * + * @fields: + * hints :: + * A handle to the T2 hints recorder object. + * + * open :: + * The function to open a recording session. + * + * close :: + * The function to close a recording session. + * + * stems :: + * The function to set the dimension's stems table. + * + * hintmask :: + * The function to set hint masks. + * + * counter :: + * The function to set counter masks. + * + * apply :: + * The function to apply the hints on the corresponding glyph outline. + * + */ + typedef struct T2_Hints_FuncsRec_ + { + T2_Hints hints; + T2_Hints_OpenFunc open; + T2_Hints_CloseFunc close; + T2_Hints_StemsFunc stems; + T2_Hints_MaskFunc hintmask; + T2_Hints_CounterFunc counter; + T2_Hints_ApplyFunc apply; + + } T2_Hints_FuncsRec; + + + /* */ + + + typedef struct PSHinter_Interface_ + { + PSH_Globals_Funcs (*get_globals_funcs)( FT_Module module ); + T1_Hints_Funcs (*get_t1_funcs) ( FT_Module module ); + T2_Hints_Funcs (*get_t2_funcs) ( FT_Module module ); + + } PSHinter_Interface; + + typedef PSHinter_Interface* PSHinter_Service; + + +FT_END_HEADER + +#endif /* __PSHINTS_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svbdf.h b/utils/openttd/freetype/internal/services/svbdf.h new file mode 100644 index 00000000000..0f7fc6115d6 --- /dev/null +++ b/utils/openttd/freetype/internal/services/svbdf.h @@ -0,0 +1,57 @@ +/***************************************************************************/ +/* */ +/* svbdf.h */ +/* */ +/* The FreeType BDF services (specification). */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVBDF_H__ +#define __SVBDF_H__ + +#include FT_BDF_H +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_BDF "bdf" + + typedef FT_Error + (*FT_BDF_GetCharsetIdFunc)( FT_Face face, + const char* *acharset_encoding, + const char* *acharset_registry ); + + typedef FT_Error + (*FT_BDF_GetPropertyFunc)( FT_Face face, + const char* prop_name, + BDF_PropertyRec *aproperty ); + + + FT_DEFINE_SERVICE( BDF ) + { + FT_BDF_GetCharsetIdFunc get_charset_id; + FT_BDF_GetPropertyFunc get_property; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVBDF_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svcid.h b/utils/openttd/freetype/internal/services/svcid.h new file mode 100644 index 00000000000..47fef62ed2d --- /dev/null +++ b/utils/openttd/freetype/internal/services/svcid.h @@ -0,0 +1,49 @@ +/***************************************************************************/ +/* */ +/* svcid.h */ +/* */ +/* The FreeType CID font services (specification). */ +/* */ +/* Copyright 2007 by Derek Clegg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVCID_H__ +#define __SVCID_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_CID "CID" + + typedef FT_Error + (*FT_CID_GetRegistryOrderingSupplementFunc)( FT_Face face, + const char* *registry, + const char* *ordering, + FT_Int *supplement ); + + FT_DEFINE_SERVICE( CID ) + { + FT_CID_GetRegistryOrderingSupplementFunc get_ros; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVCID_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svgldict.h b/utils/openttd/freetype/internal/services/svgldict.h new file mode 100644 index 00000000000..e5e56b253c1 --- /dev/null +++ b/utils/openttd/freetype/internal/services/svgldict.h @@ -0,0 +1,60 @@ +/***************************************************************************/ +/* */ +/* svgldict.h */ +/* */ +/* The FreeType glyph dictionary services (specification). */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVGLDICT_H__ +#define __SVGLDICT_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to retrieve glyph names, as well as to find the + * index of a given glyph name in a font. + * + */ + +#define FT_SERVICE_ID_GLYPH_DICT "glyph-dict" + + + typedef FT_Error + (*FT_GlyphDict_GetNameFunc)( FT_Face face, + FT_UInt glyph_index, + FT_Pointer buffer, + FT_UInt buffer_max ); + + typedef FT_UInt + (*FT_GlyphDict_NameIndexFunc)( FT_Face face, + FT_String* glyph_name ); + + + FT_DEFINE_SERVICE( GlyphDict ) + { + FT_GlyphDict_GetNameFunc get_name; + FT_GlyphDict_NameIndexFunc name_index; /* optional */ + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVGLDICT_H__ */ diff --git a/utils/openttd/freetype/internal/services/svgxval.h b/utils/openttd/freetype/internal/services/svgxval.h new file mode 100644 index 00000000000..2cdab506551 --- /dev/null +++ b/utils/openttd/freetype/internal/services/svgxval.h @@ -0,0 +1,72 @@ +/***************************************************************************/ +/* */ +/* svgxval.h */ +/* */ +/* FreeType API for validating TrueTypeGX/AAT tables (specification). */ +/* */ +/* Copyright 2004, 2005 by */ +/* Masatake YAMATO, Red Hat K.K., */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/***************************************************************************/ +/* */ +/* gxvalid is derived from both gxlayout module and otvalid module. */ +/* Development of gxlayout is supported by the Information-technology */ +/* Promotion Agency(IPA), Japan. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVGXVAL_H__ +#define __SVGXVAL_H__ + +#include FT_GX_VALIDATE_H +#include FT_INTERNAL_VALIDATE_H + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_GX_VALIDATE "truetypegx-validate" +#define FT_SERVICE_ID_CLASSICKERN_VALIDATE "classickern-validate" + + typedef FT_Error + (*gxv_validate_func)( FT_Face face, + FT_UInt gx_flags, + FT_Bytes tables[FT_VALIDATE_GX_LENGTH], + FT_UInt table_length ); + + + typedef FT_Error + (*ckern_validate_func)( FT_Face face, + FT_UInt ckern_flags, + FT_Bytes *ckern_table ); + + + FT_DEFINE_SERVICE( GXvalidate ) + { + gxv_validate_func validate; + }; + + FT_DEFINE_SERVICE( CKERNvalidate ) + { + ckern_validate_func validate; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVGXVAL_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svkern.h b/utils/openttd/freetype/internal/services/svkern.h new file mode 100644 index 00000000000..1488adf493b --- /dev/null +++ b/utils/openttd/freetype/internal/services/svkern.h @@ -0,0 +1,51 @@ +/***************************************************************************/ +/* */ +/* svkern.h */ +/* */ +/* The FreeType Kerning service (specification). */ +/* */ +/* Copyright 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVKERN_H__ +#define __SVKERN_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + +#define FT_SERVICE_ID_KERNING "kerning" + + + typedef FT_Error + (*FT_Kerning_TrackGetFunc)( FT_Face face, + FT_Fixed point_size, + FT_Int degree, + FT_Fixed* akerning ); + + FT_DEFINE_SERVICE( Kerning ) + { + FT_Kerning_TrackGetFunc get_track; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVKERN_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svmm.h b/utils/openttd/freetype/internal/services/svmm.h new file mode 100644 index 00000000000..8a99ec4b1a7 --- /dev/null +++ b/utils/openttd/freetype/internal/services/svmm.h @@ -0,0 +1,79 @@ +/***************************************************************************/ +/* */ +/* svmm.h */ +/* */ +/* The FreeType Multiple Masters and GX var services (specification). */ +/* */ +/* Copyright 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVMM_H__ +#define __SVMM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service used to manage multiple-masters data in a given face. + * + * See the related APIs in `ftmm.h' (FT_MULTIPLE_MASTERS_H). + * + */ + +#define FT_SERVICE_ID_MULTI_MASTERS "multi-masters" + + + typedef FT_Error + (*FT_Get_MM_Func)( FT_Face face, + FT_Multi_Master* master ); + + typedef FT_Error + (*FT_Get_MM_Var_Func)( FT_Face face, + FT_MM_Var* *master ); + + typedef FT_Error + (*FT_Set_MM_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + typedef FT_Error + (*FT_Set_Var_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + typedef FT_Error + (*FT_Set_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + + FT_DEFINE_SERVICE( MultiMasters ) + { + FT_Get_MM_Func get_mm; + FT_Set_MM_Design_Func set_mm_design; + FT_Set_MM_Blend_Func set_mm_blend; + FT_Get_MM_Var_Func get_mm_var; + FT_Set_Var_Design_Func set_var_design; + }; + + /* */ + + +FT_END_HEADER + +#endif /* __SVMM_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svotval.h b/utils/openttd/freetype/internal/services/svotval.h new file mode 100644 index 00000000000..970bbd57593 --- /dev/null +++ b/utils/openttd/freetype/internal/services/svotval.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svotval.h */ +/* */ +/* The FreeType OpenType validation service (specification). */ +/* */ +/* Copyright 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVOTVAL_H__ +#define __SVOTVAL_H__ + +#include FT_OPENTYPE_VALIDATE_H +#include FT_INTERNAL_VALIDATE_H + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_OPENTYPE_VALIDATE "opentype-validate" + + + typedef FT_Error + (*otv_validate_func)( FT_Face volatile face, + FT_UInt ot_flags, + FT_Bytes *base, + FT_Bytes *gdef, + FT_Bytes *gpos, + FT_Bytes *gsub, + FT_Bytes *jstf ); + + + FT_DEFINE_SERVICE( OTvalidate ) + { + otv_validate_func validate; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVOTVAL_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svpfr.h b/utils/openttd/freetype/internal/services/svpfr.h new file mode 100644 index 00000000000..462786f9ce9 --- /dev/null +++ b/utils/openttd/freetype/internal/services/svpfr.h @@ -0,0 +1,66 @@ +/***************************************************************************/ +/* */ +/* svpfr.h */ +/* */ +/* Internal PFR service functions (specification). */ +/* */ +/* Copyright 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPFR_H__ +#define __SVPFR_H__ + +#include FT_PFR_H +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_PFR_METRICS "pfr-metrics" + + + typedef FT_Error + (*FT_PFR_GetMetricsFunc)( FT_Face face, + FT_UInt *aoutline, + FT_UInt *ametrics, + FT_Fixed *ax_scale, + FT_Fixed *ay_scale ); + + typedef FT_Error + (*FT_PFR_GetKerningFunc)( FT_Face face, + FT_UInt left, + FT_UInt right, + FT_Vector *avector ); + + typedef FT_Error + (*FT_PFR_GetAdvanceFunc)( FT_Face face, + FT_UInt gindex, + FT_Pos *aadvance ); + + + FT_DEFINE_SERVICE( PfrMetrics ) + { + FT_PFR_GetMetricsFunc get_metrics; + FT_PFR_GetKerningFunc get_kerning; + FT_PFR_GetAdvanceFunc get_advance; + + }; + + /* */ + +FT_END_HEADER + +#endif /* __SVPFR_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svpostnm.h b/utils/openttd/freetype/internal/services/svpostnm.h new file mode 100644 index 00000000000..282da68d13e --- /dev/null +++ b/utils/openttd/freetype/internal/services/svpostnm.h @@ -0,0 +1,58 @@ +/***************************************************************************/ +/* */ +/* svpostnm.h */ +/* */ +/* The FreeType PostScript name services (specification). */ +/* */ +/* Copyright 2003, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPOSTNM_H__ +#define __SVPOSTNM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + /* + * A trivial service used to retrieve the PostScript name of a given + * font when available. The `get_name' field should never be NULL. + * + * The corresponding function can return NULL to indicate that the + * PostScript name is not available. + * + * The name is owned by the face and will be destroyed with it. + */ + +#define FT_SERVICE_ID_POSTSCRIPT_FONT_NAME "postscript-font-name" + + + typedef const char* + (*FT_PsName_GetFunc)( FT_Face face ); + + + FT_DEFINE_SERVICE( PsFontName ) + { + FT_PsName_GetFunc get_ps_font_name; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPOSTNM_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svpscmap.h b/utils/openttd/freetype/internal/services/svpscmap.h new file mode 100644 index 00000000000..c4e25ed635f --- /dev/null +++ b/utils/openttd/freetype/internal/services/svpscmap.h @@ -0,0 +1,129 @@ +/***************************************************************************/ +/* */ +/* svpscmap.h */ +/* */ +/* The FreeType PostScript charmap service (specification). */ +/* */ +/* Copyright 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPSCMAP_H__ +#define __SVPSCMAP_H__ + +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_CMAPS "postscript-cmaps" + + + /* + * Adobe glyph name to unicode value. + */ + typedef FT_UInt32 + (*PS_Unicode_ValueFunc)( const char* glyph_name ); + + /* + * Macintosh name id to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Macintosh_NameFunc)( FT_UInt name_index ); + + /* + * Adobe standard string ID to glyph name. NULL if invalid index. + */ + typedef const char* + (*PS_Adobe_Std_StringsFunc)( FT_UInt string_index ); + + + /* + * Simple unicode -> glyph index charmap built from font glyph names + * table. + */ + typedef struct PS_UniMap_ + { + FT_UInt32 unicode; /* bit 31 set: is glyph variant */ + FT_UInt glyph_index; + + } PS_UniMap; + + + typedef struct PS_UnicodesRec_* PS_Unicodes; + + typedef struct PS_UnicodesRec_ + { + FT_CMapRec cmap; + FT_UInt num_maps; + PS_UniMap* maps; + + } PS_UnicodesRec; + + + /* + * A function which returns a glyph name for a given index. Returns + * NULL if invalid index. + */ + typedef const char* + (*PS_GetGlyphNameFunc)( FT_Pointer data, + FT_UInt string_index ); + + /* + * A function used to release the glyph name returned by + * PS_GetGlyphNameFunc, when needed + */ + typedef void + (*PS_FreeGlyphNameFunc)( FT_Pointer data, + const char* name ); + + typedef FT_Error + (*PS_Unicodes_InitFunc)( FT_Memory memory, + PS_Unicodes unicodes, + FT_UInt num_glyphs, + PS_GetGlyphNameFunc get_glyph_name, + PS_FreeGlyphNameFunc free_glyph_name, + FT_Pointer glyph_data ); + + typedef FT_UInt + (*PS_Unicodes_CharIndexFunc)( PS_Unicodes unicodes, + FT_UInt32 unicode ); + + typedef FT_ULong + (*PS_Unicodes_CharNextFunc)( PS_Unicodes unicodes, + FT_UInt32 *unicode ); + + + FT_DEFINE_SERVICE( PsCMaps ) + { + PS_Unicode_ValueFunc unicode_value; + + PS_Unicodes_InitFunc unicodes_init; + PS_Unicodes_CharIndexFunc unicodes_char_index; + PS_Unicodes_CharNextFunc unicodes_char_next; + + PS_Macintosh_NameFunc macintosh_name; + PS_Adobe_Std_StringsFunc adobe_std_strings; + const unsigned short* adobe_std_encoding; + const unsigned short* adobe_expert_encoding; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPSCMAP_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svpsinfo.h b/utils/openttd/freetype/internal/services/svpsinfo.h new file mode 100644 index 00000000000..63f5db9c19a --- /dev/null +++ b/utils/openttd/freetype/internal/services/svpsinfo.h @@ -0,0 +1,60 @@ +/***************************************************************************/ +/* */ +/* svpsinfo.h */ +/* */ +/* The FreeType PostScript info service (specification). */ +/* */ +/* Copyright 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVPSINFO_H__ +#define __SVPSINFO_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_POSTSCRIPT_INFO "postscript-info" + + + typedef FT_Error + (*PS_GetFontInfoFunc)( FT_Face face, + PS_FontInfoRec* afont_info ); + + typedef FT_Int + (*PS_HasGlyphNamesFunc)( FT_Face face ); + + typedef FT_Error + (*PS_GetFontPrivateFunc)( FT_Face face, + PS_PrivateRec* afont_private ); + + + FT_DEFINE_SERVICE( PsInfo ) + { + PS_GetFontInfoFunc ps_get_font_info; + PS_HasGlyphNamesFunc ps_has_glyph_names; + PS_GetFontPrivateFunc ps_get_font_private; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVPSINFO_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svsfnt.h b/utils/openttd/freetype/internal/services/svsfnt.h new file mode 100644 index 00000000000..b4a85d97ec7 --- /dev/null +++ b/utils/openttd/freetype/internal/services/svsfnt.h @@ -0,0 +1,80 @@ +/***************************************************************************/ +/* */ +/* svsfnt.h */ +/* */ +/* The FreeType SFNT table loading service (specification). */ +/* */ +/* Copyright 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVSFNT_H__ +#define __SVSFNT_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + + /* + * SFNT table loading service. + */ + +#define FT_SERVICE_ID_SFNT_TABLE "sfnt-table" + + + /* + * Used to implement FT_Load_Sfnt_Table(). + */ + typedef FT_Error + (*FT_SFNT_TableLoadFunc)( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + /* + * Used to implement FT_Get_Sfnt_Table(). + */ + typedef void* + (*FT_SFNT_TableGetFunc)( FT_Face face, + FT_Sfnt_Tag tag ); + + + /* + * Used to implement FT_Sfnt_Table_Info(). + */ + typedef FT_Error + (*FT_SFNT_TableInfoFunc)( FT_Face face, + FT_UInt idx, + FT_ULong *tag, + FT_ULong *length ); + + + FT_DEFINE_SERVICE( SFNT_Table ) + { + FT_SFNT_TableLoadFunc load_table; + FT_SFNT_TableGetFunc get_table; + FT_SFNT_TableInfoFunc table_info; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVSFNT_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svttcmap.h b/utils/openttd/freetype/internal/services/svttcmap.h new file mode 100644 index 00000000000..1e02d15506d --- /dev/null +++ b/utils/openttd/freetype/internal/services/svttcmap.h @@ -0,0 +1,78 @@ +/***************************************************************************/ +/* */ +/* svsttcmap.h */ +/* */ +/* The FreeType TrueType/sfnt cmap extra information service. */ +/* */ +/* Copyright 2003 by */ +/* Masatake YAMATO, Redhat K.K. */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/* Development of this service is support of + Information-technology Promotion Agency, Japan. */ + +#ifndef __SVTTCMAP_H__ +#define __SVTTCMAP_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_TT_CMAP "tt-cmaps" + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_CMapInfo */ + /* */ + /* <Description> */ + /* A structure used to store TrueType/sfnt specific cmap information */ + /* which is not covered by the generic @FT_CharMap structure. This */ + /* structure can be accessed with the @FT_Get_TT_CMap_Info function. */ + /* */ + /* <Fields> */ + /* language :: */ + /* The language ID used in Mac fonts. Definitions of values are in */ + /* freetype/ttnameid.h. */ + /* */ + typedef struct TT_CMapInfo_ + { + FT_ULong language; + FT_Long format; + + } TT_CMapInfo; + + + typedef FT_Error + (*TT_CMap_Info_GetFunc)( FT_CharMap charmap, + TT_CMapInfo *cmap_info ); + + + FT_DEFINE_SERVICE( TTCMaps ) + { + TT_CMap_Info_GetFunc get_cmap_info; + }; + + /* */ + + +FT_END_HEADER + +#endif /* __SVTTCMAP_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svtteng.h b/utils/openttd/freetype/internal/services/svtteng.h new file mode 100644 index 00000000000..58e02a6f9dd --- /dev/null +++ b/utils/openttd/freetype/internal/services/svtteng.h @@ -0,0 +1,53 @@ +/***************************************************************************/ +/* */ +/* svtteng.h */ +/* */ +/* The FreeType TrueType engine query service (specification). */ +/* */ +/* Copyright 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVTTENG_H__ +#define __SVTTENG_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + /* + * SFNT table loading service. + */ + +#define FT_SERVICE_ID_TRUETYPE_ENGINE "truetype-engine" + + /* + * Used to implement FT_Get_TrueType_Engine_Type + */ + + FT_DEFINE_SERVICE( TrueTypeEngine ) + { + FT_TrueTypeEngineType engine_type; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVTTENG_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svttglyf.h b/utils/openttd/freetype/internal/services/svttglyf.h new file mode 100644 index 00000000000..e57d484b7e2 --- /dev/null +++ b/utils/openttd/freetype/internal/services/svttglyf.h @@ -0,0 +1,48 @@ +/***************************************************************************/ +/* */ +/* svttglyf.h */ +/* */ +/* The FreeType TrueType glyph service. */ +/* */ +/* Copyright 2007 by David Turner. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +#ifndef __SVTTGLYF_H__ +#define __SVTTGLYF_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_TRUETYPE_TABLES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_TT_GLYF "tt-glyf" + + + typedef FT_ULong + (*TT_Glyf_GetLocationFunc)( FT_Face face, + FT_UInt gindex, + FT_ULong *psize ); + + FT_DEFINE_SERVICE( TTGlyf ) + { + TT_Glyf_GetLocationFunc get_location; + }; + + /* */ + + +FT_END_HEADER + +#endif /* __SVTTGLYF_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svwinfnt.h b/utils/openttd/freetype/internal/services/svwinfnt.h new file mode 100644 index 00000000000..57f7765d92f --- /dev/null +++ b/utils/openttd/freetype/internal/services/svwinfnt.h @@ -0,0 +1,50 @@ +/***************************************************************************/ +/* */ +/* svwinfnt.h */ +/* */ +/* The FreeType Windows FNT/FONT service (specification). */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVWINFNT_H__ +#define __SVWINFNT_H__ + +#include FT_INTERNAL_SERVICE_H +#include FT_WINFONTS_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_WINFNT "winfonts" + + typedef FT_Error + (*FT_WinFnt_GetHeaderFunc)( FT_Face face, + FT_WinFNT_HeaderRec *aheader ); + + + FT_DEFINE_SERVICE( WinFnt ) + { + FT_WinFnt_GetHeaderFunc get_header; + }; + + /* */ + + +FT_END_HEADER + + +#endif /* __SVWINFNT_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/services/svxf86nm.h b/utils/openttd/freetype/internal/services/svxf86nm.h new file mode 100644 index 00000000000..ca5d884a83c --- /dev/null +++ b/utils/openttd/freetype/internal/services/svxf86nm.h @@ -0,0 +1,55 @@ +/***************************************************************************/ +/* */ +/* svxf86nm.h */ +/* */ +/* The FreeType XFree86 services (specification only). */ +/* */ +/* Copyright 2003 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SVXF86NM_H__ +#define __SVXF86NM_H__ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A trivial service used to return the name of a face's font driver, + * according to the XFree86 nomenclature. Note that the service data + * is a simple constant string pointer. + */ + +#define FT_SERVICE_ID_XF86_NAME "xf86-driver-name" + +#define FT_XF86_FORMAT_TRUETYPE "TrueType" +#define FT_XF86_FORMAT_TYPE_1 "Type 1" +#define FT_XF86_FORMAT_BDF "BDF" +#define FT_XF86_FORMAT_PCF "PCF" +#define FT_XF86_FORMAT_TYPE_42 "Type 42" +#define FT_XF86_FORMAT_CID "CID Type 1" +#define FT_XF86_FORMAT_CFF "CFF" +#define FT_XF86_FORMAT_PFR "PFR" +#define FT_XF86_FORMAT_WINFNT "Windows FNT" + + /* */ + + +FT_END_HEADER + + +#endif /* __SVXF86NM_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/sfnt.h b/utils/openttd/freetype/internal/sfnt.h new file mode 100644 index 00000000000..7e8f6847c98 --- /dev/null +++ b/utils/openttd/freetype/internal/sfnt.h @@ -0,0 +1,762 @@ +/***************************************************************************/ +/* */ +/* sfnt.h */ +/* */ +/* High-level `sfnt' driver interface (specification). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __SFNT_H__ +#define __SFNT_H__ + + +#include <ft2build.h> +#include FT_INTERNAL_DRIVER_H +#include FT_INTERNAL_TRUETYPE_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Init_Face_Func */ + /* */ + /* <Description> */ + /* First part of the SFNT face object initialization. This finds */ + /* the face in a SFNT file or collection, and load its format tag in */ + /* face->format_tag. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + /* This function recognizes fonts embedded in a `TrueType */ + /* collection'. */ + /* */ + /* Once the format tag has been validated by the font driver, it */ + /* should then call the TT_Load_Face_Func() callback to read the rest */ + /* of the SFNT tables in the object. */ + /* */ + typedef FT_Error + (*TT_Init_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Face_Func */ + /* */ + /* <Description> */ + /* Second part of the SFNT face object initialization. This loads */ + /* the common SFNT tables (head, OS/2, maxp, metrics, etc.) in the */ + /* face object. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* face :: A handle to the target face object. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* num_params :: The number of additional parameters. */ + /* */ + /* params :: Optional additional parameters. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function must be called after TT_Init_Face_Func(). */ + /* */ + typedef FT_Error + (*TT_Load_Face_Func)( FT_Stream stream, + TT_Face face, + FT_Int face_index, + FT_Int num_params, + FT_Parameter* params ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Done_Face_Func */ + /* */ + /* <Description> */ + /* A callback used to delete the common SFNT data from a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* <Note> */ + /* This function does NOT destroy the face object. */ + /* */ + typedef void + (*TT_Done_Face_Func)( TT_Face face ); + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SFNT_HeaderRec_Func */ + /* */ + /* <Description> */ + /* Loads the header of a SFNT font file. Supports collections. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection. */ + /* */ + /* <Output> */ + /* sfnt :: The SFNT header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + /* This function recognizes fonts embedded in a `TrueType */ + /* collection'. */ + /* */ + /* This function checks that the header is valid by looking at the */ + /* values of `search_range', `entry_selector', and `range_shift'. */ + /* */ + typedef FT_Error + (*TT_Load_SFNT_HeaderRec_Func)( TT_Face face, + FT_Stream stream, + FT_Long face_index, + SFNT_Header sfnt ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Directory_Func */ + /* */ + /* <Description> */ + /* Loads the table directory into a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* sfnt :: The SFNT header. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be on the first byte after the 4-byte font */ + /* format tag. This is the case just after a call to */ + /* TT_Load_Format_Tag(). */ + /* */ + typedef FT_Error + (*TT_Load_Directory_Func)( TT_Face face, + FT_Stream stream, + SFNT_Header sfnt ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Any_Func */ + /* */ + /* <Description> */ + /* Load any font table into client memory. */ + /* */ + /* <Input> */ + /* face :: The face object to look for. */ + /* */ + /* tag :: The tag of table to load. Use the value 0 if you want */ + /* to access the whole font file, else set this parameter */ + /* to a valid TrueType table tag that you can forge with */ + /* the MAKE_TT_TAG macro. */ + /* */ + /* offset :: The starting offset in the table (or the file if */ + /* tag == 0). */ + /* */ + /* length :: The address of the decision variable: */ + /* */ + /* If length == NULL: */ + /* Loads the whole table. Returns an error if */ + /* `offset' == 0! */ + /* */ + /* If *length == 0: */ + /* Exits immediately; returning the length of the given */ + /* table or of the font file, depending on the value of */ + /* `tag'. */ + /* */ + /* If *length != 0: */ + /* Loads the next `length' bytes of table or font, */ + /* starting at offset `offset' (in table or font too). */ + /* */ + /* <Output> */ + /* buffer :: The address of target buffer. */ + /* */ + /* <Return> */ + /* TrueType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Any_Func)( TT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte *buffer, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Find_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Check whether an embedded bitmap (an `sbit') exists for a given */ + /* glyph, at a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* glyph_index :: The glyph index. */ + /* */ + /* strike_index :: The current strike index. */ + /* */ + /* <Output> */ + /* arange :: The SBit range containing the glyph index. */ + /* */ + /* astrike :: The SBit strike containing the glyph index. */ + /* */ + /* aglyph_offset :: The offset of the glyph data in `EBDT' table. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns */ + /* SFNT_Err_Invalid_Argument if no sbit exists for the requested */ + /* glyph. */ + /* */ + typedef FT_Error + (*TT_Find_SBit_Image_Func)( TT_Face face, + FT_UInt glyph_index, + FT_ULong strike_index, + TT_SBit_Range *arange, + TT_SBit_Strike *astrike, + FT_ULong *aglyph_offset ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Metrics_Func */ + /* */ + /* <Description> */ + /* Get the big metrics for a given embedded bitmap. */ + /* */ + /* <Input> */ + /* stream :: The input stream. */ + /* */ + /* range :: The SBit range containing the glyph. */ + /* */ + /* <Output> */ + /* big_metrics :: A big SBit metrics structure for the glyph. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be positioned at the glyph's offset within */ + /* the `EBDT' table before the call. */ + /* */ + /* If the image format uses variable metrics, the stream cursor is */ + /* positioned just after the metrics header in the `EBDT' table on */ + /* function exit. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Metrics_Func)( FT_Stream stream, + TT_SBit_Range range, + TT_SBit_Metrics metrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_SBit_Image_Func */ + /* */ + /* <Description> */ + /* Load a given glyph sbit image from the font resource. This also */ + /* returns its metrics. */ + /* */ + /* <Input> */ + /* face :: */ + /* The target face object. */ + /* */ + /* strike_index :: */ + /* The strike index. */ + /* */ + /* glyph_index :: */ + /* The current glyph index. */ + /* */ + /* load_flags :: */ + /* The current load flags. */ + /* */ + /* stream :: */ + /* The input stream. */ + /* */ + /* <Output> */ + /* amap :: */ + /* The target pixmap. */ + /* */ + /* ametrics :: */ + /* A big sbit metrics structure for the glyph image. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* glyph sbit exists for the index. */ + /* */ + /* <Note> */ + /* The `map.buffer' field is always freed before the glyph is loaded. */ + /* */ + typedef FT_Error + (*TT_Load_SBit_Image_Func)( TT_Face face, + FT_ULong strike_index, + FT_UInt glyph_index, + FT_UInt load_flags, + FT_Stream stream, + FT_Bitmap *amap, + TT_SBit_MetricsRec *ametrics ); + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Set_SBit_Strike_OldFunc */ + /* */ + /* <Description> */ + /* Select an sbit strike for a given size request. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* req :: The size request. */ + /* */ + /* <Output> */ + /* astrike_index :: The index of the sbit strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* sbit strike exists for the selected ppem values. */ + /* */ + typedef FT_Error + (*TT_Set_SBit_Strike_OldFunc)( TT_Face face, + FT_UInt x_ppem, + FT_UInt y_ppem, + FT_ULong* astrike_index ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_CharMap_Load_Func */ + /* */ + /* <Description> */ + /* Loads a given TrueType character map into memory. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face object. */ + /* */ + /* stream :: A handle to the current stream object. */ + /* */ + /* <InOut> */ + /* cmap :: A pointer to a cmap object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The function assumes that the stream is already in use (i.e., */ + /* opened). In case of error, all partially allocated tables are */ + /* released. */ + /* */ + typedef FT_Error + (*TT_CharMap_Load_Func)( TT_Face face, + void* cmap, + FT_Stream input ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_CharMap_Free_Func */ + /* */ + /* <Description> */ + /* Destroys a character mapping table. */ + /* */ + /* <Input> */ + /* face :: A handle to the parent face object. */ + /* */ + /* cmap :: A handle to a cmap object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_CharMap_Free_Func)( TT_Face face, + void* cmap ); + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Set_SBit_Strike_Func */ + /* */ + /* <Description> */ + /* Select an sbit strike for a given size request. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* req :: The size request. */ + /* */ + /* <Output> */ + /* astrike_index :: The index of the sbit strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* sbit strike exists for the selected ppem values. */ + /* */ + typedef FT_Error + (*TT_Set_SBit_Strike_Func)( TT_Face face, + FT_Size_Request req, + FT_ULong* astrike_index ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Strike_Metrics_Func */ + /* */ + /* <Description> */ + /* Load the metrics of a given strike. */ + /* */ + /* <Input> */ + /* face :: The target face object. */ + /* */ + /* strike_index :: The strike index. */ + /* */ + /* <Output> */ + /* metrics :: the metrics of the strike. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. Returns an error if no */ + /* such sbit strike exists. */ + /* */ + typedef FT_Error + (*TT_Load_Strike_Metrics_Func)( TT_Face face, + FT_ULong strike_index, + FT_Size_Metrics* metrics ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_PS_Name_Func */ + /* */ + /* <Description> */ + /* Get the PostScript glyph name of a glyph. */ + /* */ + /* <Input> */ + /* idx :: The glyph index. */ + /* */ + /* PSname :: The address of a string pointer. Will be NULL in case */ + /* of error, otherwise it is a pointer to the glyph name. */ + /* */ + /* You must not modify the returned string! */ + /* */ + /* <Output> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_PS_Name_Func)( TT_Face face, + FT_UInt idx, + FT_String** PSname ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Metrics_Func */ + /* */ + /* <Description> */ + /* Load a metrics table, which is a table with a horizontal and a */ + /* vertical version. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load the vertical one. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Load_Metrics_Func)( TT_Face face, + FT_Stream stream, + FT_Bool vertical ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_Metrics_Func */ + /* */ + /* <Description> */ + /* Load the horizontal or vertical header in a face object. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* vertical :: A boolean flag. If set, load vertical metrics. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Get_Metrics_Func)( TT_Face face, + FT_Bool vertical, + FT_UInt gindex, + FT_Short* abearing, + FT_UShort* aadvance ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Load_Table_Func */ + /* */ + /* <Description> */ + /* Load a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The function uses `face->goto_table' to seek the stream to the */ + /* start of the table, except while loading the font directory. */ + /* */ + typedef FT_Error + (*TT_Load_Table_Func)( TT_Face face, + FT_Stream stream ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Free_Table_Func */ + /* */ + /* <Description> */ + /* Free a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + typedef void + (*TT_Free_Table_Func)( TT_Face face ); + + + /* + * @functype: + * TT_Face_GetKerningFunc + * + * @description: + * Return the horizontal kerning value between two glyphs. + * + * @input: + * face :: A handle to the source face object. + * left_glyph :: The left glyph index. + * right_glyph :: The right glyph index. + * + * @return: + * The kerning value in font units. + */ + typedef FT_Int + (*TT_Face_GetKerningFunc)( TT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_Interface */ + /* */ + /* <Description> */ + /* This structure holds pointers to the functions used to load and */ + /* free the basic tables that are required in a `sfnt' font file. */ + /* */ + /* <Fields> */ + /* Check the various xxx_Func() descriptions for details. */ + /* */ + typedef struct SFNT_Interface_ + { + TT_Loader_GotoTableFunc goto_table; + + TT_Init_Face_Func init_face; + TT_Load_Face_Func load_face; + TT_Done_Face_Func done_face; + FT_Module_Requester get_interface; + + TT_Load_Any_Func load_any; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_Load_SFNT_HeaderRec_Func load_sfnt_header; + TT_Load_Directory_Func load_directory; +#endif + + /* these functions are called by `load_face' but they can also */ + /* be called from external modules, if there is a need to do so */ + TT_Load_Table_Func load_head; + TT_Load_Metrics_Func load_hhea; + TT_Load_Table_Func load_cmap; + TT_Load_Table_Func load_maxp; + TT_Load_Table_Func load_os2; + TT_Load_Table_Func load_post; + + TT_Load_Table_Func load_name; + TT_Free_Table_Func free_name; + + /* optional tables */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_Load_Table_Func load_hdmx_stub; + TT_Free_Table_Func free_hdmx_stub; +#endif + + /* this field was called `load_kerning' up to version 2.1.10 */ + TT_Load_Table_Func load_kern; + + TT_Load_Table_Func load_gasp; + TT_Load_Table_Func load_pclt; + + /* see `ttload.h'; this field was called `load_bitmap_header' up to */ + /* version 2.1.10 */ + TT_Load_Table_Func load_bhed; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /* see `ttsbit.h' */ + TT_Set_SBit_Strike_OldFunc set_sbit_strike_stub; + TT_Load_Table_Func load_sbits_stub; + + /* + * The following two fields appeared in version 2.1.8, and were placed + * between `load_sbits' and `load_sbit_image'. We support them as a + * special exception since they are used by Xfont library within the + * X.Org xserver, and because the probability that other rogue clients + * use the other version 2.1.7 fields below is _extremely_ low. + * + * Note that this forces us to disable an interesting memory-saving + * optimization though... + */ + + TT_Find_SBit_Image_Func find_sbit_image; + TT_Load_SBit_Metrics_Func load_sbit_metrics; + +#endif + + TT_Load_SBit_Image_Func load_sbit_image; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_Free_Table_Func free_sbits_stub; +#endif + + /* see `ttpost.h' */ + TT_Get_PS_Name_Func get_psname; + TT_Free_Table_Func free_psnames; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_CharMap_Load_Func load_charmap_stub; + TT_CharMap_Free_Func free_charmap_stub; +#endif + + /* starting here, the structure differs from version 2.1.7 */ + + /* this field was introduced in version 2.1.8, named `get_psname' */ + TT_Face_GetKerningFunc get_kerning; + + /* new elements introduced after version 2.1.10 */ + + /* load the font directory, i.e., the offset table and */ + /* the table directory */ + TT_Load_Table_Func load_font_dir; + TT_Load_Metrics_Func load_hmtx; + + TT_Load_Table_Func load_eblc; + TT_Free_Table_Func free_eblc; + + TT_Set_SBit_Strike_Func set_sbit_strike; + TT_Load_Strike_Metrics_Func load_strike_metrics; + + TT_Get_Metrics_Func get_metrics; + + } SFNT_Interface; + + + /* transitional */ + typedef SFNT_Interface* SFNT_Service; + + +FT_END_HEADER + +#endif /* __SFNT_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/t1types.h b/utils/openttd/freetype/internal/t1types.h new file mode 100644 index 00000000000..047c6d59df0 --- /dev/null +++ b/utils/openttd/freetype/internal/t1types.h @@ -0,0 +1,252 @@ +/***************************************************************************/ +/* */ +/* t1types.h */ +/* */ +/* Basic Type1/Type2 type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1TYPES_H__ +#define __T1TYPES_H__ + + +#include <ft2build.h> +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TYPE1/TYPE2 TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_EncodingRec */ + /* */ + /* <Description> */ + /* A structure modeling a custom encoding. */ + /* */ + /* <Fields> */ + /* num_chars :: The number of character codes in the encoding. */ + /* Usually 256. */ + /* */ + /* code_first :: The lowest valid character code in the encoding. */ + /* */ + /* code_last :: The highest valid character code in the encoding. */ + /* */ + /* char_index :: An array of corresponding glyph indices. */ + /* */ + /* char_name :: An array of corresponding glyph names. */ + /* */ + typedef struct T1_EncodingRecRec_ + { + FT_Int num_chars; + FT_Int code_first; + FT_Int code_last; + + FT_UShort* char_index; + FT_String** char_name; + + } T1_EncodingRec, *T1_Encoding; + + + typedef enum T1_EncodingType_ + { + T1_ENCODING_TYPE_NONE = 0, + T1_ENCODING_TYPE_ARRAY, + T1_ENCODING_TYPE_STANDARD, + T1_ENCODING_TYPE_ISOLATIN1, + T1_ENCODING_TYPE_EXPERT + + } T1_EncodingType; + + + typedef struct T1_FontRec_ + { + PS_FontInfoRec font_info; /* font info dictionary */ + PS_PrivateRec private_dict; /* private dictionary */ + FT_String* font_name; /* top-level dictionary */ + + T1_EncodingType encoding_type; + T1_EncodingRec encoding; + + FT_Byte* subrs_block; + FT_Byte* charstrings_block; + FT_Byte* glyph_names_block; + + FT_Int num_subrs; + FT_Byte** subrs; + FT_PtrDist* subrs_len; + + FT_Int num_glyphs; + FT_String** glyph_names; /* array of glyph names */ + FT_Byte** charstrings; /* array of glyph charstrings */ + FT_PtrDist* charstrings_len; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + FT_BBox font_bbox; + FT_Long font_id; + + FT_Fixed stroke_width; + + } T1_FontRec, *T1_Font; + + + typedef struct CID_SubrsRec_ + { + FT_UInt num_subrs; + FT_Byte** code; + + } CID_SubrsRec, *CID_Subrs; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** AFM FONT INFORMATION STRUCTURES ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + typedef struct AFM_TrackKernRec_ + { + FT_Int degree; + FT_Fixed min_ptsize; + FT_Fixed min_kern; + FT_Fixed max_ptsize; + FT_Fixed max_kern; + + } AFM_TrackKernRec, *AFM_TrackKern; + + typedef struct AFM_KernPairRec_ + { + FT_Int index1; + FT_Int index2; + FT_Int x; + FT_Int y; + + } AFM_KernPairRec, *AFM_KernPair; + + typedef struct AFM_FontInfoRec_ + { + FT_Bool IsCIDFont; + FT_BBox FontBBox; + FT_Fixed Ascender; + FT_Fixed Descender; + AFM_TrackKern TrackKerns; /* free if non-NULL */ + FT_Int NumTrackKern; + AFM_KernPair KernPairs; /* free if non-NULL */ + FT_Int NumKernPair; + + } AFM_FontInfoRec, *AFM_FontInfo; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL T1_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct T1_FaceRec_* T1_Face; + typedef struct CID_FaceRec_* CID_Face; + + + typedef struct T1_FaceRec_ + { + FT_FaceRec root; + T1_FontRec type1; + const void* psnames; + const void* psaux; + const void* afm_data; + FT_CharMapRec charmaprecs[2]; + FT_CharMap charmaps[2]; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + PS_Unicodes unicode_map; +#endif + + /* support for Multiple Masters fonts */ + PS_Blend blend; + + /* undocumented, optional: indices of subroutines that express */ + /* the NormalizeDesignVector and the ConvertDesignVector procedure, */ + /* respectively, as Type 2 charstrings; -1 if keywords not present */ + FT_Int ndv_idx; + FT_Int cdv_idx; + + /* undocumented, optional: has the same meaning as len_buildchar */ + /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */ + FT_UInt len_buildchar; + FT_Int* buildchar; + + /* since version 2.1 - interface to PostScript hinter */ + const void* pshinter; + + } T1_FaceRec; + + + typedef struct CID_FaceRec_ + { + FT_FaceRec root; + void* psnames; + void* psaux; + CID_FaceInfoRec cid; + void* afm_data; + CID_Subrs subrs; + + /* since version 2.1 - interface to PostScript hinter */ + void* pshinter; + + /* since version 2.1.8, but was originally positioned after `afm_data' */ + FT_Byte* binary_data; /* used if hex data has been converted */ + FT_Stream cid_stream; + + } CID_FaceRec; + + +FT_END_HEADER + +#endif /* __T1TYPES_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/internal/tttypes.h b/utils/openttd/freetype/internal/tttypes.h new file mode 100644 index 00000000000..85fc27f74ee --- /dev/null +++ b/utils/openttd/freetype/internal/tttypes.h @@ -0,0 +1,1543 @@ +/***************************************************************************/ +/* */ +/* tttypes.h */ +/* */ +/* Basic SFNT/TrueType type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTTYPES_H__ +#define __TTTYPES_H__ + + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_OBJECTS_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** REQUIRED TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TTC_HeaderRec */ + /* */ + /* <Description> */ + /* TrueType collection header. This table contains the offsets of */ + /* the font headers of each distinct TrueType face in the file. */ + /* */ + /* <Fields> */ + /* tag :: Must be `ttc ' to indicate a TrueType collection. */ + /* */ + /* version :: The version number. */ + /* */ + /* count :: The number of faces in the collection. The */ + /* specification says this should be an unsigned long, but */ + /* we use a signed long since we need the value -1 for */ + /* specific purposes. */ + /* */ + /* offsets :: The offsets of the font headers, one per face. */ + /* */ + typedef struct TTC_HeaderRec_ + { + FT_ULong tag; + FT_Fixed version; + FT_Long count; + FT_ULong* offsets; + + } TTC_HeaderRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* SFNT_HeaderRec */ + /* */ + /* <Description> */ + /* SFNT file format header. */ + /* */ + /* <Fields> */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of tables in file. */ + /* */ + /* search_range :: Must be `16 * (max power of 2 <= num_tables)'. */ + /* */ + /* entry_selector :: Must be log2 of `search_range / 16'. */ + /* */ + /* range_shift :: Must be `num_tables * 16 - search_range'. */ + /* */ + typedef struct SFNT_HeaderRec_ + { + FT_ULong format_tag; + FT_UShort num_tables; + FT_UShort search_range; + FT_UShort entry_selector; + FT_UShort range_shift; + + FT_ULong offset; /* not in file */ + + } SFNT_HeaderRec, *SFNT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_TableRec */ + /* */ + /* <Description> */ + /* This structure describes a given table of a TrueType font. */ + /* */ + /* <Fields> */ + /* Tag :: A four-bytes tag describing the table. */ + /* */ + /* CheckSum :: The table checksum. This value can be ignored. */ + /* */ + /* Offset :: The offset of the table from the start of the TrueType */ + /* font in its resource. */ + /* */ + /* Length :: The table length (in bytes). */ + /* */ + typedef struct TT_TableRec_ + { + FT_ULong Tag; /* table type */ + FT_ULong CheckSum; /* table checksum */ + FT_ULong Offset; /* table file offset */ + FT_ULong Length; /* table length */ + + } TT_TableRec, *TT_Table; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_LongMetricsRec */ + /* */ + /* <Description> */ + /* A structure modeling the long metrics of the `hmtx' and `vmtx' */ + /* TrueType tables. The values are expressed in font units. */ + /* */ + /* <Fields> */ + /* advance :: The advance width or height for the glyph. */ + /* */ + /* bearing :: The left-side or top-side bearing for the glyph. */ + /* */ + typedef struct TT_LongMetricsRec_ + { + FT_UShort advance; + FT_Short bearing; + + } TT_LongMetricsRec, *TT_LongMetrics; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_ShortMetrics */ + /* */ + /* <Description> */ + /* A simple type to model the short metrics of the `hmtx' and `vmtx' */ + /* tables. */ + /* */ + typedef FT_Short TT_ShortMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameEntryRec */ + /* */ + /* <Description> */ + /* A structure modeling TrueType name records. Name records are used */ + /* to store important strings like family name, style name, */ + /* copyright, etc. in _localized_ versions (i.e., language, encoding, */ + /* etc). */ + /* */ + /* <Fields> */ + /* platformID :: The ID of the name's encoding platform. */ + /* */ + /* encodingID :: The platform-specific ID for the name's encoding. */ + /* */ + /* languageID :: The platform-specific ID for the name's language. */ + /* */ + /* nameID :: The ID specifying what kind of name this is. */ + /* */ + /* stringLength :: The length of the string in bytes. */ + /* */ + /* stringOffset :: The offset to the string in the `name' table. */ + /* */ + /* string :: A pointer to the string's bytes. Note that these */ + /* are usually UTF-16 encoded characters. */ + /* */ + typedef struct TT_NameEntryRec_ + { + FT_UShort platformID; + FT_UShort encodingID; + FT_UShort languageID; + FT_UShort nameID; + FT_UShort stringLength; + FT_ULong stringOffset; + + /* this last field is not defined in the spec */ + /* but used by the FreeType engine */ + + FT_Byte* string; + + } TT_NameEntryRec, *TT_NameEntry; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_NameTableRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType name table. */ + /* */ + /* <Fields> */ + /* format :: The format of the name table. */ + /* */ + /* numNameRecords :: The number of names in table. */ + /* */ + /* storageOffset :: The offset of the name table in the `name' */ + /* TrueType table. */ + /* */ + /* names :: An array of name records. */ + /* */ + /* stream :: the file's input stream. */ + /* */ + typedef struct TT_NameTableRec_ + { + FT_UShort format; + FT_UInt numNameRecords; + FT_UInt storageOffset; + TT_NameEntryRec* names; + FT_Stream stream; + + } TT_NameTableRec, *TT_NameTable; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** OPTIONAL TRUETYPE/OPENTYPE TABLES DEFINITIONS ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRangeRec */ + /* */ + /* <Description> */ + /* A tiny structure used to model a gasp range according to the */ + /* TrueType specification. */ + /* */ + /* <Fields> */ + /* maxPPEM :: The maximum ppem value to which `gaspFlag' applies. */ + /* */ + /* gaspFlag :: A flag describing the grid-fitting and anti-aliasing */ + /* modes to be used. */ + /* */ + typedef struct TT_GaspRangeRec_ + { + FT_UShort maxPPEM; + FT_UShort gaspFlag; + + } TT_GaspRangeRec, *TT_GaspRange; + + +#define TT_GASP_GRIDFIT 0x01 +#define TT_GASP_DOGRAY 0x02 + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GaspRec */ + /* */ + /* <Description> */ + /* A structure modeling the TrueType `gasp' table used to specify */ + /* grid-fitting and anti-aliasing behaviour. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numRanges :: The number of gasp ranges in table. */ + /* */ + /* gaspRanges :: An array of gasp ranges. */ + /* */ + typedef struct TT_Gasp_ + { + FT_UShort version; + FT_UShort numRanges; + TT_GaspRange gaspRanges; + + } TT_GaspRec; + + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HdmxEntryRec */ + /* */ + /* <Description> */ + /* A small structure used to model the pre-computed widths of a given */ + /* size. They are found in the `hdmx' table. */ + /* */ + /* <Fields> */ + /* ppem :: The pixels per EM value at which these metrics apply. */ + /* */ + /* max_width :: The maximum advance width for this metric. */ + /* */ + /* widths :: An array of widths. Note: These are 8-bit bytes. */ + /* */ + typedef struct TT_HdmxEntryRec_ + { + FT_Byte ppem; + FT_Byte max_width; + FT_Byte* widths; + + } TT_HdmxEntryRec, *TT_HdmxEntry; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HdmxRec */ + /* */ + /* <Description> */ + /* A structure used to model the `hdmx' table, which contains */ + /* pre-computed widths for a set of given sizes/dimensions. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* num_records :: The number of hdmx records. */ + /* */ + /* records :: An array of hdmx records. */ + /* */ + typedef struct TT_HdmxRec_ + { + FT_UShort version; + FT_Short num_records; + TT_HdmxEntry records; + + } TT_HdmxRec, *TT_Hdmx; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Kern0_PairRec */ + /* */ + /* <Description> */ + /* A structure used to model a kerning pair for the kerning table */ + /* format 0. The engine now loads this table if it finds one in the */ + /* font file. */ + /* */ + /* <Fields> */ + /* left :: The index of the left glyph in pair. */ + /* */ + /* right :: The index of the right glyph in pair. */ + /* */ + /* value :: The kerning distance. A positive value spaces the */ + /* glyphs, a negative one makes them closer. */ + /* */ + typedef struct TT_Kern0_PairRec_ + { + FT_UShort left; /* index of left glyph in pair */ + FT_UShort right; /* index of right glyph in pair */ + FT_FWord value; /* kerning value */ + + } TT_Kern0_PairRec, *TT_Kern0_Pair; + +#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** EMBEDDED BITMAPS SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_MetricsRec */ + /* */ + /* <Description> */ + /* A structure used to hold the big metrics of a given glyph bitmap */ + /* in a TrueType or OpenType font. These are usually found in the */ + /* `EBDT' (Microsoft) or `bloc' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* horiBearingX :: The horizontal left bearing. */ + /* */ + /* horiBearingY :: The horizontal top bearing. */ + /* */ + /* horiAdvance :: The horizontal advance. */ + /* */ + /* vertBearingX :: The vertical left bearing. */ + /* */ + /* vertBearingY :: The vertical top bearing. */ + /* */ + /* vertAdvance :: The vertical advance. */ + /* */ + typedef struct TT_SBit_MetricsRec_ + { + FT_Byte height; + FT_Byte width; + + FT_Char horiBearingX; + FT_Char horiBearingY; + FT_Byte horiAdvance; + + FT_Char vertBearingX; + FT_Char vertBearingY; + FT_Byte vertAdvance; + + } TT_SBit_MetricsRec, *TT_SBit_Metrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_SmallMetricsRec */ + /* */ + /* <Description> */ + /* A structure used to hold the small metrics of a given glyph bitmap */ + /* in a TrueType or OpenType font. These are usually found in the */ + /* `EBDT' (Microsoft) or the `bdat' (Apple) table. */ + /* */ + /* <Fields> */ + /* height :: The glyph height in pixels. */ + /* */ + /* width :: The glyph width in pixels. */ + /* */ + /* bearingX :: The left-side bearing. */ + /* */ + /* bearingY :: The top-side bearing. */ + /* */ + /* advance :: The advance width or height. */ + /* */ + typedef struct TT_SBit_Small_Metrics_ + { + FT_Byte height; + FT_Byte width; + + FT_Char bearingX; + FT_Char bearingY; + FT_Byte advance; + + } TT_SBit_SmallMetricsRec, *TT_SBit_SmallMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_LineMetricsRec */ + /* */ + /* <Description> */ + /* A structure used to describe the text line metrics of a given */ + /* bitmap strike, for either a horizontal or vertical layout. */ + /* */ + /* <Fields> */ + /* ascender :: The ascender in pixels. */ + /* */ + /* descender :: The descender in pixels. */ + /* */ + /* max_width :: The maximum glyph width in pixels. */ + /* */ + /* caret_slope_enumerator :: Rise of the caret slope, typically set */ + /* to 1 for non-italic fonts. */ + /* */ + /* caret_slope_denominator :: Rise of the caret slope, typically set */ + /* to 0 for non-italic fonts. */ + /* */ + /* caret_offset :: Offset in pixels to move the caret for */ + /* proper positioning. */ + /* */ + /* min_origin_SB :: Minimum of horiBearingX (resp. */ + /* vertBearingY). */ + /* min_advance_SB :: Minimum of */ + /* */ + /* horizontal advance - */ + /* ( horiBearingX + width ) */ + /* */ + /* resp. */ + /* */ + /* vertical advance - */ + /* ( vertBearingY + height ) */ + /* */ + /* max_before_BL :: Maximum of horiBearingY (resp. */ + /* vertBearingY). */ + /* */ + /* min_after_BL :: Minimum of */ + /* */ + /* horiBearingY - height */ + /* */ + /* resp. */ + /* */ + /* vertBearingX - width */ + /* */ + /* pads :: Unused (to make the size of the record */ + /* a multiple of 32 bits. */ + /* */ + typedef struct TT_SBit_LineMetricsRec_ + { + FT_Char ascender; + FT_Char descender; + FT_Byte max_width; + FT_Char caret_slope_numerator; + FT_Char caret_slope_denominator; + FT_Char caret_offset; + FT_Char min_origin_SB; + FT_Char min_advance_SB; + FT_Char max_before_BL; + FT_Char min_after_BL; + FT_Char pads[2]; + + } TT_SBit_LineMetricsRec, *TT_SBit_LineMetrics; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_RangeRec */ + /* */ + /* <Description> */ + /* A TrueType/OpenType subIndexTable as defined in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* first_glyph :: The first glyph index in the range. */ + /* */ + /* last_glyph :: The last glyph index in the range. */ + /* */ + /* index_format :: The format of index table. Valid values are 1 */ + /* to 5. */ + /* */ + /* image_format :: The format of `EBDT' image data. */ + /* */ + /* image_offset :: The offset to image data in `EBDT'. */ + /* */ + /* image_size :: For index formats 2 and 5. This is the size in */ + /* bytes of each glyph bitmap. */ + /* */ + /* big_metrics :: For index formats 2 and 5. This is the big */ + /* metrics for each glyph bitmap. */ + /* */ + /* num_glyphs :: For index formats 4 and 5. This is the number of */ + /* glyphs in the code array. */ + /* */ + /* glyph_offsets :: For index formats 1 and 3. */ + /* */ + /* glyph_codes :: For index formats 4 and 5. */ + /* */ + /* table_offset :: The offset of the index table in the `EBLC' */ + /* table. Only used during strike loading. */ + /* */ + typedef struct TT_SBit_RangeRec_ + { + FT_UShort first_glyph; + FT_UShort last_glyph; + + FT_UShort index_format; + FT_UShort image_format; + FT_ULong image_offset; + + FT_ULong image_size; + TT_SBit_MetricsRec metrics; + FT_ULong num_glyphs; + + FT_ULong* glyph_offsets; + FT_UShort* glyph_codes; + + FT_ULong table_offset; + + } TT_SBit_RangeRec, *TT_SBit_Range; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_StrikeRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap strike in the `EBLC' */ + /* (Microsoft) or `bloc' (Apple) tables. */ + /* */ + /* <Fields> */ + /* num_index_ranges :: The number of index ranges. */ + /* */ + /* index_ranges :: An array of glyph index ranges. */ + /* */ + /* color_ref :: Unused. `color_ref' is put in for future */ + /* enhancements, but these fields are already */ + /* in use by other platforms (e.g. Newton). */ + /* For details, please see */ + /* */ + /* http://fonts.apple.com/ */ + /* TTRefMan/RM06/Chap6bloc.html */ + /* */ + /* hori :: The line metrics for horizontal layouts. */ + /* */ + /* vert :: The line metrics for vertical layouts. */ + /* */ + /* start_glyph :: The lowest glyph index for this strike. */ + /* */ + /* end_glyph :: The highest glyph index for this strike. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* bit_depth :: The bit depth. Valid values are 1, 2, 4, */ + /* and 8. */ + /* */ + /* flags :: Is this a vertical or horizontal strike? For */ + /* details, please see */ + /* */ + /* http://fonts.apple.com/ */ + /* TTRefMan/RM06/Chap6bloc.html */ + /* */ + typedef struct TT_SBit_StrikeRec_ + { + FT_Int num_ranges; + TT_SBit_Range sbit_ranges; + FT_ULong ranges_offset; + + FT_ULong color_ref; + + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_UShort start_glyph; + FT_UShort end_glyph; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte bit_depth; + FT_Char flags; + + } TT_SBit_StrikeRec, *TT_SBit_Strike; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ComponentRec */ + /* */ + /* <Description> */ + /* A simple structure to describe a compound sbit element. */ + /* */ + /* <Fields> */ + /* glyph_code :: The element's glyph index. */ + /* */ + /* x_offset :: The element's left bearing. */ + /* */ + /* y_offset :: The element's top bearing. */ + /* */ + typedef struct TT_SBit_ComponentRec_ + { + FT_UShort glyph_code; + FT_Char x_offset; + FT_Char y_offset; + + } TT_SBit_ComponentRec, *TT_SBit_Component; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_SBit_ScaleRec */ + /* */ + /* <Description> */ + /* A structure used describe a given bitmap scaling table, as defined */ + /* in the `EBSC' table. */ + /* */ + /* <Fields> */ + /* hori :: The horizontal line metrics. */ + /* */ + /* vert :: The vertical line metrics. */ + /* */ + /* x_ppem :: The number of horizontal pixels per EM. */ + /* */ + /* y_ppem :: The number of vertical pixels per EM. */ + /* */ + /* x_ppem_substitute :: Substitution x_ppem value. */ + /* */ + /* y_ppem_substitute :: Substitution y_ppem value. */ + /* */ + typedef struct TT_SBit_ScaleRec_ + { + TT_SBit_LineMetricsRec hori; + TT_SBit_LineMetricsRec vert; + + FT_Byte x_ppem; + FT_Byte y_ppem; + + FT_Byte x_ppem_substitute; + FT_Byte y_ppem_substitute; + + } TT_SBit_ScaleRec, *TT_SBit_Scale; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** POSTSCRIPT GLYPH NAMES SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_20Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.0. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of named glyphs in the table. */ + /* */ + /* num_names :: The number of PS names stored in the table. */ + /* */ + /* glyph_indices :: The indices of the glyphs in the names arrays. */ + /* */ + /* glyph_names :: The PS names not in Mac Encoding. */ + /* */ + typedef struct TT_Post_20Rec_ + { + FT_UShort num_glyphs; + FT_UShort num_names; + FT_UShort* glyph_indices; + FT_Char** glyph_names; + + } TT_Post_20Rec, *TT_Post_20; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_25Rec */ + /* */ + /* <Description> */ + /* Postscript names sub-table, format 2.5. Stores the PS name of */ + /* each glyph in the font face. */ + /* */ + /* <Fields> */ + /* num_glyphs :: The number of glyphs in the table. */ + /* */ + /* offsets :: An array of signed offsets in a normal Mac */ + /* Postscript name encoding. */ + /* */ + typedef struct TT_Post_25_ + { + FT_UShort num_glyphs; + FT_Char* offsets; + + } TT_Post_25Rec, *TT_Post_25; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Post_NamesRec */ + /* */ + /* <Description> */ + /* Postscript names table, either format 2.0 or 2.5. */ + /* */ + /* <Fields> */ + /* loaded :: A flag to indicate whether the PS names are loaded. */ + /* */ + /* format_20 :: The sub-table used for format 2.0. */ + /* */ + /* format_25 :: The sub-table used for format 2.5. */ + /* */ + typedef struct TT_Post_NamesRec_ + { + FT_Bool loaded; + + union + { + TT_Post_20Rec format_20; + TT_Post_25Rec format_25; + + } names; + + } TT_Post_NamesRec, *TT_Post_Names; + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** GX VARIATION TABLE SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + typedef struct GX_BlendRec_ *GX_Blend; +#endif + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** EMBEDDED BDF PROPERTIES TABLE SUPPORT ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /* + * These types are used to support a `BDF ' table that isn't part of the + * official TrueType specification. It is mainly used in SFNT-based + * bitmap fonts that were generated from a set of BDF fonts. + * + * The format of the table is as follows. + * + * USHORT version `BDF ' table version number, should be 0x0001. + * USHORT strikeCount Number of strikes (bitmap sizes) in this table. + * ULONG stringTable Offset (from start of BDF table) to string + * table. + * + * This is followed by an array of `strikeCount' descriptors, having the + * following format. + * + * USHORT ppem Vertical pixels per EM for this strike. + * USHORT numItems Number of items for this strike (properties and + * atoms). Maximum is 255. + * + * This array in turn is followed by `strikeCount' value sets. Each + * `value set' is an array of `numItems' items with the following format. + * + * ULONG item_name Offset in string table to item name. + * USHORT item_type The item type. Possible values are + * 0 => string (e.g., COMMENT) + * 1 => atom (e.g., FONT or even SIZE) + * 2 => int32 + * 3 => uint32 + * 0x10 => A flag to indicate a properties. This + * is ORed with the above values. + * ULONG item_value For strings => Offset into string table without + * the corresponding double quotes. + * For atoms => Offset into string table. + * For integers => Direct value. + * + * All strings in the string table consist of bytes and are + * zero-terminated. + * + */ + +#ifdef TT_CONFIG_OPTION_BDF + + typedef struct TT_BDFRec_ + { + FT_Byte* table; + FT_Byte* table_end; + FT_Byte* strings; + FT_UInt32 strings_size; + FT_UInt num_strikes; + FT_Bool loaded; + + } TT_BDFRec, *TT_BDF; + +#endif /* TT_CONFIG_OPTION_BDF */ + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /*** ***/ + /*** ***/ + /*** ORIGINAL TT_FACE CLASS DEFINITION ***/ + /*** ***/ + /*** ***/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This structure/class is defined here because it is common to the */ + /* following formats: TTF, OpenType-TT, and OpenType-CFF. */ + /* */ + /* Note, however, that the classes TT_Size and TT_GlyphSlot are not */ + /* shared between font drivers, and are thus defined in `ttobjs.h'. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* A handle to a TrueType face/font object. A TT_Face encapsulates */ + /* the resolution and scaling independent parts of a TrueType font */ + /* resource. */ + /* */ + /* <Note> */ + /* The TT_Face structure is also used as a `parent class' for the */ + /* OpenType-CFF class (T2_Face). */ + /* */ + typedef struct TT_FaceRec_* TT_Face; + + + /* a function type used for the truetype bytecode interpreter hooks */ + typedef FT_Error + (*TT_Interpreter)( void* exec_context ); + + /* forward declaration */ + typedef struct TT_LoaderRec_* TT_Loader; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_GotoTableFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given TrueType table. */ + /* */ + /* <Input> */ + /* face :: A handle to the target face object. */ + /* */ + /* tag :: A 4-byte tag used to name the table. */ + /* */ + /* stream :: The input stream. */ + /* */ + /* <Output> */ + /* length :: The length of the table in bytes. Set to 0 if not */ + /* needed. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* The stream cursor must be at the font file's origin. */ + /* */ + typedef FT_Error + (*TT_Loader_GotoTableFunc)( TT_Face face, + FT_ULong tag, + FT_Stream stream, + FT_ULong* length ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_StartGlyphFunc */ + /* */ + /* <Description> */ + /* Seeks a stream to the start of a given glyph element, and opens a */ + /* frame for it. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* glyph index :: The index of the glyph to access. */ + /* */ + /* offset :: The offset of the glyph according to the */ + /* `locations' table. */ + /* */ + /* byte_count :: The size of the frame in bytes. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + /* <Note> */ + /* This function is normally equivalent to FT_STREAM_SEEK(offset) */ + /* followed by FT_FRAME_ENTER(byte_count) with the loader's stream, */ + /* but alternative formats (e.g. compressed ones) might use something */ + /* different. */ + /* */ + typedef FT_Error + (*TT_Loader_StartGlyphFunc)( TT_Loader loader, + FT_UInt glyph_index, + FT_ULong offset, + FT_UInt byte_count ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_ReadGlyphFunc */ + /* */ + /* <Description> */ + /* Reads one glyph element (its header, a simple glyph, or a */ + /* composite) from the loader's current stream frame. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + typedef FT_Error + (*TT_Loader_ReadGlyphFunc)( TT_Loader loader ); + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Loader_EndGlyphFunc */ + /* */ + /* <Description> */ + /* Closes the current loader stream frame for the glyph. */ + /* */ + /* <Input> */ + /* loader :: The current TrueType glyph loader object. */ + /* */ + typedef void + (*TT_Loader_EndGlyphFunc)( TT_Loader loader ); + + + /*************************************************************************/ + /* */ + /* TrueType Face Type */ + /* */ + /* <Struct> */ + /* TT_Face */ + /* */ + /* <Description> */ + /* The TrueType face class. These objects model the resolution and */ + /* point-size independent data found in a TrueType font file. */ + /* */ + /* <Fields> */ + /* root :: The base FT_Face structure, managed by the */ + /* base layer. */ + /* */ + /* ttc_header :: The TrueType collection header, used when */ + /* the file is a `ttc' rather than a `ttf'. */ + /* For ordinary font files, the field */ + /* `ttc_header.count' is set to 0. */ + /* */ + /* format_tag :: The font format tag. */ + /* */ + /* num_tables :: The number of TrueType tables in this font */ + /* file. */ + /* */ + /* dir_tables :: The directory of TrueType tables for this */ + /* font file. */ + /* */ + /* header :: The font's font header (`head' table). */ + /* Read on font opening. */ + /* */ + /* horizontal :: The font's horizontal header (`hhea' */ + /* table). This field also contains the */ + /* associated horizontal metrics table */ + /* (`hmtx'). */ + /* */ + /* max_profile :: The font's maximum profile table. Read on */ + /* font opening. Note that some maximum */ + /* values cannot be taken directly from this */ + /* table. We thus define additional fields */ + /* below to hold the computed maxima. */ + /* */ + /* vertical_info :: A boolean which is set when the font file */ + /* contains vertical metrics. If not, the */ + /* value of the `vertical' field is */ + /* undefined. */ + /* */ + /* vertical :: The font's vertical header (`vhea' table). */ + /* This field also contains the associated */ + /* vertical metrics table (`vmtx'), if found. */ + /* IMPORTANT: The contents of this field is */ + /* undefined if the `verticalInfo' field is */ + /* unset. */ + /* */ + /* num_names :: The number of name records within this */ + /* TrueType font. */ + /* */ + /* name_table :: The table of name records (`name'). */ + /* */ + /* os2 :: The font's OS/2 table (`OS/2'). */ + /* */ + /* postscript :: The font's PostScript table (`post' */ + /* table). The PostScript glyph names are */ + /* not loaded by the driver on face opening. */ + /* See the `ttpost' module for more details. */ + /* */ + /* cmap_table :: Address of the face's `cmap' SFNT table */ + /* in memory (it's an extracted frame). */ + /* */ + /* cmap_size :: The size in bytes of the `cmap_table' */ + /* described above. */ + /* */ + /* goto_table :: A function called by each TrueType table */ + /* loader to position a stream's cursor to */ + /* the start of a given table according to */ + /* its tag. It defaults to TT_Goto_Face but */ + /* can be different for strange formats (e.g. */ + /* Type 42). */ + /* */ + /* access_glyph_frame :: A function used to access the frame of a */ + /* given glyph within the face's font file. */ + /* */ + /* forget_glyph_frame :: A function used to forget the frame of a */ + /* given glyph when all data has been loaded. */ + /* */ + /* read_glyph_header :: A function used to read a glyph header. */ + /* It must be called between an `access' and */ + /* `forget'. */ + /* */ + /* read_simple_glyph :: A function used to read a simple glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* read_composite_glyph :: A function used to read a composite glyph. */ + /* It must be called after the header was */ + /* read, and before the `forget'. */ + /* */ + /* sfnt :: A pointer to the SFNT service. */ + /* */ + /* psnames :: A pointer to the PostScript names service. */ + /* */ + /* hdmx :: The face's horizontal device metrics */ + /* (`hdmx' table). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* gasp :: The grid-fitting and scaling properties */ + /* table (`gasp'). This table is optional in */ + /* TrueType/OpenType fonts. */ + /* */ + /* pclt :: The `pclt' SFNT table. */ + /* */ + /* num_sbit_strikes :: The number of sbit strikes, i.e., bitmap */ + /* sizes, embedded in this font. */ + /* */ + /* sbit_strikes :: An array of sbit strikes embedded in this */ + /* font. This table is optional in a */ + /* TrueType/OpenType font. */ + /* */ + /* num_sbit_scales :: The number of sbit scales for this font. */ + /* */ + /* sbit_scales :: Array of sbit scales embedded in this */ + /* font. This table is optional in a */ + /* TrueType/OpenType font. */ + /* */ + /* postscript_names :: A table used to store the Postscript names */ + /* of the glyphs for this font. See the */ + /* file `ttconfig.h' for comments on the */ + /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ + /* */ + /* num_locations :: The number of glyph locations in this */ + /* TrueType file. This should be */ + /* identical to the number of glyphs. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* glyph_locations :: An array of longs. These are offsets to */ + /* glyph data within the `glyf' table. */ + /* Ignored for Type 2 font faces. */ + /* */ + /* glyf_len :: The length of the `glyf' table. Needed */ + /* for malformed `loca' tables. */ + /* */ + /* font_program_size :: Size in bytecodes of the face's font */ + /* program. 0 if none defined. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* font_program :: The face's font program (bytecode stream) */ + /* executed at load time, also used during */ + /* glyph rendering. Comes from the `fpgm' */ + /* table. Ignored for Type 2 font fonts. */ + /* */ + /* cvt_program_size :: The size in bytecodes of the face's cvt */ + /* program. Ignored for Type 2 fonts. */ + /* */ + /* cvt_program :: The face's cvt program (bytecode stream) */ + /* executed each time an instance/size is */ + /* changed/reset. Comes from the `prep' */ + /* table. Ignored for Type 2 fonts. */ + /* */ + /* cvt_size :: Size of the control value table (in */ + /* entries). Ignored for Type 2 fonts. */ + /* */ + /* cvt :: The face's original control value table. */ + /* Coordinates are expressed in unscaled font */ + /* units. Comes from the `cvt ' table. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* num_kern_pairs :: The number of kerning pairs present in the */ + /* font file. The engine only loads the */ + /* first horizontal format 0 kern table it */ + /* finds in the font file. Ignored for */ + /* Type 2 fonts. */ + /* */ + /* kern_table_index :: The index of the kerning table in the font */ + /* kerning directory. Ignored for Type 2 */ + /* fonts. */ + /* */ + /* interpreter :: A pointer to the TrueType bytecode */ + /* interpreters field is also used to hook */ + /* the debugger in `ttdebug'. */ + /* */ + /* unpatented_hinting :: If true, use only unpatented methods in */ + /* the bytecode interpreter. */ + /* */ + /* doblend :: A boolean which is set if the font should */ + /* be blended (this is for GX var). */ + /* */ + /* blend :: Contains the data needed to control GX */ + /* variation tables (rather like Multiple */ + /* Master data). */ + /* */ + /* extra :: Reserved for third-party font drivers. */ + /* */ + /* postscript_name :: The PS name of the font. Used by the */ + /* postscript name service. */ + /* */ + typedef struct TT_FaceRec_ + { + FT_FaceRec root; + + TTC_HeaderRec ttc_header; + + FT_ULong format_tag; + FT_UShort num_tables; + TT_Table dir_tables; + + TT_Header header; /* TrueType header table */ + TT_HoriHeader horizontal; /* TrueType horizontal header */ + + TT_MaxProfile max_profile; +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_ULong max_components; /* stubbed to 0 */ +#endif + + FT_Bool vertical_info; + TT_VertHeader vertical; /* TT Vertical header, if present */ + + FT_UShort num_names; /* number of name records */ + TT_NameTableRec name_table; /* name table */ + + TT_OS2 os2; /* TrueType OS/2 table */ + TT_Postscript postscript; /* TrueType Postscript table */ + + FT_Byte* cmap_table; /* extracted `cmap' table */ + FT_ULong cmap_size; + + TT_Loader_GotoTableFunc goto_table; + + TT_Loader_StartGlyphFunc access_glyph_frame; + TT_Loader_EndGlyphFunc forget_glyph_frame; + TT_Loader_ReadGlyphFunc read_glyph_header; + TT_Loader_ReadGlyphFunc read_simple_glyph; + TT_Loader_ReadGlyphFunc read_composite_glyph; + + /* a typeless pointer to the SFNT_Interface table used to load */ + /* the basic TrueType tables in the face object */ + void* sfnt; + + /* a typeless pointer to the FT_Service_PsCMapsRec table used to */ + /* handle glyph names <-> unicode & Mac values */ + void* psnames; + + + /***********************************************************************/ + /* */ + /* Optional TrueType/OpenType tables */ + /* */ + /***********************************************************************/ + + /* horizontal device metrics */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + TT_HdmxRec hdmx; +#endif + + /* grid-fitting and scaling table */ + TT_GaspRec gasp; /* the `gasp' table */ + + /* PCL 5 table */ + TT_PCLT pclt; + + /* embedded bitmaps support */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_ULong num_sbit_strikes; + TT_SBit_Strike sbit_strikes; +#endif + + FT_ULong num_sbit_scales; + TT_SBit_Scale sbit_scales; + + /* postscript names table */ + TT_Post_NamesRec postscript_names; + + + /***********************************************************************/ + /* */ + /* TrueType-specific fields (ignored by the OTF-Type2 driver) */ + /* */ + /***********************************************************************/ + + /* the glyph locations */ +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + FT_UShort num_locations_stub; + FT_Long* glyph_locations_stub; +#endif + + /* the font program, if any */ + FT_ULong font_program_size; + FT_Byte* font_program; + + /* the cvt program, if any */ + FT_ULong cvt_program_size; + FT_Byte* cvt_program; + + /* the original, unscaled, control value table */ + FT_ULong cvt_size; + FT_Short* cvt; + +#ifdef FT_CONFIG_OPTION_OLD_INTERNALS + /* the format 0 kerning table, if any */ + FT_Int num_kern_pairs; + FT_Int kern_table_index; + TT_Kern0_Pair kern_pairs; +#endif + + /* A pointer to the bytecode interpreter to use. This is also */ + /* used to hook the debugger for the `ttdebug' utility. */ + TT_Interpreter interpreter; + +#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING + /* Use unpatented hinting only. */ + FT_Bool unpatented_hinting; +#endif + + /***********************************************************************/ + /* */ + /* Other tables or fields. This is used by derivative formats like */ + /* OpenType. */ + /* */ + /***********************************************************************/ + + FT_Generic extra; + + const char* postscript_name; + + /* since version 2.1.8, but was originally placed after */ + /* `glyph_locations_stub' */ + FT_ULong glyf_len; + + /* since version 2.1.8, but was originally placed before `extra' */ +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Bool doblend; + GX_Blend blend; +#endif + + /* since version 2.2 */ + + FT_Byte* horz_metrics; + FT_ULong horz_metrics_size; + + FT_Byte* vert_metrics; + FT_ULong vert_metrics_size; + + FT_UInt num_locations; + FT_Byte* glyph_locations; + + FT_Byte* hdmx_table; + FT_ULong hdmx_table_size; + FT_UInt hdmx_record_count; + FT_ULong hdmx_record_size; + FT_Byte* hdmx_record_sizes; + + FT_Byte* sbit_table; + FT_ULong sbit_table_size; + FT_UInt sbit_num_strikes; + + FT_Byte* kern_table; + FT_ULong kern_table_size; + FT_UInt num_kern_tables; + FT_UInt32 kern_avail_bits; + FT_UInt32 kern_order_bits; + +#ifdef TT_CONFIG_OPTION_BDF + TT_BDFRec bdf; +#endif /* TT_CONFIG_OPTION_BDF */ + + /* since 2.3.0 */ + FT_ULong horz_metrics_offset; + FT_ULong vert_metrics_offset; + + } TT_FaceRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_GlyphZoneRec */ + /* */ + /* <Description> */ + /* A glyph zone is used to load, scale and hint glyph outline */ + /* coordinates. */ + /* */ + /* <Fields> */ + /* memory :: A handle to the memory manager. */ + /* */ + /* max_points :: The maximal size in points of the zone. */ + /* */ + /* max_contours :: Max size in links contours of the zone. */ + /* */ + /* n_points :: The current number of points in the zone. */ + /* */ + /* n_contours :: The current number of contours in the zone. */ + /* */ + /* org :: The original glyph coordinates (font */ + /* units/scaled). */ + /* */ + /* cur :: The current glyph coordinates (scaled/hinted). */ + /* */ + /* tags :: The point control tags. */ + /* */ + /* contours :: The contours end points. */ + /* */ + /* first_point :: Offset of the current subglyph's first point. */ + /* */ + typedef struct TT_GlyphZoneRec_ + { + FT_Memory memory; + FT_UShort max_points; + FT_UShort max_contours; + FT_UShort n_points; /* number of points in zone */ + FT_Short n_contours; /* number of contours */ + + FT_Vector* org; /* original point coordinates */ + FT_Vector* cur; /* current point coordinates */ + FT_Vector* orus; /* original (unscaled) point coordinates */ + + FT_Byte* tags; /* current touch flags */ + FT_UShort* contours; /* contour end points */ + + FT_UShort first_point; /* offset of first (#0) point */ + + } TT_GlyphZoneRec, *TT_GlyphZone; + + + /* handle to execution context */ + typedef struct TT_ExecContextRec_* TT_ExecContext; + + /* glyph loader structure */ + typedef struct TT_LoaderRec_ + { + FT_Face face; + FT_Size size; + FT_GlyphSlot glyph; + FT_GlyphLoader gloader; + + FT_ULong load_flags; + FT_UInt glyph_index; + + FT_Stream stream; + FT_Int byte_len; + + FT_Short n_contours; + FT_BBox bbox; + FT_Int left_bearing; + FT_Int advance; + FT_Int linear; + FT_Bool linear_def; + FT_Bool preserve_pps; + FT_Vector pp1; + FT_Vector pp2; + + FT_ULong glyf_offset; + + /* the zone where we load our glyphs */ + TT_GlyphZoneRec base; + TT_GlyphZoneRec zone; + + TT_ExecContext exec; + FT_Byte* instructions; + FT_ULong ins_pos; + + /* for possible extensibility in other formats */ + void* other; + + /* since version 2.1.8 */ + FT_Int top_bearing; + FT_Int vadvance; + FT_Vector pp3; + FT_Vector pp4; + + /* since version 2.2.1 */ + FT_Byte* cursor; + FT_Byte* limit; + + } TT_LoaderRec; + + +FT_END_HEADER + +#endif /* __TTTYPES_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/t1tables.h b/utils/openttd/freetype/t1tables.h new file mode 100644 index 00000000000..204d7a71b3f --- /dev/null +++ b/utils/openttd/freetype/t1tables.h @@ -0,0 +1,504 @@ +/***************************************************************************/ +/* */ +/* t1tables.h */ +/* */ +/* Basic Type 1/Type 2 tables definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __T1TABLES_H__ +#define __T1TABLES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* type1_tables */ + /* */ + /* <Title> */ + /* Type 1 Tables */ + /* */ + /* <Abstract> */ + /* Type~1 (PostScript) specific font tables. */ + /* */ + /* <Description> */ + /* This section contains the definition of Type 1-specific tables, */ + /* including structures related to other PostScript font formats. */ + /* */ + /*************************************************************************/ + + + /* Note that we separate font data in PS_FontInfoRec and PS_PrivateRec */ + /* structures in order to support Multiple Master fonts. */ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfoRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 FontInfo dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* FontInfo dictionary. */ + /* */ + typedef struct PS_FontInfoRec_ + { + FT_String* version; + FT_String* notice; + FT_String* full_name; + FT_String* family_name; + FT_String* weight; + FT_Long italic_angle; + FT_Bool is_fixed_pitch; + FT_Short underline_position; + FT_UShort underline_thickness; + + } PS_FontInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_FontInfo */ + /* */ + /* <Description> */ + /* A handle to a @PS_FontInfoRec structure. */ + /* */ + typedef struct PS_FontInfoRec_* PS_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_FontInfo */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_FontInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_FontInfoRec T1_FontInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_PrivateRec */ + /* */ + /* <Description> */ + /* A structure used to model a Type~1 or Type~2 private dictionary. */ + /* Note that for Multiple Master fonts, each instance has its own */ + /* Private dictionary. */ + /* */ + typedef struct PS_PrivateRec_ + { + FT_Int unique_id; + FT_Int lenIV; + + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Short blue_values[14]; + FT_Short other_blues[10]; + + FT_Short family_blues [14]; + FT_Short family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Int blue_shift; + FT_Int blue_fuzz; + + FT_UShort standard_width[1]; + FT_UShort standard_height[1]; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Bool force_bold; + FT_Bool round_stem_up; + + FT_Short snap_widths [13]; /* including std width */ + FT_Short snap_heights[13]; /* including std height */ + + FT_Fixed expansion_factor; + + FT_Long language_group; + FT_Long password; + + FT_Short min_feature[2]; + + } PS_PrivateRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* PS_Private */ + /* */ + /* <Description> */ + /* A handle to a @PS_PrivateRec structure. */ + /* */ + typedef struct PS_PrivateRec_* PS_Private; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* T1_Private */ + /* */ + /* <Description> */ + /* This type is equivalent to @PS_PrivateRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef PS_PrivateRec T1_Private; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* T1_Blend_Flags */ + /* */ + /* <Description> */ + /* A set of flags used to indicate which fields are present in a */ + /* given blend dictionary (font info or private). Used to support */ + /* Multiple Masters fonts. */ + /* */ + typedef enum T1_Blend_Flags_ + { + /*# required fields in a FontInfo blend dictionary */ + T1_BLEND_UNDERLINE_POSITION = 0, + T1_BLEND_UNDERLINE_THICKNESS, + T1_BLEND_ITALIC_ANGLE, + + /*# required fields in a Private blend dictionary */ + T1_BLEND_BLUE_VALUES, + T1_BLEND_OTHER_BLUES, + T1_BLEND_STANDARD_WIDTH, + T1_BLEND_STANDARD_HEIGHT, + T1_BLEND_STEM_SNAP_WIDTHS, + T1_BLEND_STEM_SNAP_HEIGHTS, + T1_BLEND_BLUE_SCALE, + T1_BLEND_BLUE_SHIFT, + T1_BLEND_FAMILY_BLUES, + T1_BLEND_FAMILY_OTHER_BLUES, + T1_BLEND_FORCE_BOLD, + + /*# never remove */ + T1_BLEND_MAX + + } T1_Blend_Flags; + + /* */ + + + /*# backwards compatible definitions */ +#define t1_blend_underline_position T1_BLEND_UNDERLINE_POSITION +#define t1_blend_underline_thickness T1_BLEND_UNDERLINE_THICKNESS +#define t1_blend_italic_angle T1_BLEND_ITALIC_ANGLE +#define t1_blend_blue_values T1_BLEND_BLUE_VALUES +#define t1_blend_other_blues T1_BLEND_OTHER_BLUES +#define t1_blend_standard_widths T1_BLEND_STANDARD_WIDTH +#define t1_blend_standard_height T1_BLEND_STANDARD_HEIGHT +#define t1_blend_stem_snap_widths T1_BLEND_STEM_SNAP_WIDTHS +#define t1_blend_stem_snap_heights T1_BLEND_STEM_SNAP_HEIGHTS +#define t1_blend_blue_scale T1_BLEND_BLUE_SCALE +#define t1_blend_blue_shift T1_BLEND_BLUE_SHIFT +#define t1_blend_family_blues T1_BLEND_FAMILY_BLUES +#define t1_blend_family_other_blues T1_BLEND_FAMILY_OTHER_BLUES +#define t1_blend_force_bold T1_BLEND_FORCE_BOLD +#define t1_blend_max T1_BLEND_MAX + + + /* maximum number of Multiple Masters designs, as defined in the spec */ +#define T1_MAX_MM_DESIGNS 16 + + /* maximum number of Multiple Masters axes, as defined in the spec */ +#define T1_MAX_MM_AXIS 4 + + /* maximum number of elements in a design map */ +#define T1_MAX_MM_MAP_POINTS 20 + + + /* this structure is used to store the BlendDesignMap entry for an axis */ + typedef struct PS_DesignMap_ + { + FT_Byte num_points; + FT_Long* design_points; + FT_Fixed* blend_points; + + } PS_DesignMapRec, *PS_DesignMap; + + /* backwards-compatible definition */ + typedef PS_DesignMapRec T1_DesignMap; + + + typedef struct PS_BlendRec_ + { + FT_UInt num_designs; + FT_UInt num_axis; + + FT_String* axis_names[T1_MAX_MM_AXIS]; + FT_Fixed* design_pos[T1_MAX_MM_DESIGNS]; + PS_DesignMapRec design_map[T1_MAX_MM_AXIS]; + + FT_Fixed* weight_vector; + FT_Fixed* default_weight_vector; + + PS_FontInfo font_infos[T1_MAX_MM_DESIGNS + 1]; + PS_Private privates [T1_MAX_MM_DESIGNS + 1]; + + FT_ULong blend_bitflags; + + FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1]; + + /* since 2.3.0 */ + + /* undocumented, optional: the default design instance; */ + /* corresponds to default_weight_vector -- */ + /* num_default_design_vector == 0 means it is not present */ + /* in the font and associated metrics files */ + FT_UInt default_design_vector[T1_MAX_MM_DESIGNS]; + FT_UInt num_default_design_vector; + + } PS_BlendRec, *PS_Blend; + + + /* backwards-compatible definition */ + typedef PS_BlendRec T1_Blend; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDictRec */ + /* */ + /* <Description> */ + /* A structure used to represent data in a CID top-level dictionary. */ + /* */ + typedef struct CID_FaceDictRec_ + { + PS_PrivateRec private_dict; + + FT_UInt len_buildchar; + FT_Fixed forcebold_threshold; + FT_Pos stroke_width; + FT_Fixed expansion_factor; + + FT_Byte paint_type; + FT_Byte font_type; + FT_Matrix font_matrix; + FT_Vector font_offset; + + FT_UInt num_subrs; + FT_ULong subrmap_offset; + FT_Int sd_bytes; + + } CID_FaceDictRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceDict */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceDictRec structure. */ + /* */ + typedef struct CID_FaceDictRec_* CID_FaceDict; + + /* */ + + + /* backwards-compatible definition */ + typedef CID_FaceDictRec CID_FontDict; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfoRec */ + /* */ + /* <Description> */ + /* A structure used to represent CID Face information. */ + /* */ + typedef struct CID_FaceInfoRec_ + { + FT_String* cid_font_name; + FT_Fixed cid_version; + FT_Int cid_font_type; + + FT_String* registry; + FT_String* ordering; + FT_Int supplement; + + PS_FontInfoRec font_info; + FT_BBox font_bbox; + FT_ULong uid_base; + + FT_Int num_xuid; + FT_ULong xuid[16]; + + FT_ULong cidmap_offset; + FT_Int fd_bytes; + FT_Int gd_bytes; + FT_ULong cid_count; + + FT_Int num_dicts; + CID_FaceDict font_dicts; + + FT_ULong data_offset; + + } CID_FaceInfoRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_FaceInfo */ + /* */ + /* <Description> */ + /* A handle to a @CID_FaceInfoRec structure. */ + /* */ + typedef struct CID_FaceInfoRec_* CID_FaceInfo; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CID_Info */ + /* */ + /* <Description> */ + /* This type is equivalent to @CID_FaceInfoRec. It is deprecated but */ + /* kept to maintain source compatibility between various versions of */ + /* FreeType. */ + /* */ + typedef CID_FaceInfoRec CID_Info; + + + /************************************************************************ + * + * @function: + * FT_Has_PS_Glyph_Names + * + * @description: + * Return true if a given face provides reliable PostScript glyph + * names. This is similar to using the @FT_HAS_GLYPH_NAMES macro, + * except that certain fonts (mostly TrueType) contain incorrect + * glyph name tables. + * + * When this function returns true, the caller is sure that the glyph + * names returned by @FT_Get_Glyph_Name are reliable. + * + * @input: + * face :: + * face handle + * + * @return: + * Boolean. True if glyph names are reliable. + * + */ + FT_EXPORT( FT_Int ) + FT_Has_PS_Glyph_Names( FT_Face face ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Info + * + * @description: + * Retrieve the @PS_FontInfoRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_info :: + * Output font info structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the font info structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function will + * return the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Info( FT_Face face, + PS_FontInfo afont_info ); + + + /************************************************************************ + * + * @function: + * FT_Get_PS_Font_Private + * + * @description: + * Retrieve the @PS_PrivateRec structure corresponding to a given + * PostScript font. + * + * @input: + * face :: + * PostScript face handle. + * + * @output: + * afont_private :: + * Output private dictionary structure pointer. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * The string pointers within the font info structure are owned by + * the face and don't need to be freed by the caller. + * + * If the font's format is not PostScript-based, this function will + * return the `FT_Err_Invalid_Argument' error code. + * + */ + FT_EXPORT( FT_Error ) + FT_Get_PS_Font_Private( FT_Face face, + PS_Private afont_private ); + + /* */ + + +FT_END_HEADER + +#endif /* __T1TABLES_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ttnameid.h b/utils/openttd/freetype/ttnameid.h new file mode 100644 index 00000000000..b8010ccd6c4 --- /dev/null +++ b/utils/openttd/freetype/ttnameid.h @@ -0,0 +1,1146 @@ +/***************************************************************************/ +/* */ +/* ttnameid.h */ +/* */ +/* TrueType name ID definitions (specification only). */ +/* */ +/* Copyright 1996-2002, 2003, 2004, 2006, 2007, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTNAMEID_H__ +#define __TTNAMEID_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + + + /*************************************************************************/ + /* */ + /* Possible values for the `platform' identifier code in the name */ + /* records of the TTF `name' table. */ + /* */ + /*************************************************************************/ + + + /*********************************************************************** + * + * @enum: + * TT_PLATFORM_XXX + * + * @description: + * A list of valid values for the `platform_id' identifier code in + * @FT_CharMapRec and @FT_SfntName structures. + * + * @values: + * TT_PLATFORM_APPLE_UNICODE :: + * Used by Apple to indicate a Unicode character map and/or name entry. + * See @TT_APPLE_ID_XXX for corresponding `encoding_id' values. Note + * that name entries in this format are coded as big-endian UCS-2 + * character codes _only_. + * + * TT_PLATFORM_MACINTOSH :: + * Used by Apple to indicate a MacOS-specific charmap and/or name entry. + * See @TT_MAC_ID_XXX for corresponding `encoding_id' values. Note that + * most TrueType fonts contain an Apple roman charmap to be usable on + * MacOS systems (even if they contain a Microsoft charmap as well). + * + * TT_PLATFORM_ISO :: + * This value was used to specify Unicode charmaps. It is however + * now deprecated. See @TT_ISO_ID_XXX for a list of corresponding + * `encoding_id' values. + * + * TT_PLATFORM_MICROSOFT :: + * Used by Microsoft to indicate Windows-specific charmaps. See + * @TT_MS_ID_XXX for a list of corresponding `encoding_id' values. + * Note that most fonts contain a Unicode charmap using + * (TT_PLATFORM_MICROSOFT, @TT_MS_ID_UNICODE_CS). + * + * TT_PLATFORM_CUSTOM :: + * Used to indicate application-specific charmaps. + * + * TT_PLATFORM_ADOBE :: + * This value isn't part of any font format specification, but is used + * by FreeType to report Adobe-specific charmaps in an @FT_CharMapRec + * structure. See @TT_ADOBE_ID_XXX. + */ + +#define TT_PLATFORM_APPLE_UNICODE 0 +#define TT_PLATFORM_MACINTOSH 1 +#define TT_PLATFORM_ISO 2 /* deprecated */ +#define TT_PLATFORM_MICROSOFT 3 +#define TT_PLATFORM_CUSTOM 4 +#define TT_PLATFORM_ADOBE 7 /* artificial */ + + + /*********************************************************************** + * + * @enum: + * TT_APPLE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_APPLE_UNICODE charmaps and name entries. + * + * @values: + * TT_APPLE_ID_DEFAULT :: + * Unicode version 1.0. + * + * TT_APPLE_ID_UNICODE_1_1 :: + * Unicode 1.1; specifies Hangul characters starting at U+34xx. + * + * TT_APPLE_ID_ISO_10646 :: + * Deprecated (identical to preceding). + * + * TT_APPLE_ID_UNICODE_2_0 :: + * Unicode 2.0 and beyond (UTF-16 BMP only). + * + * TT_APPLE_ID_UNICODE_32 :: + * Unicode 3.1 and beyond, using UTF-32. + * + * TT_APPLE_ID_VARIANT_SELECTOR :: + * From Adobe, not Apple. Not a normal cmap. Specifies variations + * on a real cmap. + */ + +#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ +#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ +#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ +#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ +#define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ +#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ + + + /*********************************************************************** + * + * @enum: + * TT_MAC_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MACINTOSH charmaps and name entries. + * + * @values: + * TT_MAC_ID_ROMAN :: + * TT_MAC_ID_JAPANESE :: + * TT_MAC_ID_TRADITIONAL_CHINESE :: + * TT_MAC_ID_KOREAN :: + * TT_MAC_ID_ARABIC :: + * TT_MAC_ID_HEBREW :: + * TT_MAC_ID_GREEK :: + * TT_MAC_ID_RUSSIAN :: + * TT_MAC_ID_RSYMBOL :: + * TT_MAC_ID_DEVANAGARI :: + * TT_MAC_ID_GURMUKHI :: + * TT_MAC_ID_GUJARATI :: + * TT_MAC_ID_ORIYA :: + * TT_MAC_ID_BENGALI :: + * TT_MAC_ID_TAMIL :: + * TT_MAC_ID_TELUGU :: + * TT_MAC_ID_KANNADA :: + * TT_MAC_ID_MALAYALAM :: + * TT_MAC_ID_SINHALESE :: + * TT_MAC_ID_BURMESE :: + * TT_MAC_ID_KHMER :: + * TT_MAC_ID_THAI :: + * TT_MAC_ID_LAOTIAN :: + * TT_MAC_ID_GEORGIAN :: + * TT_MAC_ID_ARMENIAN :: + * TT_MAC_ID_MALDIVIAN :: + * TT_MAC_ID_SIMPLIFIED_CHINESE :: + * TT_MAC_ID_TIBETAN :: + * TT_MAC_ID_MONGOLIAN :: + * TT_MAC_ID_GEEZ :: + * TT_MAC_ID_SLAVIC :: + * TT_MAC_ID_VIETNAMESE :: + * TT_MAC_ID_SINDHI :: + * TT_MAC_ID_UNINTERP :: + */ + +#define TT_MAC_ID_ROMAN 0 +#define TT_MAC_ID_JAPANESE 1 +#define TT_MAC_ID_TRADITIONAL_CHINESE 2 +#define TT_MAC_ID_KOREAN 3 +#define TT_MAC_ID_ARABIC 4 +#define TT_MAC_ID_HEBREW 5 +#define TT_MAC_ID_GREEK 6 +#define TT_MAC_ID_RUSSIAN 7 +#define TT_MAC_ID_RSYMBOL 8 +#define TT_MAC_ID_DEVANAGARI 9 +#define TT_MAC_ID_GURMUKHI 10 +#define TT_MAC_ID_GUJARATI 11 +#define TT_MAC_ID_ORIYA 12 +#define TT_MAC_ID_BENGALI 13 +#define TT_MAC_ID_TAMIL 14 +#define TT_MAC_ID_TELUGU 15 +#define TT_MAC_ID_KANNADA 16 +#define TT_MAC_ID_MALAYALAM 17 +#define TT_MAC_ID_SINHALESE 18 +#define TT_MAC_ID_BURMESE 19 +#define TT_MAC_ID_KHMER 20 +#define TT_MAC_ID_THAI 21 +#define TT_MAC_ID_LAOTIAN 22 +#define TT_MAC_ID_GEORGIAN 23 +#define TT_MAC_ID_ARMENIAN 24 +#define TT_MAC_ID_MALDIVIAN 25 +#define TT_MAC_ID_SIMPLIFIED_CHINESE 25 +#define TT_MAC_ID_TIBETAN 26 +#define TT_MAC_ID_MONGOLIAN 27 +#define TT_MAC_ID_GEEZ 28 +#define TT_MAC_ID_SLAVIC 29 +#define TT_MAC_ID_VIETNAMESE 30 +#define TT_MAC_ID_SINDHI 31 +#define TT_MAC_ID_UNINTERP 32 + + + /*********************************************************************** + * + * @enum: + * TT_ISO_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ISO charmaps and name entries. + * + * Their use is now deprecated. + * + * @values: + * TT_ISO_ID_7BIT_ASCII :: + * ASCII. + * TT_ISO_ID_10646 :: + * ISO/10646. + * TT_ISO_ID_8859_1 :: + * Also known as Latin-1. + */ + +#define TT_ISO_ID_7BIT_ASCII 0 +#define TT_ISO_ID_10646 1 +#define TT_ISO_ID_8859_1 2 + + + /*********************************************************************** + * + * @enum: + * TT_MS_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_MICROSOFT charmaps and name entries. + * + * @values: + * TT_MS_ID_SYMBOL_CS :: + * Corresponds to Microsoft symbol encoding. See + * @FT_ENCODING_MS_SYMBOL. + * + * TT_MS_ID_UNICODE_CS :: + * Corresponds to a Microsoft WGL4 charmap, matching Unicode. See + * @FT_ENCODING_UNICODE. + * + * TT_MS_ID_SJIS :: + * Corresponds to SJIS Japanese encoding. See @FT_ENCODING_SJIS. + * + * TT_MS_ID_GB2312 :: + * Corresponds to Simplified Chinese as used in Mainland China. See + * @FT_ENCODING_GB2312. + * + * TT_MS_ID_BIG_5 :: + * Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. + * See @FT_ENCODING_BIG5. + * + * TT_MS_ID_WANSUNG :: + * Corresponds to Korean Wansung encoding. See @FT_ENCODING_WANSUNG. + * + * TT_MS_ID_JOHAB :: + * Corresponds to Johab encoding. See @FT_ENCODING_JOHAB. + * + * TT_MS_ID_UCS_4 :: + * Corresponds to UCS-4 or UTF-32 charmaps. This has been added to + * the OpenType specification version 1.4 (mid-2001.) + */ + +#define TT_MS_ID_SYMBOL_CS 0 +#define TT_MS_ID_UNICODE_CS 1 +#define TT_MS_ID_SJIS 2 +#define TT_MS_ID_GB2312 3 +#define TT_MS_ID_BIG_5 4 +#define TT_MS_ID_WANSUNG 5 +#define TT_MS_ID_JOHAB 6 +#define TT_MS_ID_UCS_4 10 + + + /*********************************************************************** + * + * @enum: + * TT_ADOBE_ID_XXX + * + * @description: + * A list of valid values for the `encoding_id' for + * @TT_PLATFORM_ADOBE charmaps. This is a FreeType-specific extension! + * + * @values: + * TT_ADOBE_ID_STANDARD :: + * Adobe standard encoding. + * TT_ADOBE_ID_EXPERT :: + * Adobe expert encoding. + * TT_ADOBE_ID_CUSTOM :: + * Adobe custom encoding. + * TT_ADOBE_ID_LATIN_1 :: + * Adobe Latin~1 encoding. + */ + +#define TT_ADOBE_ID_STANDARD 0 +#define TT_ADOBE_ID_EXPERT 1 +#define TT_ADOBE_ID_CUSTOM 2 +#define TT_ADOBE_ID_LATIN_1 3 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MACINTOSH. */ + /* */ + /* The canonical source for the Apple assigned Language ID's is at */ + /* */ + /* http://fonts.apple.com/TTRefMan/RM06/Chap6name.html */ + /* */ +#define TT_MAC_LANGID_ENGLISH 0 +#define TT_MAC_LANGID_FRENCH 1 +#define TT_MAC_LANGID_GERMAN 2 +#define TT_MAC_LANGID_ITALIAN 3 +#define TT_MAC_LANGID_DUTCH 4 +#define TT_MAC_LANGID_SWEDISH 5 +#define TT_MAC_LANGID_SPANISH 6 +#define TT_MAC_LANGID_DANISH 7 +#define TT_MAC_LANGID_PORTUGUESE 8 +#define TT_MAC_LANGID_NORWEGIAN 9 +#define TT_MAC_LANGID_HEBREW 10 +#define TT_MAC_LANGID_JAPANESE 11 +#define TT_MAC_LANGID_ARABIC 12 +#define TT_MAC_LANGID_FINNISH 13 +#define TT_MAC_LANGID_GREEK 14 +#define TT_MAC_LANGID_ICELANDIC 15 +#define TT_MAC_LANGID_MALTESE 16 +#define TT_MAC_LANGID_TURKISH 17 +#define TT_MAC_LANGID_CROATIAN 18 +#define TT_MAC_LANGID_CHINESE_TRADITIONAL 19 +#define TT_MAC_LANGID_URDU 20 +#define TT_MAC_LANGID_HINDI 21 +#define TT_MAC_LANGID_THAI 22 +#define TT_MAC_LANGID_KOREAN 23 +#define TT_MAC_LANGID_LITHUANIAN 24 +#define TT_MAC_LANGID_POLISH 25 +#define TT_MAC_LANGID_HUNGARIAN 26 +#define TT_MAC_LANGID_ESTONIAN 27 +#define TT_MAC_LANGID_LETTISH 28 +#define TT_MAC_LANGID_SAAMISK 29 +#define TT_MAC_LANGID_FAEROESE 30 +#define TT_MAC_LANGID_FARSI 31 +#define TT_MAC_LANGID_RUSSIAN 32 +#define TT_MAC_LANGID_CHINESE_SIMPLIFIED 33 +#define TT_MAC_LANGID_FLEMISH 34 +#define TT_MAC_LANGID_IRISH 35 +#define TT_MAC_LANGID_ALBANIAN 36 +#define TT_MAC_LANGID_ROMANIAN 37 +#define TT_MAC_LANGID_CZECH 38 +#define TT_MAC_LANGID_SLOVAK 39 +#define TT_MAC_LANGID_SLOVENIAN 40 +#define TT_MAC_LANGID_YIDDISH 41 +#define TT_MAC_LANGID_SERBIAN 42 +#define TT_MAC_LANGID_MACEDONIAN 43 +#define TT_MAC_LANGID_BULGARIAN 44 +#define TT_MAC_LANGID_UKRAINIAN 45 +#define TT_MAC_LANGID_BYELORUSSIAN 46 +#define TT_MAC_LANGID_UZBEK 47 +#define TT_MAC_LANGID_KAZAKH 48 +#define TT_MAC_LANGID_AZERBAIJANI 49 +#define TT_MAC_LANGID_AZERBAIJANI_CYRILLIC_SCRIPT 49 +#define TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT 50 +#define TT_MAC_LANGID_ARMENIAN 51 +#define TT_MAC_LANGID_GEORGIAN 52 +#define TT_MAC_LANGID_MOLDAVIAN 53 +#define TT_MAC_LANGID_KIRGHIZ 54 +#define TT_MAC_LANGID_TAJIKI 55 +#define TT_MAC_LANGID_TURKMEN 56 +#define TT_MAC_LANGID_MONGOLIAN 57 +#define TT_MAC_LANGID_MONGOLIAN_MONGOLIAN_SCRIPT 57 +#define TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT 58 +#define TT_MAC_LANGID_PASHTO 59 +#define TT_MAC_LANGID_KURDISH 60 +#define TT_MAC_LANGID_KASHMIRI 61 +#define TT_MAC_LANGID_SINDHI 62 +#define TT_MAC_LANGID_TIBETAN 63 +#define TT_MAC_LANGID_NEPALI 64 +#define TT_MAC_LANGID_SANSKRIT 65 +#define TT_MAC_LANGID_MARATHI 66 +#define TT_MAC_LANGID_BENGALI 67 +#define TT_MAC_LANGID_ASSAMESE 68 +#define TT_MAC_LANGID_GUJARATI 69 +#define TT_MAC_LANGID_PUNJABI 70 +#define TT_MAC_LANGID_ORIYA 71 +#define TT_MAC_LANGID_MALAYALAM 72 +#define TT_MAC_LANGID_KANNADA 73 +#define TT_MAC_LANGID_TAMIL 74 +#define TT_MAC_LANGID_TELUGU 75 +#define TT_MAC_LANGID_SINHALESE 76 +#define TT_MAC_LANGID_BURMESE 77 +#define TT_MAC_LANGID_KHMER 78 +#define TT_MAC_LANGID_LAO 79 +#define TT_MAC_LANGID_VIETNAMESE 80 +#define TT_MAC_LANGID_INDONESIAN 81 +#define TT_MAC_LANGID_TAGALOG 82 +#define TT_MAC_LANGID_MALAY_ROMAN_SCRIPT 83 +#define TT_MAC_LANGID_MALAY_ARABIC_SCRIPT 84 +#define TT_MAC_LANGID_AMHARIC 85 +#define TT_MAC_LANGID_TIGRINYA 86 +#define TT_MAC_LANGID_GALLA 87 +#define TT_MAC_LANGID_SOMALI 88 +#define TT_MAC_LANGID_SWAHILI 89 +#define TT_MAC_LANGID_RUANDA 90 +#define TT_MAC_LANGID_RUNDI 91 +#define TT_MAC_LANGID_CHEWA 92 +#define TT_MAC_LANGID_MALAGASY 93 +#define TT_MAC_LANGID_ESPERANTO 94 +#define TT_MAC_LANGID_WELSH 128 +#define TT_MAC_LANGID_BASQUE 129 +#define TT_MAC_LANGID_CATALAN 130 +#define TT_MAC_LANGID_LATIN 131 +#define TT_MAC_LANGID_QUECHUA 132 +#define TT_MAC_LANGID_GUARANI 133 +#define TT_MAC_LANGID_AYMARA 134 +#define TT_MAC_LANGID_TATAR 135 +#define TT_MAC_LANGID_UIGHUR 136 +#define TT_MAC_LANGID_DZONGKHA 137 +#define TT_MAC_LANGID_JAVANESE 138 +#define TT_MAC_LANGID_SUNDANESE 139 + + +#if 0 /* these seem to be errors that have been dropped */ + +#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 +#define TT_MAC_LANGID_IRISH_GAELIC 141 + +#endif + + + /* The following codes are new as of 2000-03-10 */ +#define TT_MAC_LANGID_GALICIAN 140 +#define TT_MAC_LANGID_AFRIKAANS 141 +#define TT_MAC_LANGID_BRETON 142 +#define TT_MAC_LANGID_INUKTITUT 143 +#define TT_MAC_LANGID_SCOTTISH_GAELIC 144 +#define TT_MAC_LANGID_MANX_GAELIC 145 +#define TT_MAC_LANGID_IRISH_GAELIC 146 +#define TT_MAC_LANGID_TONGAN 147 +#define TT_MAC_LANGID_GREEK_POLYTONIC 148 +#define TT_MAC_LANGID_GREELANDIC 149 +#define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 + + + /*************************************************************************/ + /* */ + /* Possible values of the language identifier field in the name records */ + /* of the TTF `name' table if the `platform' identifier code is */ + /* TT_PLATFORM_MICROSOFT. */ + /* */ + /* The canonical source for the MS assigned LCID's (seems to) be at */ + /* */ + /* http://www.microsoft.com/globaldev/reference/lcid-all.mspx */ + /* */ + /* It used to be at various places, among them */ + /* */ + /* http://www.microsoft.com/typography/OTSPEC/lcid-cp.txt */ + /* http://www.microsoft.com/globaldev/reference/loclanghome.asp */ + /* http://support.microsoft.com/support/kb/articles/Q224/8/04.ASP */ + /* http://msdn.microsoft.com/library/en-us/passport25/ */ + /* NET_Passport_VBScript_Documentation/Single_Sign_In/ */ + /* Advanced_Single_Sign_In/Localization_and_LCIDs.asp */ + /* */ + /* Hopefully, it seems now that the Globaldev site prevails... */ + /* (updated by Antoine, 2004-02-17) */ + +#define TT_MS_LANGID_ARABIC_GENERAL 0x0001 +#define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 +#define TT_MS_LANGID_ARABIC_IRAQ 0x0801 +#define TT_MS_LANGID_ARABIC_EGYPT 0x0c01 +#define TT_MS_LANGID_ARABIC_LIBYA 0x1001 +#define TT_MS_LANGID_ARABIC_ALGERIA 0x1401 +#define TT_MS_LANGID_ARABIC_MOROCCO 0x1801 +#define TT_MS_LANGID_ARABIC_TUNISIA 0x1c01 +#define TT_MS_LANGID_ARABIC_OMAN 0x2001 +#define TT_MS_LANGID_ARABIC_YEMEN 0x2401 +#define TT_MS_LANGID_ARABIC_SYRIA 0x2801 +#define TT_MS_LANGID_ARABIC_JORDAN 0x2c01 +#define TT_MS_LANGID_ARABIC_LEBANON 0x3001 +#define TT_MS_LANGID_ARABIC_KUWAIT 0x3401 +#define TT_MS_LANGID_ARABIC_UAE 0x3801 +#define TT_MS_LANGID_ARABIC_BAHRAIN 0x3c01 +#define TT_MS_LANGID_ARABIC_QATAR 0x4001 +#define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 +#define TT_MS_LANGID_CATALAN_SPAIN 0x0403 +#define TT_MS_LANGID_CHINESE_GENERAL 0x0004 +#define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 +#define TT_MS_LANGID_CHINESE_PRC 0x0804 +#define TT_MS_LANGID_CHINESE_HONG_KONG 0x0c04 +#define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 + +#if 1 /* this looks like the correct value */ +#define TT_MS_LANGID_CHINESE_MACAU 0x1404 +#else /* but beware, Microsoft may change its mind... + the most recent Word reference has the following: */ +#define TT_MS_LANGID_CHINESE_MACAU TT_MS_LANGID_CHINESE_HONG_KONG +#endif + +#if 0 /* used only with .NET `cultures'; commented out */ +#define TT_MS_LANGID_CHINESE_TRADITIONAL 0x7C04 +#endif + +#define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 +#define TT_MS_LANGID_DANISH_DENMARK 0x0406 +#define TT_MS_LANGID_GERMAN_GERMANY 0x0407 +#define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 +#define TT_MS_LANGID_GERMAN_AUSTRIA 0x0c07 +#define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 +#define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 +#define TT_MS_LANGID_GREEK_GREECE 0x0408 + + /* don't ask what this one means... It is commented out currently. */ +#if 0 +#define TT_MS_LANGID_GREEK_GREECE2 0x2008 +#endif + +#define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 +#define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 +#define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 +#define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0c09 +#define TT_MS_LANGID_ENGLISH_CANADA 0x1009 +#define TT_MS_LANGID_ENGLISH_NEW_ZEALAND 0x1409 +#define TT_MS_LANGID_ENGLISH_IRELAND 0x1809 +#define TT_MS_LANGID_ENGLISH_SOUTH_AFRICA 0x1c09 +#define TT_MS_LANGID_ENGLISH_JAMAICA 0x2009 +#define TT_MS_LANGID_ENGLISH_CARIBBEAN 0x2409 +#define TT_MS_LANGID_ENGLISH_BELIZE 0x2809 +#define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2c09 +#define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 +#define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 +#define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 +#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3c09 +#define TT_MS_LANGID_ENGLISH_INDIA 0x4009 +#define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 +#define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 +#define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040a +#define TT_MS_LANGID_SPANISH_MEXICO 0x080a +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0c0a +#define TT_MS_LANGID_SPANISH_GUATEMALA 0x100a +#define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140a +#define TT_MS_LANGID_SPANISH_PANAMA 0x180a +#define TT_MS_LANGID_SPANISH_DOMINICAN_REPUBLIC 0x1c0a +#define TT_MS_LANGID_SPANISH_VENEZUELA 0x200a +#define TT_MS_LANGID_SPANISH_COLOMBIA 0x240a +#define TT_MS_LANGID_SPANISH_PERU 0x280a +#define TT_MS_LANGID_SPANISH_ARGENTINA 0x2c0a +#define TT_MS_LANGID_SPANISH_ECUADOR 0x300a +#define TT_MS_LANGID_SPANISH_CHILE 0x340a +#define TT_MS_LANGID_SPANISH_URUGUAY 0x380a +#define TT_MS_LANGID_SPANISH_PARAGUAY 0x3c0a +#define TT_MS_LANGID_SPANISH_BOLIVIA 0x400a +#define TT_MS_LANGID_SPANISH_EL_SALVADOR 0x440a +#define TT_MS_LANGID_SPANISH_HONDURAS 0x480a +#define TT_MS_LANGID_SPANISH_NICARAGUA 0x4c0a +#define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500a +#define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540a + /* The following ID blatantly violate MS specs by using a */ + /* sublanguage > 0x1F. */ +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40aU +#define TT_MS_LANGID_FINNISH_FINLAND 0x040b +#define TT_MS_LANGID_FRENCH_FRANCE 0x040c +#define TT_MS_LANGID_FRENCH_BELGIUM 0x080c +#define TT_MS_LANGID_FRENCH_CANADA 0x0c0c +#define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100c +#define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140c +#define TT_MS_LANGID_FRENCH_MONACO 0x180c +#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1c0c +#define TT_MS_LANGID_FRENCH_REUNION 0x200c +#define TT_MS_LANGID_FRENCH_CONGO 0x240c + /* which was formerly: */ +#define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO +#define TT_MS_LANGID_FRENCH_SENEGAL 0x280c +#define TT_MS_LANGID_FRENCH_CAMEROON 0x2c0c +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300c +#define TT_MS_LANGID_FRENCH_MALI 0x340c +#define TT_MS_LANGID_FRENCH_MOROCCO 0x380c +#define TT_MS_LANGID_FRENCH_HAITI 0x3c0c + /* and another violation of the spec (see 0xE40aU) */ +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40cU +#define TT_MS_LANGID_HEBREW_ISRAEL 0x040d +#define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040e +#define TT_MS_LANGID_ICELANDIC_ICELAND 0x040f +#define TT_MS_LANGID_ITALIAN_ITALY 0x0410 +#define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 +#define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 +#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA 0x0412 +#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 +#define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 +#define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 +#define TT_MS_LANGID_NORWEGIAN_NORWAY_NYNORSK 0x0814 +#define TT_MS_LANGID_POLISH_POLAND 0x0415 +#define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 +#define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 +#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND 0x0417 +#define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 +#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 +#define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 +#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 +#define TT_MS_LANGID_CROATIAN_CROATIA 0x041a +#define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081a +#define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0c1a + +#if 0 /* this used to be this value, but it looks like we were wrong */ +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101a +#else /* current sources say */ +#define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101a +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141a + /* and XPsp2 Platform SDK added (2004-07-26) */ + /* Names are shortened to be significant within 40 chars. */ +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181a +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181a +#endif + +#define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041b +#define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041c +#define TT_MS_LANGID_SWEDISH_SWEDEN 0x041d +#define TT_MS_LANGID_SWEDISH_FINLAND 0x081d +#define TT_MS_LANGID_THAI_THAILAND 0x041e +#define TT_MS_LANGID_TURKISH_TURKEY 0x041f +#define TT_MS_LANGID_URDU_PAKISTAN 0x0420 +#define TT_MS_LANGID_URDU_INDIA 0x0820 +#define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 +#define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 +#define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 +#define TT_MS_LANGID_SLOVENE_SLOVENIA 0x0424 +#define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 +#define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 +#define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 +#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 +#define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 +#define TT_MS_LANGID_FARSI_IRAN 0x0429 +#define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042a +#define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042b +#define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042c +#define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082c +#define TT_MS_LANGID_BASQUE_SPAIN 0x042d +#define TT_MS_LANGID_SORBIAN_GERMANY 0x042e +#define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042f +#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 +#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 +#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 +#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 +#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA 0x0434 +#define TT_MS_LANGID_ZULU_SOUTH_AFRICA 0x0435 +#define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 +#define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 +#define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 +#define TT_MS_LANGID_HINDI_INDIA 0x0439 +#define TT_MS_LANGID_MALTESE_MALTA 0x043a + /* Added by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043b +#define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083b +#define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3b +#define TT_MS_LANGID_SAMI_LULE_NORWAY 0x103b +#define TT_MS_LANGID_SAMI_LULE_SWEDEN 0x143b +#define TT_MS_LANGID_SAMI_SOUTHERN_NORWAY 0x183b +#define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3b +#define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203b +#define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243b + /* ... and we also keep our old identifier... */ +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043b + +#if 0 /* this seems to be a previous inversion */ +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#else +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083c +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043c +#endif + +#define TT_MS_LANGID_YIDDISH_GERMANY 0x043d +#define TT_MS_LANGID_MALAY_MALAYSIA 0x043e +#define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083e +#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043f +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ + TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN + +#define TT_MS_LANGID_SWAHILI_KENYA 0x0441 +#define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 +#define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 +#define TT_MS_LANGID_TATAR_TATARSTAN 0x0444 +#define TT_MS_LANGID_BENGALI_INDIA 0x0445 +#define TT_MS_LANGID_BENGALI_BANGLADESH 0x0845 +#define TT_MS_LANGID_PUNJABI_INDIA 0x0446 +#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 +#define TT_MS_LANGID_GUJARATI_INDIA 0x0447 +#define TT_MS_LANGID_ORIYA_INDIA 0x0448 +#define TT_MS_LANGID_TAMIL_INDIA 0x0449 +#define TT_MS_LANGID_TELUGU_INDIA 0x044a +#define TT_MS_LANGID_KANNADA_INDIA 0x044b +#define TT_MS_LANGID_MALAYALAM_INDIA 0x044c +#define TT_MS_LANGID_ASSAMESE_INDIA 0x044d +#define TT_MS_LANGID_MARATHI_INDIA 0x044e +#define TT_MS_LANGID_SANSKRIT_INDIA 0x044f +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 +#define TT_MS_LANGID_TIBETAN_CHINA 0x0451 + /* Don't use the next constant! It has */ + /* (1) the wrong spelling (Dzonghka) */ + /* (2) Microsoft doesn't officially define it -- */ + /* at least it is not in the List of Local */ + /* ID Values. */ + /* (3) Dzongkha is not the same language as */ + /* Tibetan, so merging it is wrong anyway. */ + /* */ + /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW. */ +#define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 + +#if 0 + /* the following used to be defined */ +#define TT_MS_LANGID_TIBETAN_BHUTAN 0x0451 + /* ... but it was changed; */ +#else + /* So we will continue to #define it, but with the correct value */ +#define TT_MS_LANGID_TIBETAN_BHUTAN TT_MS_LANGID_DZONGHKA_BHUTAN +#endif + +#define TT_MS_LANGID_WELSH_WALES 0x0452 +#define TT_MS_LANGID_KHMER_CAMBODIA 0x0453 +#define TT_MS_LANGID_LAO_LAOS 0x0454 +#define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 +#define TT_MS_LANGID_GALICIAN_SPAIN 0x0456 +#define TT_MS_LANGID_KONKANI_INDIA 0x0457 +#define TT_MS_LANGID_MANIPURI_INDIA /* Bengali */ 0x0458 +#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 +#define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 + /* Missing a LCID for Sindhi in Devanagari script */ +#define TT_MS_LANGID_SYRIAC_SYRIA 0x045a +#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045b +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045c +#define TT_MS_LANGID_INUKTITUT_CANADA 0x045d +#define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045e +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045f +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085f + /* Missing a LCID for Tifinagh script */ +#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 + /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */ + /* script is yet unclear... might be Arabic, Nagari or Sharada */ +#define TT_MS_LANGID_KASHMIRI_SASIA 0x0860 + /* ... and aliased (by MS) for compatibility reasons. */ +#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA +#define TT_MS_LANGID_NEPALI_NEPAL 0x0461 +#define TT_MS_LANGID_NEPALI_INDIA 0x0861 +#define TT_MS_LANGID_FRISIAN_NETHERLANDS 0x0462 +#define TT_MS_LANGID_PASHTO_AFGHANISTAN 0x0463 +#define TT_MS_LANGID_FILIPINO_PHILIPPINES 0x0464 +#define TT_MS_LANGID_DHIVEHI_MALDIVES 0x0465 + /* alias declared in Windows 2000 */ +#define TT_MS_LANGID_DIVEHI_MALDIVES TT_MS_LANGID_DHIVEHI_MALDIVES +#define TT_MS_LANGID_EDO_NIGERIA 0x0466 +#define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 +#define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 +#define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 +#define TT_MS_LANGID_YORUBA_NIGERIA 0x046a +#define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046b +#define TT_MS_LANGID_QUECHUA_ECUADOR 0x086b +#define TT_MS_LANGID_QUECHUA_PERU 0x0c6b +#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046c + /* Also spelled by XPsp2 Platform SDK (2004-07-26) */ +#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ + TT_MS_LANGID_SEPEDI_SOUTH_AFRICA + /* language codes 0x046d, 0x046e and 0x046f are (still) unknown. */ +#define TT_MS_LANGID_IGBO_NIGERIA 0x0470 +#define TT_MS_LANGID_KANURI_NIGERIA 0x0471 +#define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 +#define TT_MS_LANGID_TIGRIGNA_ETHIOPIA 0x0473 +#define TT_MS_LANGID_TIGRIGNA_ERYTHREA 0x0873 + /* also spelled in the `Passport SDK' list as: */ +#define TT_MS_LANGID_TIGRIGNA_ERYTREA TT_MS_LANGID_TIGRIGNA_ERYTHREA +#define TT_MS_LANGID_GUARANI_PARAGUAY 0x0474 +#define TT_MS_LANGID_HAWAIIAN_UNITED_STATES 0x0475 +#define TT_MS_LANGID_LATIN 0x0476 +#define TT_MS_LANGID_SOMALI_SOMALIA 0x0477 + /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */ + /* not written (but OTOH the peculiar writing system is worth */ + /* studying). */ +#define TT_MS_LANGID_YI_CHINA 0x0478 +#define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 + /* language codes from 0x047a to 0x047f are (still) unknown. */ +#define TT_MS_LANGID_UIGHUR_CHINA 0x0480 +#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 + +#if 0 /* not deemed useful for fonts */ +#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04ff +#endif + + + /*************************************************************************/ + /* */ + /* Possible values of the `name' identifier field in the name records of */ + /* the TTF `name' table. These values are platform independent. */ + /* */ +#define TT_NAME_ID_COPYRIGHT 0 +#define TT_NAME_ID_FONT_FAMILY 1 +#define TT_NAME_ID_FONT_SUBFAMILY 2 +#define TT_NAME_ID_UNIQUE_ID 3 +#define TT_NAME_ID_FULL_NAME 4 +#define TT_NAME_ID_VERSION_STRING 5 +#define TT_NAME_ID_PS_NAME 6 +#define TT_NAME_ID_TRADEMARK 7 + + /* the following values are from the OpenType spec */ +#define TT_NAME_ID_MANUFACTURER 8 +#define TT_NAME_ID_DESIGNER 9 +#define TT_NAME_ID_DESCRIPTION 10 +#define TT_NAME_ID_VENDOR_URL 11 +#define TT_NAME_ID_DESIGNER_URL 12 +#define TT_NAME_ID_LICENSE 13 +#define TT_NAME_ID_LICENSE_URL 14 + /* number 15 is reserved */ +#define TT_NAME_ID_PREFERRED_FAMILY 16 +#define TT_NAME_ID_PREFERRED_SUBFAMILY 17 +#define TT_NAME_ID_MAC_FULL_NAME 18 + + /* The following code is new as of 2000-01-21 */ +#define TT_NAME_ID_SAMPLE_TEXT 19 + + /* This is new in OpenType 1.3 */ +#define TT_NAME_ID_CID_FINDFONT_NAME 20 + + + /*************************************************************************/ + /* */ + /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ + /* */ + /* Updated 02-Jul-2000. */ + /* */ + + /* General Scripts Area */ + + /* Bit 0 Basic Latin */ +#define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ + /* Bit 1 C1 Controls and Latin-1 Supplement */ +#define TT_UCR_LATIN1_SUPPLEMENT (1L << 1) /* U+0080-U+00FF */ + /* Bit 2 Latin Extended-A */ +#define TT_UCR_LATIN_EXTENDED_A (1L << 2) /* U+0100-U+017F */ + /* Bit 3 Latin Extended-B */ +#define TT_UCR_LATIN_EXTENDED_B (1L << 3) /* U+0180-U+024F */ + /* Bit 4 IPA Extensions */ +#define TT_UCR_IPA_EXTENSIONS (1L << 4) /* U+0250-U+02AF */ + /* Bit 5 Spacing Modifier Letters */ +#define TT_UCR_SPACING_MODIFIER (1L << 5) /* U+02B0-U+02FF */ + /* Bit 6 Combining Diacritical Marks */ +#define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ + /* Bit 7 Greek and Coptic */ +#define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ + /* Bit 8 is reserved (was: Greek Symbols and Coptic) */ + /* Bit 9 Cyrillic + */ + /* Cyrillic Supplementary */ +#define TT_UCR_CYRILLIC (1L << 9) /* U+0400-U+04FF */ + /* U+0500-U+052F */ + /* Bit 10 Armenian */ +#define TT_UCR_ARMENIAN (1L << 10) /* U+0530-U+058F */ + /* Bit 11 Hebrew */ +#define TT_UCR_HEBREW (1L << 11) /* U+0590-U+05FF */ + /* Bit 12 is reserved (was: Hebrew Extended) */ + /* Bit 13 Arabic */ +#define TT_UCR_ARABIC (1L << 13) /* U+0600-U+06FF */ + /* Bit 14 is reserved (was: Arabic Extended) */ + /* Bit 15 Devanagari */ +#define TT_UCR_DEVANAGARI (1L << 15) /* U+0900-U+097F */ + /* Bit 16 Bengali */ +#define TT_UCR_BENGALI (1L << 16) /* U+0980-U+09FF */ + /* Bit 17 Gurmukhi */ +#define TT_UCR_GURMUKHI (1L << 17) /* U+0A00-U+0A7F */ + /* Bit 18 Gujarati */ +#define TT_UCR_GUJARATI (1L << 18) /* U+0A80-U+0AFF */ + /* Bit 19 Oriya */ +#define TT_UCR_ORIYA (1L << 19) /* U+0B00-U+0B7F */ + /* Bit 20 Tamil */ +#define TT_UCR_TAMIL (1L << 20) /* U+0B80-U+0BFF */ + /* Bit 21 Telugu */ +#define TT_UCR_TELUGU (1L << 21) /* U+0C00-U+0C7F */ + /* Bit 22 Kannada */ +#define TT_UCR_KANNADA (1L << 22) /* U+0C80-U+0CFF */ + /* Bit 23 Malayalam */ +#define TT_UCR_MALAYALAM (1L << 23) /* U+0D00-U+0D7F */ + /* Bit 24 Thai */ +#define TT_UCR_THAI (1L << 24) /* U+0E00-U+0E7F */ + /* Bit 25 Lao */ +#define TT_UCR_LAO (1L << 25) /* U+0E80-U+0EFF */ + /* Bit 26 Georgian */ +#define TT_UCR_GEORGIAN (1L << 26) /* U+10A0-U+10FF */ + /* Bit 27 is reserved (was Georgian Extended) */ + /* Bit 28 Hangul Jamo */ +#define TT_UCR_HANGUL_JAMO (1L << 28) /* U+1100-U+11FF */ + /* Bit 29 Latin Extended Additional */ +#define TT_UCR_LATIN_EXTENDED_ADDITIONAL (1L << 29) /* U+1E00-U+1EFF */ + /* Bit 30 Greek Extended */ +#define TT_UCR_GREEK_EXTENDED (1L << 30) /* U+1F00-U+1FFF */ + + /* Symbols Area */ + + /* Bit 31 General Punctuation */ +#define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ + /* Bit 32 Superscripts And Subscripts */ +#define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ + /* Bit 33 Currency Symbols */ +#define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ + /* Bit 34 Combining Diacritical Marks For Symbols */ +#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) /* U+20D0-U+20FF */ + /* Bit 35 Letterlike Symbols */ +#define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ + /* Bit 36 Number Forms */ +#define TT_UCR_NUMBER_FORMS (1L << 4) /* U+2150-U+218F */ + /* Bit 37 Arrows + */ + /* Supplemental Arrows-A + */ + /* Supplemental Arrows-B */ +#define TT_UCR_ARROWS (1L << 5) /* U+2190-U+21FF */ + /* U+27F0-U+27FF */ + /* U+2900-U+297F */ + /* Bit 38 Mathematical Operators + */ + /* Supplemental Mathematical Operators + */ + /* Miscellaneous Mathematical Symbols-A + */ + /* Miscellaneous Mathematical Symbols-B */ +#define TT_UCR_MATHEMATICAL_OPERATORS (1L << 6) /* U+2200-U+22FF */ + /* U+2A00-U+2AFF */ + /* U+27C0-U+27EF */ + /* U+2980-U+29FF */ + /* Bit 39 Miscellaneous Technical */ +#define TT_UCR_MISCELLANEOUS_TECHNICAL (1L << 7) /* U+2300-U+23FF */ + /* Bit 40 Control Pictures */ +#define TT_UCR_CONTROL_PICTURES (1L << 8) /* U+2400-U+243F */ + /* Bit 41 Optical Character Recognition */ +#define TT_UCR_OCR (1L << 9) /* U+2440-U+245F */ + /* Bit 42 Enclosed Alphanumerics */ +#define TT_UCR_ENCLOSED_ALPHANUMERICS (1L << 10) /* U+2460-U+24FF */ + /* Bit 43 Box Drawing */ +#define TT_UCR_BOX_DRAWING (1L << 11) /* U+2500-U+257F */ + /* Bit 44 Block Elements */ +#define TT_UCR_BLOCK_ELEMENTS (1L << 12) /* U+2580-U+259F */ + /* Bit 45 Geometric Shapes */ +#define TT_UCR_GEOMETRIC_SHAPES (1L << 13) /* U+25A0-U+25FF */ + /* Bit 46 Miscellaneous Symbols */ +#define TT_UCR_MISCELLANEOUS_SYMBOLS (1L << 14) /* U+2600-U+26FF */ + /* Bit 47 Dingbats */ +#define TT_UCR_DINGBATS (1L << 15) /* U+2700-U+27BF */ + + /* CJK Phonetics and Symbols Area */ + + /* Bit 48 CJK Symbols and Punctuation */ +#define TT_UCR_CJK_SYMBOLS (1L << 16) /* U+3000-U+303F */ + /* Bit 49 Hiragana */ +#define TT_UCR_HIRAGANA (1L << 17) /* U+3040-U+309F */ + /* Bit 50 Katakana + */ + /* Katakana Phonetic Extensions */ +#define TT_UCR_KATAKANA (1L << 18) /* U+30A0-U+30FF */ + /* U+31F0-U+31FF */ + /* Bit 51 Bopomofo + */ + /* Bopomofo Extended */ +#define TT_UCR_BOPOMOFO (1L << 19) /* U+3100-U+312F */ + /* U+31A0-U+31BF */ + /* Bit 52 Hangul Compatibility Jamo */ +#define TT_UCR_HANGUL_COMPATIBILITY_JAMO (1L << 20) /* U+3130-U+318F */ + /* Bit 53 Kanbun */ +#define TT_UCR_CJK_MISC (1L << 21) /* U+3190-U+319F */ +#define TT_UCR_KANBUN TT_UCR_CJK_MISC + /* Bit 54 Enclosed CJK Letters and Months */ +#define TT_UCR_ENCLOSED_CJK_LETTERS_MONTHS (1L << 22) /* U+3200-U+32FF */ + /* Bit 55 CJK Compatibility */ +#define TT_UCR_CJK_COMPATIBILITY (1L << 23) /* U+3300-U+33FF */ + + /* Hangul Syllables Area */ + + /* Bit 56 Hangul */ +#define TT_UCR_HANGUL (1L << 24) /* U+AC00-U+D7A3 */ + + /* Surrogates Area */ + + /* Bit 57 High Surrogates + */ + /* High Private Use Surrogates + */ + /* Low Surrogates */ +#define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ + /* U+DB80-U+DBFF */ + /* U+DC00-U+DFFF */ + /* According to OpenType specs v.1.3+, setting bit 57 implies that there */ + /* is at least one codepoint beyond the Basic Multilingual Plane that is */ + /* supported by this font. So it really means: >= U+10000 */ + + /* Bit 58 is reserved for Unicode SubRanges */ + + /* CJK Ideographs Area */ + + /* Bit 59 CJK Unified Ideographs + */ + /* CJK Radicals Supplement + */ + /* Kangxi Radicals + */ + /* Ideographic Description Characters + */ + /* CJK Unified Ideographs Extension A */ + /* CJK Unified Ideographs Extension A + */ + /* CJK Unified Ideographs Extension B + */ + /* Kanbun */ +#define TT_UCR_CJK_UNIFIED_IDEOGRAPHS (1L << 27) /* U+4E00-U+9FFF */ + /* U+2E80-U+2EFF */ + /* U+2F00-U+2FDF */ + /* U+2FF0-U+2FFF */ + /* U+3400-U+4DB5 */ + /*U+20000-U+2A6DF*/ + /* U+3190-U+319F */ + + /* Private Use Area */ + + /* Bit 60 Private Use */ +#define TT_UCR_PRIVATE_USE (1L << 28) /* U+E000-U+F8FF */ + + /* Compatibility Area and Specials */ + + /* Bit 61 CJK Compatibility Ideographs + */ + /* CJK Compatibility Ideographs Supplement */ +#define TT_UCR_CJK_COMPATIBILITY_IDEOGRAPHS (1L << 29) /* U+F900-U+FAFF */ + /*U+2F800-U+2FA1F*/ + /* Bit 62 Alphabetic Presentation Forms */ +#define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ + /* Bit 63 Arabic Presentation Forms-A */ +#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FDFF */ + /* Bit 64 Combining Half Marks */ +#define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ + /* Bit 65 CJK Compatibility Forms */ +#define TT_UCR_CJK_COMPATIBILITY_FORMS (1L << 1) /* U+FE30-U+FE4F */ + /* Bit 66 Small Form Variants */ +#define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ + /* Bit 67 Arabic Presentation Forms-B */ +#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) /* U+FE70-U+FEFE */ + /* Bit 68 Halfwidth and Fullwidth Forms */ +#define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ + /* Bit 69 Specials */ +#define TT_UCR_SPECIALS (1L << 5) /* U+FFF0-U+FFFD */ + /* Bit 70 Tibetan */ +#define TT_UCR_TIBETAN (1L << 6) /* U+0F00-U+0FFF */ + /* Bit 71 Syriac */ +#define TT_UCR_SYRIAC (1L << 7) /* U+0700-U+074F */ + /* Bit 72 Thaana */ +#define TT_UCR_THAANA (1L << 8) /* U+0780-U+07BF */ + /* Bit 73 Sinhala */ +#define TT_UCR_SINHALA (1L << 9) /* U+0D80-U+0DFF */ + /* Bit 74 Myanmar */ +#define TT_UCR_MYANMAR (1L << 10) /* U+1000-U+109F */ + /* Bit 75 Ethiopic */ +#define TT_UCR_ETHIOPIC (1L << 11) /* U+1200-U+137F */ + /* Bit 76 Cherokee */ +#define TT_UCR_CHEROKEE (1L << 12) /* U+13A0-U+13FF */ + /* Bit 77 Unified Canadian Aboriginal Syllabics */ +#define TT_UCR_CANADIAN_ABORIGINAL_SYLLABICS (1L << 13) /* U+1400-U+167F */ + /* Bit 78 Ogham */ +#define TT_UCR_OGHAM (1L << 14) /* U+1680-U+169F */ + /* Bit 79 Runic */ +#define TT_UCR_RUNIC (1L << 15) /* U+16A0-U+16FF */ + /* Bit 80 Khmer */ +#define TT_UCR_KHMER (1L << 16) /* U+1780-U+17FF */ + /* Bit 81 Mongolian */ +#define TT_UCR_MONGOLIAN (1L << 17) /* U+1800-U+18AF */ + /* Bit 82 Braille Patterns */ +#define TT_UCR_BRAILLE (1L << 18) /* U+2800-U+28FF */ + /* Bit 83 Yi Syllables + */ + /* Yi Radicals */ +#define TT_UCR_YI (1L << 19) /* U+A000-U+A48F */ + /* U+A490-U+A4CF */ + /* Bit 84 Tagalog + */ + /* Hanunoo + */ + /* Buhid + */ + /* Tagbanwa */ +#define TT_UCR_PHILIPPINE (1L << 20) /* U+1700-U+171F */ + /* U+1720-U+173F */ + /* U+1740-U+175F */ + /* U+1760-U+177F */ + /* Bit 85 Old Italic */ +#define TT_UCR_OLD_ITALIC (1L << 21) /*U+10300-U+1032F*/ + /* Bit 86 Gothic */ +#define TT_UCR_GOTHIC (1L << 22) /*U+10330-U+1034F*/ + /* Bit 87 Deseret */ +#define TT_UCR_DESERET (1L << 23) /*U+10400-U+1044F*/ + /* Bit 88 Byzantine Musical Symbols + */ + /* Musical Symbols */ +#define TT_UCR_MUSICAL_SYMBOLS (1L << 24) /*U+1D000-U+1D0FF*/ + /*U+1D100-U+1D1FF*/ + /* Bit 89 Mathematical Alphanumeric Symbols */ +#define TT_UCR_MATH_ALPHANUMERIC_SYMBOLS (1L << 25) /*U+1D400-U+1D7FF*/ + /* Bit 90 Private Use (plane 15) + */ + /* Private Use (plane 16) */ +#define TT_UCR_PRIVATE_USE_SUPPLEMENTARY (1L << 26) /*U+F0000-U+FFFFD*/ + /*U+100000-U+10FFFD*/ + /* Bit 91 Variation Selectors */ +#define TT_UCR_VARIATION_SELECTORS (1L << 27) /* U+FE00-U+FE0F */ + /* Bit 92 Tags */ +#define TT_UCR_TAGS (1L << 28) /*U+E0000-U+E007F*/ + + + /*************************************************************************/ + /* */ + /* Some compilers have a very limited length of identifiers. */ + /* */ +#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ ) +#define HAVE_LIMIT_ON_IDENTS +#endif + + +#ifndef HAVE_LIMIT_ON_IDENTS + + + /*************************************************************************/ + /* */ + /* Here some alias #defines in order to be clearer. */ + /* */ + /* These are not always #defined to stay within the 31~character limit */ + /* which some compilers have. */ + /* */ + /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ + /* Borland compilers (read: from BC++ 3.1 on) can increase this limit. */ + /* If you get a warning with such a compiler, use the -i40 switch. */ + /* */ +#define TT_UCR_ARABIC_PRESENTATION_FORMS_A \ + TT_UCR_ARABIC_PRESENTATIONS_A +#define TT_UCR_ARABIC_PRESENTATION_FORMS_B \ + TT_UCR_ARABIC_PRESENTATIONS_B + +#define TT_UCR_COMBINING_DIACRITICAL_MARKS \ + TT_UCR_COMBINING_DIACRITICS +#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ + TT_UCR_COMBINING_DIACRITICS_SYMB + + +#endif /* !HAVE_LIMIT_ON_IDENTS */ + + +FT_END_HEADER + +#endif /* __TTNAMEID_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/tttables.h b/utils/openttd/freetype/tttables.h new file mode 100644 index 00000000000..72d8e4f291c --- /dev/null +++ b/utils/openttd/freetype/tttables.h @@ -0,0 +1,756 @@ +/***************************************************************************/ +/* */ +/* tttables.h */ +/* */ +/* Basic SFNT/TrueType tables definitions and interface */ +/* (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2008 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTTABLES_H__ +#define __TTTABLES_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* <Section> */ + /* truetype_tables */ + /* */ + /* <Title> */ + /* TrueType Tables */ + /* */ + /* <Abstract> */ + /* TrueType specific table types and functions. */ + /* */ + /* <Description> */ + /* This section contains the definition of TrueType-specific tables */ + /* as well as some routines used to access and process them. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Header */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType font header table. All */ + /* fields follow the TrueType specification. */ + /* */ + typedef struct TT_Header_ + { + FT_Fixed Table_Version; + FT_Fixed Font_Revision; + + FT_Long CheckSum_Adjust; + FT_Long Magic_Number; + + FT_UShort Flags; + FT_UShort Units_Per_EM; + + FT_Long Created [2]; + FT_Long Modified[2]; + + FT_Short xMin; + FT_Short yMin; + FT_Short xMax; + FT_Short yMax; + + FT_UShort Mac_Style; + FT_UShort Lowest_Rec_PPEM; + + FT_Short Font_Direction; + FT_Short Index_To_Loc_Format; + FT_Short Glyph_Data_Format; + + } TT_Header; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_HoriHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType horizontal header, the `hhea' */ + /* table, as well as the corresponding horizontal metrics table, */ + /* i.e., the `hmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of all */ + /* glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoAscender' field */ + /* of the OS/2 table instead if you want */ + /* the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the distance */ + /* from the baseline to the bottom-most of */ + /* all glyph points found in the font. It */ + /* is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of the */ + /* glyphs found in the font (maybe ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Width_Max :: This field is the maximum of all advance */ + /* widths found in the font. It can be */ + /* used to compute the maximum width of an */ + /* arbitrary string of text. */ + /* */ + /* min_Left_Side_Bearing :: The minimum left side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Right_Side_Bearing :: The minimum right side bearing of all */ + /* glyphs within the font. */ + /* */ + /* xMax_Extent :: The maximum horizontal extent (i.e., the */ + /* `width' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of HMetrics entries in the `hmtx' */ + /* table -- this value can be smaller than */ + /* the total number of glyphs in the font. */ + /* */ + /* long_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `hmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields which */ + /* are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_HoriHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Width_Max; /* advance width maximum */ + + FT_Short min_Left_Side_Bearing; /* minimum left-sb */ + FT_Short min_Right_Side_Bearing; /* minimum right-sb */ + FT_Short xMax_Extent; /* xmax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_HMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they are used to connect the metrics header to the relevant */ + /* `HMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_HoriHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_VertHeader */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType vertical header, the `vhea' */ + /* table, as well as the corresponding vertical metrics table, i.e., */ + /* the `vmtx' table. */ + /* */ + /* <Fields> */ + /* Version :: The table version. */ + /* */ + /* Ascender :: The font's ascender, i.e., the distance */ + /* from the baseline to the top-most of */ + /* all glyph points found in the font. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoAscender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Descender :: The font's descender, i.e., the */ + /* distance from the baseline to the */ + /* bottom-most of all glyph points found */ + /* in the font. It is negative. */ + /* */ + /* This value is invalid in many fonts, as */ + /* it is usually set by the font designer, */ + /* and often reflects only a portion of */ + /* the glyphs found in the font (maybe */ + /* ASCII). */ + /* */ + /* You should use the `sTypoDescender' */ + /* field of the OS/2 table instead if you */ + /* want the correct one. */ + /* */ + /* Line_Gap :: The font's line gap, i.e., the distance */ + /* to add to the ascender and descender to */ + /* get the BTB, i.e., the */ + /* baseline-to-baseline distance for the */ + /* font. */ + /* */ + /* advance_Height_Max :: This field is the maximum of all */ + /* advance heights found in the font. It */ + /* can be used to compute the maximum */ + /* height of an arbitrary string of text. */ + /* */ + /* min_Top_Side_Bearing :: The minimum top side bearing of all */ + /* glyphs within the font. */ + /* */ + /* min_Bottom_Side_Bearing :: The minimum bottom side bearing of all */ + /* glyphs within the font. */ + /* */ + /* yMax_Extent :: The maximum vertical extent (i.e., the */ + /* `height' of a glyph's bounding box) for */ + /* all glyphs in the font. */ + /* */ + /* caret_Slope_Rise :: The rise coefficient of the cursor's */ + /* slope of the cursor (slope=rise/run). */ + /* */ + /* caret_Slope_Run :: The run coefficient of the cursor's */ + /* slope. */ + /* */ + /* caret_Offset :: The cursor's offset for slanted fonts. */ + /* This value is `reserved' in vmtx */ + /* version 1.0. */ + /* */ + /* Reserved :: 8~reserved bytes. */ + /* */ + /* metric_Data_Format :: Always~0. */ + /* */ + /* number_Of_HMetrics :: Number of VMetrics entries in the */ + /* `vmtx' table -- this value can be */ + /* smaller than the total number of glyphs */ + /* in the font. */ + /* */ + /* long_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* short_metrics :: A pointer into the `vmtx' table. */ + /* */ + /* <Note> */ + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields which */ + /* are different. */ + /* */ + /* This ensures that a single function in the `ttload' */ + /* module is able to read both the horizontal and vertical */ + /* headers. */ + /* */ + typedef struct TT_VertHeader_ + { + FT_Fixed Version; + FT_Short Ascender; + FT_Short Descender; + FT_Short Line_Gap; + + FT_UShort advance_Height_Max; /* advance height maximum */ + + FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ + FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ + FT_Short yMax_Extent; /* xmax or ymax extents */ + FT_Short caret_Slope_Rise; + FT_Short caret_Slope_Run; + FT_Short caret_Offset; + + FT_Short Reserved[4]; + + FT_Short metric_Data_Format; + FT_UShort number_Of_VMetrics; + + /* The following fields are not defined by the TrueType specification */ + /* but they're used to connect the metrics header to the relevant */ + /* `HMTX' or `VMTX' table. */ + + void* long_metrics; + void* short_metrics; + + } TT_VertHeader; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_OS2 */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType OS/2 table. This is the long */ + /* table version. All fields comply to the TrueType specification. */ + /* */ + /* Note that we now support old Mac fonts which do not include an */ + /* OS/2 table. In this case, the `version' field is always set to */ + /* 0xFFFF. */ + /* */ + typedef struct TT_OS2_ + { + FT_UShort version; /* 0x0001 - more or 0xFFFF */ + FT_Short xAvgCharWidth; + FT_UShort usWeightClass; + FT_UShort usWidthClass; + FT_Short fsType; + FT_Short ySubscriptXSize; + FT_Short ySubscriptYSize; + FT_Short ySubscriptXOffset; + FT_Short ySubscriptYOffset; + FT_Short ySuperscriptXSize; + FT_Short ySuperscriptYSize; + FT_Short ySuperscriptXOffset; + FT_Short ySuperscriptYOffset; + FT_Short yStrikeoutSize; + FT_Short yStrikeoutPosition; + FT_Short sFamilyClass; + + FT_Byte panose[10]; + + FT_ULong ulUnicodeRange1; /* Bits 0-31 */ + FT_ULong ulUnicodeRange2; /* Bits 32-63 */ + FT_ULong ulUnicodeRange3; /* Bits 64-95 */ + FT_ULong ulUnicodeRange4; /* Bits 96-127 */ + + FT_Char achVendID[4]; + + FT_UShort fsSelection; + FT_UShort usFirstCharIndex; + FT_UShort usLastCharIndex; + FT_Short sTypoAscender; + FT_Short sTypoDescender; + FT_Short sTypoLineGap; + FT_UShort usWinAscent; + FT_UShort usWinDescent; + + /* only version 1 tables: */ + + FT_ULong ulCodePageRange1; /* Bits 0-31 */ + FT_ULong ulCodePageRange2; /* Bits 32-63 */ + + /* only version 2 tables: */ + + FT_Short sxHeight; + FT_Short sCapHeight; + FT_UShort usDefaultChar; + FT_UShort usBreakChar; + FT_UShort usMaxContext; + + } TT_OS2; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_Postscript */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PostScript table. All fields */ + /* comply to the TrueType specification. This structure does not */ + /* reference the PostScript glyph names, which can be nevertheless */ + /* accessed with the `ttpost' module. */ + /* */ + typedef struct TT_Postscript_ + { + FT_Fixed FormatType; + FT_Fixed italicAngle; + FT_Short underlinePosition; + FT_Short underlineThickness; + FT_ULong isFixedPitch; + FT_ULong minMemType42; + FT_ULong maxMemType42; + FT_ULong minMemType1; + FT_ULong maxMemType1; + + /* Glyph names follow in the file, but we don't */ + /* load them by default. See the ttpost.c file. */ + + } TT_Postscript; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_PCLT */ + /* */ + /* <Description> */ + /* A structure used to model a TrueType PCLT table. All fields */ + /* comply to the TrueType specification. */ + /* */ + typedef struct TT_PCLT_ + { + FT_Fixed Version; + FT_ULong FontNumber; + FT_UShort Pitch; + FT_UShort xHeight; + FT_UShort Style; + FT_UShort TypeFamily; + FT_UShort CapHeight; + FT_UShort SymbolSet; + FT_Char TypeFace[16]; + FT_Char CharacterComplement[8]; + FT_Char FileName[6]; + FT_Char StrokeWeight; + FT_Char WidthType; + FT_Byte SerifStyle; + FT_Byte Reserved; + + } TT_PCLT; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_MaxProfile */ + /* */ + /* <Description> */ + /* The maximum profile is a table containing many max values which */ + /* can be used to pre-allocate arrays. This ensures that no memory */ + /* allocation occurs during a glyph load. */ + /* */ + /* <Fields> */ + /* version :: The version number. */ + /* */ + /* numGlyphs :: The number of glyphs in this TrueType */ + /* font. */ + /* */ + /* maxPoints :: The maximum number of points in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositePoints'. */ + /* */ + /* maxContours :: The maximum number of contours in a */ + /* non-composite TrueType glyph. See also */ + /* the structure element */ + /* `maxCompositeContours'. */ + /* */ + /* maxCompositePoints :: The maximum number of points in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxPoints'. */ + /* */ + /* maxCompositeContours :: The maximum number of contours in a */ + /* composite TrueType glyph. See also the */ + /* structure element `maxContours'. */ + /* */ + /* maxZones :: The maximum number of zones used for */ + /* glyph hinting. */ + /* */ + /* maxTwilightPoints :: The maximum number of points in the */ + /* twilight zone used for glyph hinting. */ + /* */ + /* maxStorage :: The maximum number of elements in the */ + /* storage area used for glyph hinting. */ + /* */ + /* maxFunctionDefs :: The maximum number of function */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxInstructionDefs :: The maximum number of instruction */ + /* definitions in the TrueType bytecode for */ + /* this font. */ + /* */ + /* maxStackElements :: The maximum number of stack elements used */ + /* during bytecode interpretation. */ + /* */ + /* maxSizeOfInstructions :: The maximum number of TrueType opcodes */ + /* used for glyph hinting. */ + /* */ + /* maxComponentElements :: The maximum number of simple (i.e., non- */ + /* composite) glyphs in a composite glyph. */ + /* */ + /* maxComponentDepth :: The maximum nesting depth of composite */ + /* glyphs. */ + /* */ + /* <Note> */ + /* This structure is only used during font loading. */ + /* */ + typedef struct TT_MaxProfile_ + { + FT_Fixed version; + FT_UShort numGlyphs; + FT_UShort maxPoints; + FT_UShort maxContours; + FT_UShort maxCompositePoints; + FT_UShort maxCompositeContours; + FT_UShort maxZones; + FT_UShort maxTwilightPoints; + FT_UShort maxStorage; + FT_UShort maxFunctionDefs; + FT_UShort maxInstructionDefs; + FT_UShort maxStackElements; + FT_UShort maxSizeOfInstructions; + FT_UShort maxComponentElements; + FT_UShort maxComponentDepth; + + } TT_MaxProfile; + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_Sfnt_Tag */ + /* */ + /* <Description> */ + /* An enumeration used to specify the index of an SFNT table. */ + /* Used in the @FT_Get_Sfnt_Table API function. */ + /* */ + typedef enum FT_Sfnt_Tag_ + { + ft_sfnt_head = 0, + ft_sfnt_maxp = 1, + ft_sfnt_os2 = 2, + ft_sfnt_hhea = 3, + ft_sfnt_vhea = 4, + ft_sfnt_post = 5, + ft_sfnt_pclt = 6, + + sfnt_max /* internal end mark */ + + } FT_Sfnt_Tag; + + /* */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_Table */ + /* */ + /* <Description> */ + /* Return a pointer to a given SFNT table within a face. */ + /* */ + /* <Input> */ + /* face :: A handle to the source. */ + /* */ + /* tag :: The index of the SFNT table. */ + /* */ + /* <Return> */ + /* A type-less pointer to the table. This will be~0 in case of */ + /* error, or if the corresponding table was not found *OR* loaded */ + /* from the file. */ + /* */ + /* <Note> */ + /* The table is owned by the face object and disappears with it. */ + /* */ + /* This function is only useful to access SFNT tables that are loaded */ + /* by the sfnt, truetype, and opentype drivers. See @FT_Sfnt_Tag for */ + /* a list. */ + /* */ + FT_EXPORT( void* ) + FT_Get_Sfnt_Table( FT_Face face, + FT_Sfnt_Tag tag ); + + + /************************************************************************** + * + * @function: + * FT_Load_Sfnt_Table + * + * @description: + * Load any font table into client memory. + * + * @input: + * face :: + * A handle to the source face. + * + * tag :: + * The four-byte tag of the table to load. Use the value~0 if you want + * to access the whole font file. Otherwise, you can use one of the + * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new + * one with @FT_MAKE_TAG. + * + * offset :: + * The starting offset in the table (or file if tag == 0). + * + * @output: + * buffer :: + * The target buffer address. The client must ensure that the memory + * array is big enough to hold the data. + * + * @inout: + * length :: + * If the `length' parameter is NULL, then try to load the whole table. + * Return an error code if it fails. + * + * Else, if `*length' is~0, exit immediately while returning the + * table's (or file) full size in it. + * + * Else the number of bytes to read from the table or file, from the + * starting offset. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If you need to determine the table's length you should first call this + * function with `*length' set to~0, as in the following example: + * + * { + * FT_ULong length = 0; + * + * + * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); + * if ( error ) { ... table does not exist ... } + * + * buffer = malloc( length ); + * if ( buffer == NULL ) { ... not enough memory ... } + * + * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); + * if ( error ) { ... could not load table ... } + * } + */ + FT_EXPORT( FT_Error ) + FT_Load_Sfnt_Table( FT_Face face, + FT_ULong tag, + FT_Long offset, + FT_Byte* buffer, + FT_ULong* length ); + + + /************************************************************************** + * + * @function: + * FT_Sfnt_Table_Info + * + * @description: + * Return information on an SFNT table. + * + * @input: + * face :: + * A handle to the source face. + * + * table_index :: + * The index of an SFNT table. The function returns + * FT_Err_Table_Missing for an invalid value. + * + * @output: + * tag :: + * The name tag of the SFNT table. + * + * length :: + * The length of the SFNT table. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * SFNT tables with length zero are treated as missing by Windows. + * + */ + FT_EXPORT( FT_Error ) + FT_Sfnt_Table_Info( FT_Face face, + FT_UInt table_index, + FT_ULong *tag, + FT_ULong *length ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Language_ID */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap language ID. Definitions of */ + /* language ID values are in `freetype/ttnameid.h'. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The language ID of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, just return~0 as the default value. */ + /* */ + FT_EXPORT( FT_ULong ) + FT_Get_CMap_Language_ID( FT_CharMap charmap ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_CMap_Format */ + /* */ + /* <Description> */ + /* Return TrueType/sfnt specific cmap format. */ + /* */ + /* <Input> */ + /* charmap :: */ + /* The target charmap. */ + /* */ + /* <Return> */ + /* The format of `charmap'. If `charmap' doesn't belong to a */ + /* TrueType/sfnt face, return -1. */ + /* */ + FT_EXPORT( FT_Long ) + FT_Get_CMap_Format( FT_CharMap charmap ); + + /* */ + + +FT_END_HEADER + +#endif /* __TTTABLES_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/tttags.h b/utils/openttd/freetype/tttags.h new file mode 100644 index 00000000000..5a79008209d --- /dev/null +++ b/utils/openttd/freetype/tttags.h @@ -0,0 +1,100 @@ +/***************************************************************************/ +/* */ +/* tttags.h */ +/* */ +/* Tags for TrueType and OpenType tables (specification only). */ +/* */ +/* Copyright 1996-2001, 2004, 2005, 2007 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTAGS_H__ +#define __TTAGS_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + +#define TTAG_avar FT_MAKE_TAG( 'a', 'v', 'a', 'r' ) +#define TTAG_BASE FT_MAKE_TAG( 'B', 'A', 'S', 'E' ) +#define TTAG_bdat FT_MAKE_TAG( 'b', 'd', 'a', 't' ) +#define TTAG_BDF FT_MAKE_TAG( 'B', 'D', 'F', ' ' ) +#define TTAG_bhed FT_MAKE_TAG( 'b', 'h', 'e', 'd' ) +#define TTAG_bloc FT_MAKE_TAG( 'b', 'l', 'o', 'c' ) +#define TTAG_bsln FT_MAKE_TAG( 'b', 's', 'l', 'n' ) +#define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) +#define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) +#define TTAG_cvt FT_MAKE_TAG( 'c', 'v', 't', ' ' ) +#define TTAG_DSIG FT_MAKE_TAG( 'D', 'S', 'I', 'G' ) +#define TTAG_EBDT FT_MAKE_TAG( 'E', 'B', 'D', 'T' ) +#define TTAG_EBLC FT_MAKE_TAG( 'E', 'B', 'L', 'C' ) +#define TTAG_EBSC FT_MAKE_TAG( 'E', 'B', 'S', 'C' ) +#define TTAG_feat FT_MAKE_TAG( 'f', 'e', 'a', 't' ) +#define TTAG_fpgm FT_MAKE_TAG( 'f', 'p', 'g', 'm' ) +#define TTAG_fvar FT_MAKE_TAG( 'f', 'v', 'a', 'r' ) +#define TTAG_gasp FT_MAKE_TAG( 'g', 'a', 's', 'p' ) +#define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' ) +#define TTAG_glyf FT_MAKE_TAG( 'g', 'l', 'y', 'f' ) +#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) +#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) +#define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) +#define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) +#define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) +#define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) +#define TTAG_hmtx FT_MAKE_TAG( 'h', 'm', 't', 'x' ) +#define TTAG_JSTF FT_MAKE_TAG( 'J', 'S', 'T', 'F' ) +#define TTAG_just FT_MAKE_TAG( 'j', 'u', 's', 't' ) +#define TTAG_kern FT_MAKE_TAG( 'k', 'e', 'r', 'n' ) +#define TTAG_lcar FT_MAKE_TAG( 'l', 'c', 'a', 'r' ) +#define TTAG_loca FT_MAKE_TAG( 'l', 'o', 'c', 'a' ) +#define TTAG_LTSH FT_MAKE_TAG( 'L', 'T', 'S', 'H' ) +#define TTAG_MATH FT_MAKE_TAG( 'M', 'A', 'T', 'H' ) +#define TTAG_maxp FT_MAKE_TAG( 'm', 'a', 'x', 'p' ) +#define TTAG_META FT_MAKE_TAG( 'M', 'E', 'T', 'A' ) +#define TTAG_MMFX FT_MAKE_TAG( 'M', 'M', 'F', 'X' ) +#define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) +#define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) +#define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) +#define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) +#define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) +#define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) +#define TTAG_OTTO FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) +#define TTAG_PCLT FT_MAKE_TAG( 'P', 'C', 'L', 'T' ) +#define TTAG_post FT_MAKE_TAG( 'p', 'o', 's', 't' ) +#define TTAG_prep FT_MAKE_TAG( 'p', 'r', 'e', 'p' ) +#define TTAG_prop FT_MAKE_TAG( 'p', 'r', 'o', 'p' ) +#define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) +#define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) +#define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) +#define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) +#define TTAG_ttcf FT_MAKE_TAG( 't', 't', 'c', 'f' ) +#define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) +#define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) +#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) + + +FT_END_HEADER + +#endif /* __TTAGS_H__ */ + + +/* END */ diff --git a/utils/openttd/freetype/ttunpat.h b/utils/openttd/freetype/ttunpat.h new file mode 100644 index 00000000000..a0162759b78 --- /dev/null +++ b/utils/openttd/freetype/ttunpat.h @@ -0,0 +1,59 @@ +/***************************************************************************/ +/* */ +/* ttunpat.h */ +/* */ +/* Definitions for the unpatented TrueType hinting system */ +/* */ +/* Copyright 2003, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Written by Graham Asher <graham.asher@btinternet.com> */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __TTUNPAT_H__ +#define __TTUNPAT_H__ + + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_UNPATENTED_HINTING + * + * @description: + * A constant used as the tag of an @FT_Parameter structure to indicate + * that unpatented methods only should be used by the TrueType bytecode + * interpreter for a typeface opened by @FT_Open_Face. + * + */ +#define FT_PARAM_TAG_UNPATENTED_HINTING FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) + + /* */ + +FT_END_HEADER + + +#endif /* __TTUNPAT_H__ */ + + +/* END */ diff --git a/utils/openttd/ft2build.h b/utils/openttd/ft2build.h new file mode 100644 index 00000000000..923d887df6f --- /dev/null +++ b/utils/openttd/ft2build.h @@ -0,0 +1,39 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* (Generic version) */ +/* */ +/* Copyright 1996-2001, 2006 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + + /*************************************************************************/ + /* */ + /* This file corresponds to the default `ft2build.h' file for */ + /* FreeType 2. It uses the `freetype' include root. */ + /* */ + /* Note that specific platforms might use a different configuration. */ + /* See builds/unix/ft2unix.h for an example. */ + /* */ + /*************************************************************************/ + + +#ifndef __FT2_BUILD_GENERIC_H__ +#define __FT2_BUILD_GENERIC_H__ + +#include <freetype/config/ftheader.h> + +#endif /* __FT2_BUILD_GENERIC_H__ */ + + +/* END */ diff --git a/utils/openttd/png.h b/utils/openttd/png.h new file mode 100644 index 00000000000..80e6645b5c9 --- /dev/null +++ b/utils/openttd/png.h @@ -0,0 +1,3592 @@ +/* png.h - header file for PNG reference library + * + * libpng version 1.2.32 - September 18, 2008 + * Copyright (c) 1998-2008 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * + * Authors and maintainers: + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.2.32 - September 18, 2008: Glenn + * See also "Contributing Authors", below. + * + * Note about libpng version numbers: + * + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: + * + * source png.h png.h shared-lib + * version string int version + * ------- ------ ----- ---------- + * 0.89c "1.0 beta 3" 0.89 89 1.0.89 + * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] + * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] + * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] + * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] + * 0.97c 0.97 97 2.0.97 + * 0.98 0.98 98 2.0.98 + * 0.99 0.99 98 2.0.99 + * 0.99a-m 0.99 99 2.0.99 + * 1.00 1.00 100 2.1.0 [100 should be 10000] + * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] + * 1.0.1 png.h string is 10001 2.1.0 + * 1.0.1a-e identical to the 10002 from here on, the shared library + * 1.0.2 source version) 10002 is 2.V where V is the source code + * 1.0.2a-b 10003 version, except as noted. + * 1.0.3 10003 + * 1.0.3a-d 10004 + * 1.0.4 10004 + * 1.0.4a-f 10005 + * 1.0.5 (+ 2 patches) 10005 + * 1.0.5a-d 10006 + * 1.0.5e-r 10100 (not source compatible) + * 1.0.5s-v 10006 (not binary compatible) + * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) + * 1.0.6d-f 10007 (still binary incompatible) + * 1.0.6g 10007 + * 1.0.6h 10007 10.6h (testing xy.z so-numbering) + * 1.0.6i 10007 10.6i + * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) + * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) + * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) + * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) + * 1.0.7 1 10007 (still compatible) + * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4 + * 1.0.8rc1 1 10008 2.1.0.8rc1 + * 1.0.8 1 10008 2.1.0.8 + * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6 + * 1.0.9rc1 1 10009 2.1.0.9rc1 + * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10 + * 1.0.9rc2 1 10009 2.1.0.9rc2 + * 1.0.9 1 10009 2.1.0.9 + * 1.0.10beta1 1 10010 2.1.0.10beta1 + * 1.0.10rc1 1 10010 2.1.0.10rc1 + * 1.0.10 1 10010 2.1.0.10 + * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 + * 1.0.11rc1 1 10011 2.1.0.11rc1 + * 1.0.11 1 10011 2.1.0.11 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5 + * 1.2.0rc1 3 10200 3.1.2.0rc1 + * 1.2.0 3 10200 3.1.2.0 + * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 + * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 + * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 + * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2 + * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3 + * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3 + * 1.0.15 10 10015 10.so.0.1.0.15 + * 1.2.5 13 10205 12.so.0.1.2.5 + * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4 + * 1.0.16 10 10016 10.so.0.1.0.16 + * 1.2.6 13 10206 12.so.0.1.2.6 + * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 + * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1 + * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 + * 1.0.17 10 10017 10.so.0.1.0.17 + * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 10.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-8 13 10210 12.so.0.10[.0] + * 1.2.10rc1-3 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.0.19rc1-5 10 10019 10.so.0.19[.0] + * 1.2.11rc1-5 13 10211 12.so.0.11[.0] + * 1.0.19 10 10019 10.so.0.19[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.0.20 10 10020 10.so.0.20[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.2.13beta1 13 10213 12.so.0.13[.0] + * 1.0.21 10 10021 10.so.0.21[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.2.14beta1-2 13 10214 12.so.0.14[.0] + * 1.0.22rc1 10 10022 10.so.0.22[.0] + * 1.2.14rc1 13 10214 12.so.0.14[.0] + * 1.0.22 10 10022 10.so.0.22[.0] + * 1.2.14 13 10214 12.so.0.14[.0] + * 1.2.15beta1-6 13 10215 12.so.0.15[.0] + * 1.0.23rc1-5 10 10023 10.so.0.23[.0] + * 1.2.15rc1-5 13 10215 12.so.0.15[.0] + * 1.0.23 10 10023 10.so.0.23[.0] + * 1.2.15 13 10215 12.so.0.15[.0] + * 1.2.16beta1-2 13 10216 12.so.0.16[.0] + * 1.2.16rc1 13 10216 12.so.0.16[.0] + * 1.0.24 10 10024 10.so.0.24[.0] + * 1.2.16 13 10216 12.so.0.16[.0] + * 1.2.17beta1-2 13 10217 12.so.0.17[.0] + * 1.0.25rc1 10 10025 10.so.0.25[.0] + * 1.2.17rc1-3 13 10217 12.so.0.17[.0] + * 1.0.25 10 10025 10.so.0.25[.0] + * 1.2.17 13 10217 12.so.0.17[.0] + * 1.0.26 10 10026 10.so.0.26[.0] + * 1.2.18 13 10218 12.so.0.18[.0] + * 1.2.19beta1-31 13 10219 12.so.0.19[.0] + * 1.0.27rc1-6 10 10027 10.so.0.27[.0] + * 1.2.19rc1-6 13 10219 12.so.0.19[.0] + * 1.0.27 10 10027 10.so.0.27[.0] + * 1.2.19 13 10219 12.so.0.19[.0] + * 1.2.20beta01-04 13 10220 12.so.0.20[.0] + * 1.0.28rc1-6 10 10028 10.so.0.28[.0] + * 1.2.20rc1-6 13 10220 12.so.0.20[.0] + * 1.0.28 10 10028 10.so.0.28[.0] + * 1.2.20 13 10220 12.so.0.20[.0] + * 1.2.21beta1-2 13 10221 12.so.0.21[.0] + * 1.2.21rc1-3 13 10221 12.so.0.21[.0] + * 1.0.29 10 10029 10.so.0.29[.0] + * 1.2.21 13 10221 12.so.0.21[.0] + * 1.2.22beta1-4 13 10222 12.so.0.22[.0] + * 1.0.30rc1 10 10030 10.so.0.30[.0] + * 1.2.22rc1 13 10222 12.so.0.22[.0] + * 1.0.30 10 10030 10.so.0.30[.0] + * 1.2.22 13 10222 12.so.0.22[.0] + * 1.2.23beta01-05 13 10223 12.so.0.23[.0] + * 1.2.23rc01 13 10223 12.so.0.23[.0] + * 1.2.23 13 10223 12.so.0.23[.0] + * 1.2.24beta01-02 13 10224 12.so.0.24[.0] + * 1.2.24rc01 13 10224 12.so.0.24[.0] + * 1.2.24 13 10224 12.so.0.24[.0] + * 1.2.25beta01-06 13 10225 12.so.0.25[.0] + * 1.2.25rc01-02 13 10225 12.so.0.25[.0] + * 1.0.31 10 10031 10.so.0.31[.0] + * 1.2.25 13 10225 12.so.0.25[.0] + * 1.2.26beta01-06 13 10226 12.so.0.26[.0] + * 1.2.26rc01 13 10226 12.so.0.26[.0] + * 1.2.26 13 10226 12.so.0.26[.0] + * 1.0.32 10 10032 10.so.0.32[.0] + * 1.2.27beta01-06 13 10227 12.so.0.27[.0] + * 1.2.27rc01 13 10227 12.so.0.27[.0] + * 1.0.33 10 10033 10.so.0.33[.0] + * 1.2.27 13 10227 12.so.0.27[.0] + * 1.0.34 10 10034 10.so.0.34[.0] + * 1.2.28 13 10228 12.so.0.28[.0] + * 1.2.29beta01-03 13 10229 12.so.0.29[.0] + * 1.2.29rc01 13 10229 12.so.0.29[.0] + * 1.0.35 10 10035 10.so.0.35[.0] + * 1.2.29 13 10229 12.so.0.29[.0] + * 1.0.37 10 10037 10.so.0.37[.0] + * 1.2.30beta01-04 13 10230 12.so.0.30[.0] + * 1.0.38rc01-08 10 10038 10.so.0.38[.0] + * 1.2.30rc01-08 13 10230 12.so.0.30[.0] + * 1.0.38 10 10038 10.so.0.38[.0] + * 1.2.30 13 10230 12.so.0.30[.0] + * 1.0.39rc01-03 10 10039 10.so.0.39[.0] + * 1.2.31rc01-03 13 10231 12.so.0.31[.0] + * 1.0.39 10 10039 10.so.0.39[.0] + * 1.2.31 13 10231 12.so.0.31[.0] + * 1.2.32beta01-02 13 10232 12.so.0.32[.0] + * 1.0.40rc01 10 10040 10.so.0.40[.0] + * 1.2.32rc01 13 10232 12.so.0.32[.0] + * 1.0.40 10 10040 10.so.0.40[.0] + * 1.2.32 13 10232 12.so.0.32[.0] + * + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcNN". + * + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. + * + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). + * + * See libpng.txt or libpng.3 for more information. The PNG specification + * is available as a W3C Recommendation and as an ISO Specification, + * <http://www.w3.org/TR/2003/REC-PNG-20031110/ + */ + +/* + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + * + * If you modify libpng you may insert additional notices immediately following + * this sentence. + * + * libpng versions 1.2.6, August 15, 2004, through 1.2.32, September 18, 2008, are + * Copyright (c) 2004, 2006-2008 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.2.5 + * with the following individual added to the list of Contributing Authors: + * + * Cosmin Truta + * + * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are + * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-1.0.6 + * with the following individuals added to the list of Contributing Authors: + * + * Simon-Pierre Cadieux + * Eric S. Raymond + * Gilles Vollant + * + * and with the following additions to the disclaimer: + * + * There is no warranty against interference with your enjoyment of the + * library or against infringement. There is no warranty that our + * efforts or the library will fulfill any of your particular purposes + * or needs. This library is provided with all faults, and the entire + * risk of satisfactory quality, performance, accuracy, and effort is with + * the user. + * + * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are + * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are + * distributed according to the same disclaimer and license as libpng-0.96, + * with the following individuals added to the list of Contributing Authors: + * + * Tom Lane + * Glenn Randers-Pehrson + * Willem van Schaik + * + * libpng versions 0.89, June 1996, through 0.96, May 1997, are + * Copyright (c) 1996, 1997 Andreas Dilger + * Distributed according to the same disclaimer and license as libpng-0.88, + * with the following individuals added to the list of Contributing Authors: + * + * John Bowler + * Kevin Bracey + * Sam Bushell + * Magnus Holmgren + * Greg Roelofs + * Tom Tanner + * + * libpng versions 0.5, May 1995, through 0.88, January 1996, are + * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + * + * For the purposes of this copyright and license, "Contributing Authors" + * is defined as the following set of individuals: + * + * Andreas Dilger + * Dave Martindale + * Guy Eric Schalnat + * Paul Schmidt + * Tim Wegner + * + * The PNG Reference Library is supplied "AS IS". The Contributing Authors + * and Group 42, Inc. disclaim all warranties, expressed or implied, + * including, without limitation, the warranties of merchantability and of + * fitness for any purpose. The Contributing Authors and Group 42, Inc. + * assume no liability for direct, indirect, incidental, special, exemplary, + * or consequential damages, which may result from the use of the PNG + * Reference Library, even if advised of the possibility of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * source code, or portions hereof, for any purpose, without fee, subject + * to the following restrictions: + * + * 1. The origin of this source code must not be misrepresented. + * + * 2. Altered versions must be plainly marked as such and + * must not be misrepresented as being the original source. + * + * 3. This Copyright notice may not be removed or altered from + * any source or altered source distribution. + * + * The Contributing Authors and Group 42, Inc. specifically permit, without + * fee, and encourage the use of this source code as a component to + * supporting the PNG file format in commercial products. If you use this + * source code in a product, acknowledgment is not required but would be + * appreciated. + */ + +/* + * A "png_get_copyright" function is available, for convenient use in "about" + * boxes and the like: + * + * printf("%s",png_get_copyright(NULL)); + * + * Also, the PNG logo (in PNG format, of course) is supplied in the + * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + */ + +/* + * Libpng is OSI Certified Open Source Software. OSI Certified is a + * certification mark of the Open Source Initiative. + */ + +/* + * The contributing authors would like to thank all those who helped + * with testing, bug fixes, and patience. This wouldn't have been + * possible without all of you. + * + * Thanks to Frank J. T. Wojcik for helping with the documentation. + */ + +/* + * Y2K compliance in libpng: + * ========================= + * + * September 18, 2008 + * + * Since the PNG Development group is an ad-hoc body, we can't make + * an official declaration. + * + * This is your unofficial assurance that libpng from version 0.71 and + * upward through 1.2.32 are Y2K compliant. It is my belief that earlier + * versions were also Y2K compliant. + * + * Libpng only has three year fields. One is a 2-byte unsigned integer + * that will hold years up to 65535. The other two hold the date in text + * format, and will hold years up to 9999. + * + * The integer is + * "png_uint_16 year" in png_time_struct. + * + * The strings are + * "png_charp time_buffer" in png_struct and + * "near_time_buffer", which is a local character string in png.c. + * + * There are seven time-related functions: + * png.c: png_convert_to_rfc_1123() in png.c + * (formerly png_convert_to_rfc_1152() in error) + * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c + * png_convert_from_time_t() in pngwrite.c + * png_get_tIME() in pngget.c + * png_handle_tIME() in pngrutil.c, called in pngread.c + * png_set_tIME() in pngset.c + * png_write_tIME() in pngwutil.c, called in pngwrite.c + * + * All handle dates properly in a Y2K environment. The + * png_convert_from_time_t() function calls gmtime() to convert from system + * clock time, which returns (year - 1900), which we properly convert to + * the full 4-digit year. There is a possibility that applications using + * libpng are not passing 4-digit years into the png_convert_to_rfc_1123() + * function, or that they are incorrectly passing only a 2-digit year + * instead of "year - 1900" into the png_convert_from_struct_tm() function, + * but this is not under our control. The libpng documentation has always + * stated that it works with 4-digit years, and the APIs have been + * documented as such. + * + * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned + * integer to hold the year, and can hold years as large as 65535. + * + * zlib, upon which libpng depends, is also Y2K compliant. It contains + * no date-related code. + * + * Glenn Randers-Pehrson + * libpng maintainer + * PNG Development Group + */ + +#ifndef PNG_H +#define PNG_H + +/* This is not the place to learn how to use libpng. The file libpng.txt + * describes how to use libpng, and the file example.c summarizes it + * with some code on which to build. This file is useful for looking + * at the actual function definitions and structure components. + */ + +/* Version information for png.h - this should match the version in png.c */ +#define PNG_LIBPNG_VER_STRING "1.2.32" +#define PNG_HEADER_VERSION_STRING \ + " libpng version 1.2.32 - September 18, 2008\n" + +#define PNG_LIBPNG_VER_SONUM 0 +#define PNG_LIBPNG_VER_DLLNUM 13 + +/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ +#define PNG_LIBPNG_VER_MAJOR 1 +#define PNG_LIBPNG_VER_MINOR 2 +#define PNG_LIBPNG_VER_RELEASE 32 +/* This should match the numeric part of the final component of + * PNG_LIBPNG_VER_STRING, omitting any leading zero: */ + +#define PNG_LIBPNG_VER_BUILD 0 + +/* Release Status */ +#define PNG_LIBPNG_BUILD_ALPHA 1 +#define PNG_LIBPNG_BUILD_BETA 2 +#define PNG_LIBPNG_BUILD_RC 3 +#define PNG_LIBPNG_BUILD_STABLE 4 +#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7 + +/* Release-Specific Flags */ +#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with + PNG_LIBPNG_BUILD_STABLE only */ +#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_SPECIAL */ +#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_PRIVATE */ + +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE + +/* Careful here. At one time, Guy wanted to use 082, but that would be octal. + * We must not include leading zeros. + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only + * version 1.0.0 was mis-numbered 100 instead of 10000). From + * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ +#define PNG_LIBPNG_VER 10232 /* 1.2.32 */ + +#ifndef PNG_VERSION_INFO_ONLY +/* include the compression library's header */ +#include "zlib.h" +#endif + +/* include all user configurable info, including optional assembler routines */ +#include "pngconf.h" + +/* + * Added at libpng-1.2.8 */ +/* Ref MSDN: Private as priority over Special + * VS_FF_PRIVATEBUILD File *was not* built using standard release + * procedures. If this value is given, the StringFileInfo block must + * contain a PrivateBuild string. + * + * VS_FF_SPECIALBUILD File *was* built by the original company using + * standard release procedures but is a variation of the standard + * file of the same version number. If this value is given, the + * StringFileInfo block must contain a SpecialBuild string. + */ + +#if defined(PNG_USER_PRIVATEBUILD) +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) +#else +# if defined(PNG_LIBPNG_SPECIALBUILD) +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) +# else +# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) +# endif +#endif + +#ifndef PNG_VERSION_INFO_ONLY + +/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* This file is arranged in several sections. The first section contains + * structure and type definitions. The second section contains the external + * library functions, while the third has the internal library functions, + * which applications aren't expected to use directly. + */ + +#ifndef PNG_NO_TYPECAST_NULL +#define int_p_NULL (int *)NULL +#define png_bytep_NULL (png_bytep)NULL +#define png_bytepp_NULL (png_bytepp)NULL +#define png_doublep_NULL (png_doublep)NULL +#define png_error_ptr_NULL (png_error_ptr)NULL +#define png_flush_ptr_NULL (png_flush_ptr)NULL +#define png_free_ptr_NULL (png_free_ptr)NULL +#define png_infopp_NULL (png_infopp)NULL +#define png_malloc_ptr_NULL (png_malloc_ptr)NULL +#define png_read_status_ptr_NULL (png_read_status_ptr)NULL +#define png_rw_ptr_NULL (png_rw_ptr)NULL +#define png_structp_NULL (png_structp)NULL +#define png_uint_16p_NULL (png_uint_16p)NULL +#define png_voidp_NULL (png_voidp)NULL +#define png_write_status_ptr_NULL (png_write_status_ptr)NULL +#else +#define int_p_NULL NULL +#define png_bytep_NULL NULL +#define png_bytepp_NULL NULL +#define png_doublep_NULL NULL +#define png_error_ptr_NULL NULL +#define png_flush_ptr_NULL NULL +#define png_free_ptr_NULL NULL +#define png_infopp_NULL NULL +#define png_malloc_ptr_NULL NULL +#define png_read_status_ptr_NULL NULL +#define png_rw_ptr_NULL NULL +#define png_structp_NULL NULL +#define png_uint_16p_NULL NULL +#define png_voidp_NULL NULL +#define png_write_status_ptr_NULL NULL +#endif + +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) +/* Version information for C files, stored in png.c. This had better match + * the version above. + */ +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (PNG_CONST char) png_libpng_ver[18]; + /* need room for 99.99.99beta99z */ +#else +#define png_libpng_ver png_get_header_ver(NULL) +#endif + +#ifdef PNG_USE_GLOBAL_ARRAYS +/* This was removed in version 1.0.5c */ +/* Structures to facilitate easy interlacing. See png.c for more details */ +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_start[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_inc[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_ystart[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_yinc[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_mask[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_dsp_mask[7]; +/* This isn't currently used. If you need it, see png.c for more details. +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_height[7]; +*/ +#endif + +#endif /* PNG_NO_EXTERN */ + +/* Three color definitions. The order of the red, green, and blue, (and the + * exact size) is not important, although the size of the fields need to + * be png_byte or png_uint_16 (as defined below). + */ +typedef struct png_color_struct +{ + png_byte red; + png_byte green; + png_byte blue; +} png_color; +typedef png_color FAR * png_colorp; +typedef png_color FAR * FAR * png_colorpp; + +typedef struct png_color_16_struct +{ + png_byte index; /* used for palette files */ + png_uint_16 red; /* for use in red green blue files */ + png_uint_16 green; + png_uint_16 blue; + png_uint_16 gray; /* for use in grayscale files */ +} png_color_16; +typedef png_color_16 FAR * png_color_16p; +typedef png_color_16 FAR * FAR * png_color_16pp; + +typedef struct png_color_8_struct +{ + png_byte red; /* for use in red green blue files */ + png_byte green; + png_byte blue; + png_byte gray; /* for use in grayscale files */ + png_byte alpha; /* for alpha channel files */ +} png_color_8; +typedef png_color_8 FAR * png_color_8p; +typedef png_color_8 FAR * FAR * png_color_8pp; + +/* + * The following two structures are used for the in-core representation + * of sPLT chunks. + */ +typedef struct png_sPLT_entry_struct +{ + png_uint_16 red; + png_uint_16 green; + png_uint_16 blue; + png_uint_16 alpha; + png_uint_16 frequency; +} png_sPLT_entry; +typedef png_sPLT_entry FAR * png_sPLT_entryp; +typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp; + +/* When the depth of the sPLT palette is 8 bits, the color and alpha samples + * occupy the LSB of their respective members, and the MSB of each member + * is zero-filled. The frequency member always occupies the full 16 bits. + */ + +typedef struct png_sPLT_struct +{ + png_charp name; /* palette name */ + png_byte depth; /* depth of palette samples */ + png_sPLT_entryp entries; /* palette entries */ + png_int_32 nentries; /* number of palette entries */ +} png_sPLT_t; +typedef png_sPLT_t FAR * png_sPLT_tp; +typedef png_sPLT_t FAR * FAR * png_sPLT_tpp; + +#ifdef PNG_TEXT_SUPPORTED +/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, + * and whether that contents is compressed or not. The "key" field + * points to a regular zero-terminated C string. The "text", "lang", and + * "lang_key" fields can be regular C strings, empty strings, or NULL pointers. + * However, the * structure returned by png_get_text() will always contain + * regular zero-terminated C strings (possibly empty), never NULL pointers, + * so they can be safely used in printf() and other string-handling functions. + */ +typedef struct png_text_struct +{ + int compression; /* compression value: + -1: tEXt, none + 0: zTXt, deflate + 1: iTXt, none + 2: iTXt, deflate */ + png_charp key; /* keyword, 1-79 character description of "text" */ + png_charp text; /* comment, may be an empty string (ie "") + or a NULL pointer */ + png_size_t text_length; /* length of the text string */ +#ifdef PNG_iTXt_SUPPORTED + png_size_t itxt_length; /* length of the itxt string */ + png_charp lang; /* language code, 0-79 characters + or a NULL pointer */ + png_charp lang_key; /* keyword translated UTF-8 string, 0 or more + chars or a NULL pointer */ +#endif +} png_text; +typedef png_text FAR * png_textp; +typedef png_text FAR * FAR * png_textpp; +#endif + +/* Supported compression types for text in PNG files (tEXt, and zTXt). + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ +#define PNG_TEXT_COMPRESSION_NONE_WR -3 +#define PNG_TEXT_COMPRESSION_zTXt_WR -2 +#define PNG_TEXT_COMPRESSION_NONE -1 +#define PNG_TEXT_COMPRESSION_zTXt 0 +#define PNG_ITXT_COMPRESSION_NONE 1 +#define PNG_ITXT_COMPRESSION_zTXt 2 +#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ + +/* png_time is a way to hold the time in an machine independent way. + * Two conversions are provided, both from time_t and struct tm. There + * is no portable way to convert to either of these structures, as far + * as I know. If you know of a portable way, send it to me. As a side + * note - PNG has always been Year 2000 compliant! + */ +typedef struct png_time_struct +{ + png_uint_16 year; /* full year, as in, 1995 */ + png_byte month; /* month of year, 1 - 12 */ + png_byte day; /* day of month, 1 - 31 */ + png_byte hour; /* hour of day, 0 - 23 */ + png_byte minute; /* minute of hour, 0 - 59 */ + png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ +} png_time; +typedef png_time FAR * png_timep; +typedef png_time FAR * FAR * png_timepp; + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +/* png_unknown_chunk is a structure to hold queued chunks for which there is + * no specific support. The idea is that we can use this to queue + * up private chunks for output even though the library doesn't actually + * know about their semantics. + */ +#define PNG_CHUNK_NAME_LENGTH 5 +typedef struct png_unknown_chunk_t +{ + png_byte name[PNG_CHUNK_NAME_LENGTH]; + png_byte *data; + png_size_t size; + + /* libpng-using applications should NOT directly modify this byte. */ + png_byte location; /* mode of operation at read time */ +} +png_unknown_chunk; +typedef png_unknown_chunk FAR * png_unknown_chunkp; +typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp; +#endif + +/* png_info is a structure that holds the information in a PNG file so + * that the application can find out the characteristics of the image. + * If you are reading the file, this structure will tell you what is + * in the PNG file. If you are writing the file, fill in the information + * you want to put into the PNG file, then call png_write_info(). + * The names chosen should be very close to the PNG specification, so + * consult that document for information about the meaning of each field. + * + * With libpng < 0.95, it was only possible to directly set and read the + * the values in the png_info_struct, which meant that the contents and + * order of the values had to remain fixed. With libpng 0.95 and later, + * however, there are now functions that abstract the contents of + * png_info_struct from the application, so this makes it easier to use + * libpng with dynamic libraries, and even makes it possible to use + * libraries that don't have all of the libpng ancillary chunk-handing + * functionality. + * + * In any case, the order of the parameters in png_info_struct should NOT + * be changed for as long as possible to keep compatibility with applications + * that use the old direct-access method with png_info_struct. + * + * The following members may have allocated storage attached that should be + * cleaned up before the structure is discarded: palette, trans, text, + * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, + * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these + * are automatically freed when the info structure is deallocated, if they were + * allocated internally by libpng. This behavior can be changed by means + * of the png_data_freer() function. + * + * More allocation details: all the chunk-reading functions that + * change these members go through the corresponding png_set_* + * functions. A function to clear these members is available: see + * png_free_data(). The png_set_* functions do not depend on being + * able to point info structure members to any of the storage they are + * passed (they make their own copies), EXCEPT that the png_set_text + * functions use the same storage passed to them in the text_ptr or + * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns + * functions do not make their own copies. + */ +typedef struct png_info_struct +{ + /* the following are necessary for every PNG file */ + png_uint_32 width; /* width of image in pixels (from IHDR) */ + png_uint_32 height; /* height of image in pixels (from IHDR) */ + png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ + png_uint_32 rowbytes; /* bytes needed to hold an untransformed row */ + png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ + png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ + png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ + png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */ + png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */ + /* The following three should have been named *_method not *_type */ + png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ + png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ + png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + + /* The following is informational only on read, and not used on writes. */ + png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte spare_byte; /* to align the data, and for future use */ + png_byte signature[8]; /* magic bytes read by libpng from start of file */ + + /* The rest of the data is optional. If you are reading, check the + * valid field to see if the information in these are valid. If you + * are writing, set the valid field to those chunks you want written, + * and initialize the appropriate fields below. + */ + +#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) + /* The gAMA chunk describes the gamma characteristics of the system + * on which the image was created, normally in the range [1.0, 2.5]. + * Data is valid if (valid & PNG_INFO_gAMA) is non-zero. + */ + float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */ +#endif + +#if defined(PNG_sRGB_SUPPORTED) + /* GR-P, 0.96a */ + /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */ + png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */ +#endif + +#if defined(PNG_TEXT_SUPPORTED) + /* The tEXt, and zTXt chunks contain human-readable textual data in + * uncompressed, compressed, and optionally compressed forms, respectively. + * The data in "text" is an array of pointers to uncompressed, + * null-terminated C strings. Each chunk has a keyword that describes the + * textual data contained in that chunk. Keywords are not required to be + * unique, and the text string may be empty. Any number of text chunks may + * be in an image. + */ + int num_text; /* number of comments read/to write */ + int max_text; /* current size of text array */ + png_textp text; /* array of comments read/to write */ +#endif /* PNG_TEXT_SUPPORTED */ + +#if defined(PNG_tIME_SUPPORTED) + /* The tIME chunk holds the last time the displayed image data was + * modified. See the png_time struct for the contents of this struct. + */ + png_time mod_time; +#endif + +#if defined(PNG_sBIT_SUPPORTED) + /* The sBIT chunk specifies the number of significant high-order bits + * in the pixel data. Values are in the range [1, bit_depth], and are + * only specified for the channels in the pixel data. The contents of + * the low-order bits is not specified. Data is valid if + * (valid & PNG_INFO_sBIT) is non-zero. + */ + png_color_8 sig_bit; /* significant bits in color channels */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ +defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The tRNS chunk supplies transparency data for paletted images and + * other image types that don't need a full alpha channel. There are + * "num_trans" transparency values for a paletted image, stored in the + * same order as the palette colors, starting from index 0. Values + * for the data are in the range [0, 255], ranging from fully transparent + * to fully opaque, respectively. For non-paletted images, there is a + * single color specified that should be treated as fully transparent. + * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. + */ + png_bytep trans; /* transparent values for paletted image */ + png_color_16 trans_values; /* transparent color for non-palette image */ +#endif + +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + /* The bKGD chunk gives the suggested image background color if the + * display program does not have its own background color and the image + * is needs to composited onto a background before display. The colors + * in "background" are normally in the same color space/depth as the + * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. + */ + png_color_16 background; +#endif + +#if defined(PNG_oFFs_SUPPORTED) + /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards + * and downwards from the top-left corner of the display, page, or other + * application-specific co-ordinate space. See the PNG_OFFSET_ defines + * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. + */ + png_int_32 x_offset; /* x offset on page */ + png_int_32 y_offset; /* y offset on page */ + png_byte offset_unit_type; /* offset units type */ +#endif + +#if defined(PNG_pHYs_SUPPORTED) + /* The pHYs chunk gives the physical pixel density of the image for + * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ + * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. + */ + png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ + png_uint_32 y_pixels_per_unit; /* vertical pixel density */ + png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ +#endif + +#if defined(PNG_hIST_SUPPORTED) + /* The hIST chunk contains the relative frequency or importance of the + * various palette entries, so that a viewer can intelligently select a + * reduced-color palette, if required. Data is an array of "num_palette" + * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) + * is non-zero. + */ + png_uint_16p hist; +#endif + +#ifdef PNG_cHRM_SUPPORTED + /* The cHRM chunk describes the CIE color characteristics of the monitor + * on which the PNG was created. This data allows the viewer to do gamut + * mapping of the input image to ensure that the viewer sees the same + * colors in the image as the creator. Values are in the range + * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero. + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + float x_white; + float y_white; + float x_red; + float y_red; + float x_green; + float y_green; + float x_blue; + float y_blue; +#endif +#endif + +#if defined(PNG_pCAL_SUPPORTED) + /* The pCAL chunk describes a transformation between the stored pixel + * values and original physical data values used to create the image. + * The integer range [0, 2^bit_depth - 1] maps to the floating-point + * range given by [pcal_X0, pcal_X1], and are further transformed by a + * (possibly non-linear) transformation function given by "pcal_type" + * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ + * defines below, and the PNG-Group's PNG extensions document for a + * complete description of the transformations and how they should be + * implemented, and for a description of the ASCII parameter strings. + * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. + */ + png_charp pcal_purpose; /* pCAL chunk description string */ + png_int_32 pcal_X0; /* minimum value */ + png_int_32 pcal_X1; /* maximum value */ + png_charp pcal_units; /* Latin-1 string giving physical units */ + png_charpp pcal_params; /* ASCII strings containing parameter values */ + png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ + png_byte pcal_nparams; /* number of parameters given in pcal_params */ +#endif + +/* New members added in libpng-1.0.6 */ +#ifdef PNG_FREE_ME_SUPPORTED + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + /* storage for unknown chunks that the library doesn't recognize. */ + png_unknown_chunkp unknown_chunks; + png_size_t unknown_chunks_num; +#endif + +#if defined(PNG_iCCP_SUPPORTED) + /* iCCP chunk data. */ + png_charp iccp_name; /* profile name */ + png_charp iccp_profile; /* International Color Consortium profile data */ + /* Note to maintainer: should be png_bytep */ + png_uint_32 iccp_proflen; /* ICC profile data length */ + png_byte iccp_compression; /* Always zero */ +#endif + +#if defined(PNG_sPLT_SUPPORTED) + /* data on sPLT chunks (there may be more than one). */ + png_sPLT_tp splt_palettes; + png_uint_32 splt_palettes_num; +#endif + +#if defined(PNG_sCAL_SUPPORTED) + /* The sCAL chunk describes the actual physical dimensions of the + * subject matter of the graphic. The chunk contains a unit specification + * a byte value, and two ASCII strings representing floating-point + * values. The values are width and height corresponsing to one pixel + * in the image. This external representation is converted to double + * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero. + */ + png_byte scal_unit; /* unit of physical scale */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + double scal_pixel_width; /* width of one pixel */ + double scal_pixel_height; /* height of one pixel */ +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED + png_charp scal_s_width; /* string containing height */ + png_charp scal_s_height; /* string containing width */ +#endif +#endif + +#if defined(PNG_INFO_IMAGE_SUPPORTED) + /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */ + /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ + png_bytepp row_pointers; /* the image bits */ +#endif + +#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED) + png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */ +#endif + +#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED) + png_fixed_point int_x_white; + png_fixed_point int_y_white; + png_fixed_point int_x_red; + png_fixed_point int_y_red; + png_fixed_point int_x_green; + png_fixed_point int_y_green; + png_fixed_point int_x_blue; + png_fixed_point int_y_blue; +#endif + +} png_info; + +typedef png_info FAR * png_infop; +typedef png_info FAR * FAR * png_infopp; + +/* Maximum positive integer used in PNG is (2^31)-1 */ +#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) +#define PNG_UINT_32_MAX ((png_uint_32)(-1)) +#define PNG_SIZE_MAX ((png_size_t)(-1)) +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */ +#define PNG_MAX_UINT PNG_UINT_31_MAX +#endif + +/* These describe the color_type field in png_info. */ +/* color type masks */ +#define PNG_COLOR_MASK_PALETTE 1 +#define PNG_COLOR_MASK_COLOR 2 +#define PNG_COLOR_MASK_ALPHA 4 + +/* color types. Note that not all combinations are legal */ +#define PNG_COLOR_TYPE_GRAY 0 +#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) +#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) +#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) +#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) +/* aliases */ +#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA +#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA + +/* This is for compression type. PNG 1.0-1.2 only define the single type. */ +#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ +#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE + +/* This is for filter type. PNG 1.0-1.2 only define the single type. */ +#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ +#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ +#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE + +/* These are for the interlacing type. These values should NOT be changed. */ +#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ +#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ +#define PNG_INTERLACE_LAST 2 /* Not a valid value */ + +/* These are for the oFFs chunk. These values should NOT be changed. */ +#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ +#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ +#define PNG_OFFSET_LAST 2 /* Not a valid value */ + +/* These are for the pCAL chunk. These values should NOT be changed. */ +#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ +#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ +#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ +#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ +#define PNG_EQUATION_LAST 4 /* Not a valid value */ + +/* These are for the sCAL chunk. These values should NOT be changed. */ +#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ +#define PNG_SCALE_METER 1 /* meters per pixel */ +#define PNG_SCALE_RADIAN 2 /* radians per pixel */ +#define PNG_SCALE_LAST 3 /* Not a valid value */ + +/* These are for the pHYs chunk. These values should NOT be changed. */ +#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ +#define PNG_RESOLUTION_METER 1 /* pixels/meter */ +#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ + +/* These are for the sRGB chunk. These values should NOT be changed. */ +#define PNG_sRGB_INTENT_PERCEPTUAL 0 +#define PNG_sRGB_INTENT_RELATIVE 1 +#define PNG_sRGB_INTENT_SATURATION 2 +#define PNG_sRGB_INTENT_ABSOLUTE 3 +#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ + +/* This is for text chunks */ +#define PNG_KEYWORD_MAX_LENGTH 79 + +/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ +#define PNG_MAX_PALETTE_LENGTH 256 + +/* These determine if an ancillary chunk's data has been successfully read + * from the PNG header, or if the application has filled in the corresponding + * data in the info_struct to be written into the output file. The values + * of the PNG_INFO_<chunk> defines should NOT be changed. + */ +#define PNG_INFO_gAMA 0x0001 +#define PNG_INFO_sBIT 0x0002 +#define PNG_INFO_cHRM 0x0004 +#define PNG_INFO_PLTE 0x0008 +#define PNG_INFO_tRNS 0x0010 +#define PNG_INFO_bKGD 0x0020 +#define PNG_INFO_hIST 0x0040 +#define PNG_INFO_pHYs 0x0080 +#define PNG_INFO_oFFs 0x0100 +#define PNG_INFO_tIME 0x0200 +#define PNG_INFO_pCAL 0x0400 +#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ +#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */ + +/* This is used for the transformation routines, as some of them + * change these values for the row. It also should enable using + * the routines for other purposes. + */ +typedef struct png_row_info_struct +{ + png_uint_32 width; /* width of row */ + png_uint_32 rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_byte pixel_depth; /* bits per pixel (depth * channels) */ +} png_row_info; + +typedef png_row_info FAR * png_row_infop; +typedef png_row_info FAR * FAR * png_row_infopp; + +/* These are the function types for the I/O functions and for the functions + * that allow the user to override the default I/O functions with his or her + * own. The png_error_ptr type should match that of user-supplied warning + * and error functions, while the png_rw_ptr type should match that of the + * user read/write data functions. + */ +typedef struct png_struct_def png_struct; +typedef png_struct FAR * png_structp; + +typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp)); +typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t)); +typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp)); +typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32, + int)); +typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32, + int)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); +typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, + png_uint_32, int)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp, + png_row_infop, png_bytep)); +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) +typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp)); +#endif +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp)); +#endif + +/* Transform masks for the high-level interface */ +#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ +#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ +#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ +#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ +#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ +#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ +#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ +#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ +#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ +#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ +#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ +#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */ + +/* Flags for MNG supported features */ +#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 +#define PNG_FLAG_MNG_FILTER_64 0x04 +#define PNG_ALL_MNG_FEATURES 0x05 + +typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t)); +typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp)); + +/* The structure that holds the information to read and write PNG files. + * The only people who need to care about what is inside of this are the + * people who will be modifying the library for their own special needs. + * It should NOT be accessed directly by an application, except to store + * the jmp_buf. + */ + +struct png_struct_def +{ +#ifdef PNG_SETJMP_SUPPORTED + jmp_buf jmpbuf; /* used in png_error */ +#endif + png_error_ptr error_fn; /* function for printing errors and aborting */ + png_error_ptr warning_fn; /* function for printing warnings */ + png_voidp error_ptr; /* user supplied struct for error functions */ + png_rw_ptr write_data_fn; /* function for writing output data */ + png_rw_ptr read_data_fn; /* function for reading input data */ + png_voidp io_ptr; /* ptr to application struct for I/O functions */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr read_user_transform_fn; /* user read transform */ +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_user_transform_ptr write_user_transform_fn; /* user write transform */ +#endif + +/* These were added in libpng-1.0.2 */ +#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) + png_voidp user_transform_ptr; /* user supplied struct for user transform */ + png_byte user_transform_depth; /* bit depth of user transformed pixels */ + png_byte user_transform_channels; /* channels in user transformed pixels */ +#endif +#endif + + png_uint_32 mode; /* tells us where we are in the PNG file */ + png_uint_32 flags; /* flags indicating various things to libpng */ + png_uint_32 transformations; /* which transformations to perform */ + + z_stream zstream; /* pointer to decompression structure (below) */ + png_bytep zbuf; /* buffer for zlib */ + png_size_t zbuf_size; /* size of zbuf */ + int zlib_level; /* holds zlib compression level */ + int zlib_method; /* holds zlib compression method */ + int zlib_window_bits; /* holds zlib compression window bits */ + int zlib_mem_level; /* holds zlib compression memory level */ + int zlib_strategy; /* holds zlib compression strategy */ + + png_uint_32 width; /* width of image in pixels */ + png_uint_32 height; /* height of image in pixels */ + png_uint_32 num_rows; /* number of rows in current pass */ + png_uint_32 usr_width; /* width of row at start of write */ + png_uint_32 rowbytes; /* size of row in bytes */ + png_uint_32 irowbytes; /* size of current interlaced row in bytes */ + png_uint_32 iwidth; /* width of current interlaced row in pixels */ + png_uint_32 row_number; /* current row in interlace pass */ + png_bytep prev_row; /* buffer to save previous (unfiltered) row */ + png_bytep row_buf; /* buffer to save current (unfiltered) row */ +#ifndef PNG_NO_WRITE_FILTER + png_bytep sub_row; /* buffer to save "sub" row when filtering */ + png_bytep up_row; /* buffer to save "up" row when filtering */ + png_bytep avg_row; /* buffer to save "avg" row when filtering */ + png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ +#endif + png_row_info row_info; /* used for transformation routines */ + + png_uint_32 idat_size; /* current IDAT size for read */ + png_uint_32 crc; /* current chunk CRC value */ + png_colorp palette; /* palette from the input file */ + png_uint_16 num_palette; /* number of color entries in palette */ + png_uint_16 num_trans; /* number of transparency values */ + png_byte chunk_name[5]; /* null-terminated name of current chunk */ + png_byte compression; /* file compression type (always 0) */ + png_byte filter; /* file filter type (always 0) */ + png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ + png_byte pass; /* current interlace pass (0 - 6) */ + png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */ + png_byte color_type; /* color type of file */ + png_byte bit_depth; /* bit depth of file */ + png_byte usr_bit_depth; /* bit depth of users row */ + png_byte pixel_depth; /* number of bits per pixel */ + png_byte channels; /* number of channels in file */ + png_byte usr_channels; /* channels at start of write */ + png_byte sig_bytes; /* magic bytes read/written from start of file */ + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +#ifdef PNG_LEGACY_SUPPORTED + png_byte filler; /* filler byte for pixel expansion */ +#else + png_uint_16 filler; /* filler bytes for pixel expansion */ +#endif +#endif + +#if defined(PNG_bKGD_SUPPORTED) + png_byte background_gamma_type; +# ifdef PNG_FLOATING_POINT_SUPPORTED + float background_gamma; +# endif + png_color_16 background; /* background color in screen gamma space */ +#if defined(PNG_READ_GAMMA_SUPPORTED) + png_color_16 background_1; /* background normalized to gamma 1.0 */ +#endif +#endif /* PNG_bKGD_SUPPORTED */ + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) + png_flush_ptr output_flush_fn;/* Function for flushing output */ + png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ + png_uint_32 flush_rows; /* number of rows written since last flush */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + int gamma_shift; /* number of "insignificant" bits 16-bit gamma */ +#ifdef PNG_FLOATING_POINT_SUPPORTED + float gamma; /* file gamma value */ + float screen_gamma; /* screen gamma value (display_exponent) */ +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep gamma_table; /* gamma table for 8-bit depth files */ + png_bytep gamma_from_1; /* converts from 1.0 to screen */ + png_bytep gamma_to_1; /* converts from file to 1.0 */ + png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ + png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ + png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) + png_color_8 sig_bit; /* significant bits in each available channel */ +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) + png_color_8 shift; /* shift for significant bit tranformation */ +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ + || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_bytep trans; /* transparency values for paletted files */ + png_color_16 trans_values; /* transparency values for non-paletted files */ +#endif + + png_read_status_ptr read_row_fn; /* called after each row is decoded */ + png_write_status_ptr write_row_fn; /* called after each row is encoded */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + png_progressive_info_ptr info_fn; /* called after header data fully read */ + png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */ + png_progressive_end_ptr end_fn; /* called after image is complete */ + png_bytep save_buffer_ptr; /* current location in save_buffer */ + png_bytep save_buffer; /* buffer for previously read data */ + png_bytep current_buffer_ptr; /* current location in current_buffer */ + png_bytep current_buffer; /* buffer for recently used data */ + png_uint_32 push_length; /* size of current input chunk */ + png_uint_32 skip_length; /* bytes to skip in input data */ + png_size_t save_buffer_size; /* amount of data now in save_buffer */ + png_size_t save_buffer_max; /* total size of save_buffer */ + png_size_t buffer_size; /* total amount of available input data */ + png_size_t current_buffer_size; /* amount of data now in current_buffer */ + int process_mode; /* what push library is currently doing */ + int cur_palette; /* current push library palette index */ + +# if defined(PNG_TEXT_SUPPORTED) + png_size_t current_text_size; /* current size of text input data */ + png_size_t current_text_left; /* how much text left to read in input */ + png_charp current_text; /* current text chunk buffer */ + png_charp current_text_ptr; /* current location in current_text */ +# endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) +/* for the Borland special 64K segment handler */ + png_bytepp offset_table_ptr; + png_bytep offset_table; + png_uint_16 offset_table_number; + png_uint_16 offset_table_count; + png_uint_16 offset_table_count_free; +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) + png_bytep palette_lookup; /* lookup table for dithering */ + png_bytep dither_index; /* index translation for palette files */ +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED) + png_uint_16p hist; /* histogram */ +#endif + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) + png_byte heuristic_method; /* heuristic for row filter selection */ + png_byte num_prev_filters; /* number of weights for previous rows */ + png_bytep prev_filters; /* filter type(s) of previous row(s) */ + png_uint_16p filter_weights; /* weight(s) for previous line(s) */ + png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ + png_uint_16p filter_costs; /* relative filter calculation cost */ + png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) + png_charp time_buffer; /* String to hold RFC 1123 time text */ +#endif + +/* New members added in libpng-1.0.6 */ + +#ifdef PNG_FREE_ME_SUPPORTED + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ +#endif + +#if defined(PNG_USER_CHUNKS_SUPPORTED) + png_voidp user_chunk_ptr; + png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ +#endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + int num_chunk_list; + png_bytep chunk_list; +#endif + +/* New members added in libpng-1.0.3 */ +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + png_byte rgb_to_gray_status; + /* These were changed from png_byte in libpng-1.0.6 */ + png_uint_16 rgb_to_gray_red_coeff; + png_uint_16 rgb_to_gray_green_coeff; + png_uint_16 rgb_to_gray_blue_coeff; +#endif + +/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ + defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* changed from png_byte to png_uint_32 at version 1.2.0 */ +#ifdef PNG_1_0_X + png_byte mng_features_permitted; +#else + png_uint_32 mng_features_permitted; +#endif /* PNG_1_0_X */ +#endif + +/* New member added in libpng-1.0.7 */ +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) + png_fixed_point int_gamma; +#endif + +/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ +#if defined(PNG_MNG_FEATURES_SUPPORTED) + png_byte filter_type; +#endif + +#if defined(PNG_1_0_X) +/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */ + png_uint_32 row_buf_size; +#endif + +/* New members added in libpng-1.2.0 */ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +# if !defined(PNG_1_0_X) +# if defined(PNG_MMX_CODE_SUPPORTED) + png_byte mmx_bitdepth_threshold; + png_uint_32 mmx_rowbytes_threshold; +# endif + png_uint_32 asm_flags; +# endif +#endif + +/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ +#ifdef PNG_USER_MEM_SUPPORTED + png_voidp mem_ptr; /* user supplied struct for mem functions */ + png_malloc_ptr malloc_fn; /* function for allocating memory */ + png_free_ptr free_fn; /* function for freeing memory */ +#endif + +/* New member added in libpng-1.0.13 and 1.2.0 */ + png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep dither_sort; /* working sort array */ + png_bytep index_to_palette; /* where the original index currently is */ + /* in the palette */ + png_bytep palette_to_index; /* which original index points to this */ + /* palette color */ +#endif + +/* New members added in libpng-1.0.16 and 1.2.6 */ + png_byte compression_type; + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_uint_32 user_width_max; + png_uint_32 user_height_max; +#endif + +/* New member added in libpng-1.0.25 and 1.2.17 */ +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + /* storage for unknown chunk that the library doesn't recognize. */ + png_unknown_chunk unknown_chunk; +#endif + +/* New members added in libpng-1.2.26 */ + png_uint_32 old_big_row_buf_size, old_prev_row_size; + +/* New member added in libpng-1.2.30 */ + png_charp chunkdata; /* buffer for reading chunk data */ + +}; + + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef png_structp version_1_2_32; + +typedef png_struct FAR * FAR * png_structpp; + +/* Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng.txt for the + * full explanation, see example.c for the summary. This just provides + * a simple one line description of the use of each function. + */ + +/* Returns the version number of the library */ +extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void)); + +/* Tell lib we have already handled the first <num_bytes> magic bytes. + * Handling more than 8 bytes from the beginning of the file is an error. + */ +extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr, + int num_bytes)); + +/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a + * PNG file. Returns zero if the supplied bytes match the 8-byte PNG + * signature, and non-zero otherwise. Having num_to_check == 0 or + * start > 7 will always fail (ie return non-zero). + */ +extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start, + png_size_t num_to_check)); + +/* Simple signature checking function. This is the same as calling + * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + */ +extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num)); + +/* Allocate and initialize png_ptr struct for reading, and any other memory. */ +extern PNG_EXPORT(png_structp,png_create_read_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +/* Allocate and initialize png_ptr struct for writing, and any other memory */ +extern PNG_EXPORT(png_structp,png_create_write_struct) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn)); + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_WRITE_SUPPORTED +extern PNG_EXPORT(void,png_set_compression_buffer_size) + PNGARG((png_structp png_ptr, png_uint_32 size)); +#endif + +/* Reset the compression stream */ +extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr)); + +/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_structp,png_create_read_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +extern PNG_EXPORT(png_structp,png_create_write_struct_2) + PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +#endif + +/* Write a PNG chunk - size, type, (optional) data, CRC. */ +extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_bytep data, png_size_t length)); + +/* Write the start of a PNG chunk - length and chunk name. */ +extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr, + png_bytep chunk_name, png_uint_32 length)); + +/* Write the data of a PNG chunk started with png_write_chunk_start(). */ +extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ +extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr)); + +/* Allocate and initialize the info structure */ +extern PNG_EXPORT(png_infop,png_create_info_struct) + PNGARG((png_structp png_ptr)); + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize the info structure (old interface - DEPRECATED) */ +extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)); +#undef png_info_init +#define png_info_init(info_ptr) png_info_init_3(&info_ptr,\ + png_sizeof(png_info)); +#endif + +extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, + png_size_t png_info_struct_size)); + +/* Writes all the PNG information before the image. */ +extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the information before the actual image data. */ +extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#if defined(PNG_TIME_RFC1123_SUPPORTED) +extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) + PNGARG((png_structp png_ptr, png_timep ptime)); +#endif + +#if !defined(_WIN32_WCE) +/* "time.h" functions are not supported on WindowsCE */ +#if defined(PNG_WRITE_tIME_SUPPORTED) +/* convert from a struct tm to png_time */ +extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime, + struct tm FAR * ttime)); + +/* convert from time_t to png_time. Uses gmtime() */ +extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, + time_t ttime)); +#endif /* PNG_WRITE_tIME_SUPPORTED */ +#endif /* _WIN32_WCE */ + +#if defined(PNG_READ_EXPAND_SUPPORTED) +/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ +extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); +#if !defined(PNG_1_0_X) +extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp + png_ptr)); +#endif +extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated */ +extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr)); +#endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +/* Use blue, green, red order for pixels. */ +extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +/* Expand the grayscale to 24-bit RGB if necessary. */ +extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +/* Reduce RGB to grayscale. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr, + int error_action, double red, double green )); +#endif +extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green )); +extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp + png_ptr)); +#endif + +extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth, + png_colorp palette)); + +#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ + defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) +/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ +extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +/* The values of the PNG_FILLER_ defines should NOT be changed */ +#define PNG_FILLER_BEFORE 0 +#define PNG_FILLER_AFTER 1 +/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ +#if !defined(PNG_1_0_X) +extern PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr, + png_uint_32 filler, int flags)); +#endif +#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +/* Swap bytes in 16-bit depth files. */ +extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ +extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +/* Swap packing order of pixels in bytes. */ +extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) +/* Converts files to legal bit depths. */ +extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr, + png_color_8p true_bits)); +#endif + +#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ + defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* Have the code handle the interlacing. Returns the number of passes. */ +extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +/* Invert monochrome files */ +extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +/* Handle alpha and tRNS by replacing with a background color. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, + png_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)); +#endif +#define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +#define PNG_BACKGROUND_GAMMA_SCREEN 1 +#define PNG_BACKGROUND_GAMMA_FILE 2 +#define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +/* strip the second byte of information from a 16-bit depth file. */ +extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +/* Turn on dithering, and reduce the palette to the number of colors available. */ +extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette, int maximum_colors, + png_uint_16p histogram, int full_dither)); +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +/* Handle gamma correction. Screen_gamma=(display_exponent) */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, + double screen_gamma, double default_file_gamma)); +#endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ + defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */ +/* Deprecated and will be removed. Use png_permit_mng_features() instead. */ +extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr, + int empty_plte_permitted)); +#endif +#endif + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +/* Set how many lines between output flushes - 0 for no flushing */ +extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); +/* Flush the current PNG output buffer */ +extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); +#endif + +/* optional update palette with requested transformations */ +extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); + +/* optional call to update the users info structure */ +extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read one or more rows of image data. */ +extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read a row of data. */ +extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, + png_bytep row, + png_bytep display_row)); +#endif + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the whole image into memory at once. */ +extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, + png_bytepp image)); +#endif + +/* write a row of image data */ +extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, + png_bytep row)); + +/* write a few rows of image data */ +extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr, + png_bytepp row, png_uint_32 num_rows)); + +/* write the image data */ +extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, + png_bytepp image)); + +/* writes the end of the PNG file. */ +extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +/* read the end of the PNG file. */ +extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +/* free any memory associated with the png_info_struct */ +extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, + png_infopp info_ptr_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp + png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); + +/* free all memory used by the read (old method - NOT DLL EXPORTED) */ +extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, + png_infop end_info_ptr)); + +/* free any memory associated with the png_struct and the png_info_structs */ +extern PNG_EXPORT(void,png_destroy_write_struct) + PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); + +/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +extern void png_write_destroy PNGARG((png_structp png_ptr)); + +/* set the libpng method of handling chunk CRC errors */ +extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, + int crit_action, int ancil_action)); + +/* Values for png_set_crc_action() to say how to handle CRC errors in + * ancillary and critical chunks, and whether to use the data contained + * therein. Note that it is impossible to "discard" data in a critical + * chunk. For versions prior to 0.90, the action was always error/quit, + * whereas in version 0.90 and later, the action for CRC errors in ancillary + * chunks is warn/discard. These values should NOT be changed. + * + * value action:critical action:ancillary + */ +#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ +#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ +#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ +#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ +#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ +#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ + +/* These functions give the user control over the scan-line filtering in + * libpng and the compression methods used by zlib. These functions are + * mainly useful for testing, as the defaults should work with most users. + * Those users who are tight on memory or want faster performance at the + * expense of compression can modify them. See the compression library + * header file (zlib.h) for an explination of the compression functions. + */ + +/* set the filtering method(s) used by libpng. Currently, the only valid + * value for "method" is 0. + */ +extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, + int filters)); + +/* Flags for png_set_filter() to say which filters to use. The flags + * are chosen so that they don't conflict with real filter types + * below, in case they are supplied instead of the #defined constants. + * These values should NOT be changed. + */ +#define PNG_NO_FILTERS 0x00 +#define PNG_FILTER_NONE 0x08 +#define PNG_FILTER_SUB 0x10 +#define PNG_FILTER_UP 0x20 +#define PNG_FILTER_AVG 0x40 +#define PNG_FILTER_PAETH 0x80 +#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \ + PNG_FILTER_AVG | PNG_FILTER_PAETH) + +/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. + * These defines should NOT be changed. + */ +#define PNG_FILTER_VALUE_NONE 0 +#define PNG_FILTER_VALUE_SUB 1 +#define PNG_FILTER_VALUE_UP 2 +#define PNG_FILTER_VALUE_AVG 3 +#define PNG_FILTER_VALUE_PAETH 4 +#define PNG_FILTER_VALUE_LAST 5 + +#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */ +/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_ + * defines, either the default (minimum-sum-of-absolute-differences), or + * the experimental method (weighted-minimum-sum-of-absolute-differences). + * + * Weights are factors >= 1.0, indicating how important it is to keep the + * filter type consistent between rows. Larger numbers mean the current + * filter is that many times as likely to be the same as the "num_weights" + * previous filters. This is cumulative for each previous row with a weight. + * There needs to be "num_weights" values in "filter_weights", or it can be + * NULL if the weights aren't being specified. Weights have no influence on + * the selection of the first row filter. Well chosen weights can (in theory) + * improve the compression for a given image. + * + * Costs are factors >= 1.0 indicating the relative decoding costs of a + * filter type. Higher costs indicate more decoding expense, and are + * therefore less likely to be selected over a filter with lower computational + * costs. There needs to be a value in "filter_costs" for each valid filter + * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't + * setting the costs. Costs try to improve the speed of decompression without + * unduly increasing the compressed image size. + * + * A negative weight or cost indicates the default value is to be used, and + * values in the range [0.0, 1.0) indicate the value is to remain unchanged. + * The default values for both weights and costs are currently 1.0, but may + * change if good general weighting/cost heuristics can be found. If both + * the weights and costs are set to 1.0, this degenerates the WEIGHTED method + * to the UNWEIGHTED method, but with added encoding time/computation. + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr, + int heuristic_method, int num_weights, png_doublep filter_weights, + png_doublep filter_costs)); +#endif +#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ + +/* Heuristic used for row filter selection. These defines should NOT be + * changed. + */ +#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ +#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ +#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ +#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ + +/* Set the library compression level. Currently, valid values range from + * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 + * (0 - no compression, 9 - "maximal" compression). Note that tests have + * shown that zlib compression levels 3-6 usually perform as well as level 9 + * for PNG images, and do considerably fewer caclulations. In the future, + * these values may not correspond directly to the zlib compression levels. + */ +extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr, + int level)); + +extern PNG_EXPORT(void,png_set_compression_mem_level) + PNGARG((png_structp png_ptr, int mem_level)); + +extern PNG_EXPORT(void,png_set_compression_strategy) + PNGARG((png_structp png_ptr, int strategy)); + +extern PNG_EXPORT(void,png_set_compression_window_bits) + PNGARG((png_structp png_ptr, int window_bits)); + +extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr, + int method)); + +/* These next functions are called for input/output, memory, and error + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * and call standard C I/O routines such as fread(), fwrite(), and + * fprintf(). These functions can be made to use other I/O routines + * at run time for those applications that need to handle I/O in a + * different manner by calling png_set_???_fn(). See libpng.txt for + * more information. + */ + +#if !defined(PNG_NO_STDIO) +/* Initialize the input/output for the PNG file to the default functions. */ +extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)); +#endif + +/* Replace the (error and abort), and warning functions with user + * supplied functions. If no messages are to be printed you must still + * write and use replacement functions. The replacement error_fn should + * still do a longjmp to the last setjmp location if you are using this + * method of error handling. If error_fn or warning_fn is NULL, the + * default function will be used. + */ + +extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr, + png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); + +/* Return the user pointer associated with the error functions */ +extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); + +/* Replace the default data output functions with a user supplied one(s). + * If buffered output is not used, then output_flush_fn can be set to NULL. + * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time + * output_flush_fn will be ignored (and thus can be NULL). + */ +extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); + +/* Replace the default data input function with a user supplied one. */ +extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr, + png_voidp io_ptr, png_rw_ptr read_data_fn)); + +/* Return the user pointer associated with the I/O functions */ +extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr)); + +extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr, + png_read_status_ptr read_row_fn)); + +extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr, + png_write_status_ptr write_row_fn)); + +#ifdef PNG_USER_MEM_SUPPORTED +/* Replace the default memory allocation functions with user supplied one(s). */ +extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); +/* Return the user pointer associated with the memory functions */ +extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr read_user_transform_fn)); +#endif + +#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp + png_ptr, png_user_transform_ptr write_user_transform_fn)); +#endif + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_LEGACY_SUPPORTED) +extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp + png_ptr, png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); +/* Return the user pointer associated with the user transform functions */ +extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr) + PNGARG((png_structp png_ptr)); +#endif + +#ifdef PNG_USER_CHUNKS_SUPPORTED +extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp + png_ptr)); +#endif + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* Sets the function callbacks for the push reader, and a pointer to a + * user-defined structure available to the callback functions. + */ +extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr, + png_voidp progressive_ptr, + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn)); + +/* returns the user pointer associated with the push read functions */ +extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) + PNGARG((png_structp png_ptr)); + +/* function to be called when data becomes available */ +extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)); + +/* function that combines rows. Not very much different than the + * png_combine_row() call. Is this even used????? + */ +extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr, + png_bytep old_row, png_bytep new_row)); +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr, + png_uint_32 size)); + +#if defined(PNG_1_0_X) +# define png_malloc_warn png_malloc +#else +/* Added at libpng version 1.2.4 */ +extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, + png_uint_32 size)); +#endif + +/* frees a pointer allocated by png_malloc() */ +extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); + +#if defined(PNG_1_0_X) +/* Function to allocate memory for zlib. */ +extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items, + uInt size)); + +/* Function to free memory for zlib */ +extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr)); +#endif + +/* Free data that was allocated internally */ +extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 free_me, int num)); +#ifdef PNG_FREE_ME_SUPPORTED +/* Reassign responsibility for freeing existing data, whether allocated + * by libpng or by the application */ +extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, + png_infop info_ptr, int freer, png_uint_32 mask)); +#endif +/* assignments for png_data_freer */ +#define PNG_DESTROY_WILL_FREE_DATA 1 +#define PNG_SET_WILL_FREE_DATA 1 +#define PNG_USER_WILL_FREE_DATA 2 +/* Flags for png_ptr->free_me and info_ptr->free_me */ +#define PNG_FREE_HIST 0x0008 +#define PNG_FREE_ICCP 0x0010 +#define PNG_FREE_SPLT 0x0020 +#define PNG_FREE_ROWS 0x0040 +#define PNG_FREE_PCAL 0x0080 +#define PNG_FREE_SCAL 0x0100 +#define PNG_FREE_UNKN 0x0200 +#define PNG_FREE_LIST 0x0400 +#define PNG_FREE_PLTE 0x1000 +#define PNG_FREE_TRNS 0x2000 +#define PNG_FREE_TEXT 0x4000 +#define PNG_FREE_ALL 0x7fff +#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ + +#ifdef PNG_USER_MEM_SUPPORTED +extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr, + png_uint_32 size)); +extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr, + png_voidp ptr)); +#endif + +extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr, + png_voidp s1, png_voidp s2, png_uint_32 size)); + +extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr, + png_voidp s1, int value, png_uint_32 size)); + +#if defined(USE_FAR_KEYWORD) /* memory model conversion function */ +extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, + int check)); +#endif /* USE_FAR_KEYWORD */ + +#ifndef PNG_NO_ERROR_TEXT +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); + +/* The same, but the chunk name is prepended to the error string. */ +extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, + png_const_charp error_message)); +#else +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr)); +#endif + +#ifndef PNG_NO_WARNINGS +/* Non-fatal error in libpng. Can continue, but may have a problem. */ +extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); + +#ifdef PNG_READ_SUPPORTED +/* Non-fatal error in libpng, chunk name is prepended to message. */ +extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, + png_const_charp warning_message)); +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_NO_WARNINGS */ + +/* The png_set_<chunk> functions are for storing values in the png_info_struct. + * Similarly, the png_get_<chunk> calls are used to read values from the + * png_info_struct, either storing the parameters in the passed variables, or + * setting pointers into the png_info_struct where the data is stored. The + * png_get_<chunk> functions return a non-zero value if the data was available + * in info_ptr, or return zero and do not change any of the parameters if the + * data was not available. + * + * These functions should be used instead of directly accessing png_info + * to avoid problems with future changes in the size and internal layout of + * png_info_struct. + */ +/* Returns "flag" if chunk data is valid in info_ptr. */ +extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 flag)); + +/* Returns number of bytes needed to hold a transformed row. */ +extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* Returns row_pointers, which is an array of pointers to scanlines that was +returned from png_read_png(). */ +extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr, +png_infop info_ptr)); +/* Set row_pointers, which is an array of pointers to scanlines for use +by png_write_png(). */ +extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytepp row_pointers)); +#endif + +/* Returns number of color channels in image. */ +extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#ifdef PNG_EASY_ACCESS_SUPPORTED +/* Returns image width in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image height in pixels. */ +extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image bit_depth. */ +extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image color_type. */ +extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image filter_type. */ +extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image interlace_type. */ +extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image compression_type. */ +extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns image resolution in pixels per meter, from pHYs chunk data. */ +extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +/* Returns pixel aspect ratio, computed from pHYs chunk data. */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +#endif + +/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ +extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); +extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp +png_ptr, png_infop info_ptr)); + +#endif /* PNG_EASY_ACCESS_SUPPORTED */ + +/* Returns pointer to signature string read from PNG header */ +extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p *background)); +#endif + +#if defined(PNG_bKGD_SUPPORTED) +extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_16p background)); +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *white_x, double *white_y, double *red_x, + double *red_y, double *green_x, double *green_y, double *blue_x, + double *blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point + *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y, + png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point + *int_blue_x, png_fixed_point *int_blue_y)); +#endif +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, double white_x, double white_y, double red_x, + double red_y, double green_x, double green_y, double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double *file_gamma)); +#endif +extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_file_gamma)); +#endif + +#if defined(PNG_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr, + png_infop info_ptr, double file_gamma)); +#endif +extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_file_gamma)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p *hist)); +#endif + +#if defined(PNG_hIST_SUPPORTED) +extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_16p hist)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, + int *bit_depth, int *color_type, int *interlace_method, + int *compression_method, int *filter_method)); + +extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_method, int compression_method, + int filter_method)); + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, + int *unit_type)); +#endif + +#if defined(PNG_oFFs_SUPPORTED) +extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, + int unit_type)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, + int *type, int *nparams, png_charp *units, png_charpp *params)); +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, + int type, int nparams, png_charp units, png_charpp params)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif + +#if defined(PNG_pHYs_SUPPORTED) +extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); +#endif + +extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp *palette, int *num_palette)); + +extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_colorp palette, int num_palette)); + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p *sig_bit)); +#endif + +#if defined(PNG_sBIT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_color_8p sig_bit)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *intent)); +#endif + +#if defined(PNG_sRGB_SUPPORTED) +extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr, + png_infop info_ptr, int intent)); +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charpp name, int *compression_type, + png_charpp profile, png_uint_32 *proflen)); + /* Note to maintainer: profile should be png_bytepp */ +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp name, int compression_type, + png_charp profile, png_uint_32 proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tpp entries)); +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_sPLT_tp entries, int nentries)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) +/* png_get_text also returns the number of text chunks in *num_text */ +extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp *text_ptr, int *num_text)); +#endif + +/* + * Note while png_set_text() will accept a structure whose text, + * language, and translated keywords are NULL pointers, the structure + * returned by png_get_text will always contain regular + * zero-terminated C strings. They might be empty strings but + * they will never be NULL pointers. + */ + +#if defined(PNG_TEXT_SUPPORTED) +extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep *mod_time)); +#endif + +#if defined(PNG_tIME_SUPPORTED) +extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_timep mod_time)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep *trans, int *num_trans, + png_color_16p *trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_bytep trans, int num_trans, + png_color_16p trans_values)); +#endif + +#if defined(PNG_tRNS_SUPPORTED) +#endif + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, double *width, double *height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED */ + +#if defined(PNG_sCAL_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr, + png_infop info_ptr, int unit, png_charp swidth, png_charp sheight)); +#endif +#endif +#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +/* provide a list of chunks and how they are to be handled, if the built-in + handling or default unknown chunk handling is not desired. Any chunks not + listed will be handled in the default manner. The IHDR and IEND chunks + must not be listed. + keep = 0: follow default behaviour + = 1: do not keep + = 2: keep only if safe-to-copy + = 3: keep even if unsafe-to-copy +*/ +extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp + png_ptr, int keep, png_bytep chunk_list, int num_chunks)); +extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)); +extern PNG_EXPORT(void, png_set_unknown_chunk_location) + PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location)); +extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp + png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); +#endif +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep + chunk_name)); +#endif + +/* Png_free_data() will turn off the "valid" flag for anything it frees. + If you need to turn it off for a chunk that your application has freed, + you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */ +extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr, + png_infop info_ptr, int mask)); + +#if defined(PNG_INFO_IMAGE_SUPPORTED) +/* The "params" pointer is currently not used and is for future expansion. */ +extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, + png_infop info_ptr, + int transforms, + png_voidp params)); +#endif + +/* Define PNG_DEBUG at compile time for debugging information. Higher + * numbers for PNG_DEBUG mean more debugging information. This has + * only been added since version 0.95 so it is not implemented throughout + * libpng yet, but more support will be added as needed. + */ +#ifdef PNG_DEBUG +#if (PNG_DEBUG > 0) +#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) +#include <crtdbg.h> +#if (PNG_DEBUG > 1) +#define png_debug(l,m) _RPT0(_CRT_WARN,m) +#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1) +#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2) +#endif +#else /* PNG_DEBUG_FILE || !_MSC_VER */ +#ifndef PNG_DEBUG_FILE +#define PNG_DEBUG_FILE stderr +#endif /* PNG_DEBUG_FILE */ +#if (PNG_DEBUG > 1) +#define png_debug(l,m) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ +} +#define png_debug1(l,m,p1) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ +} +#define png_debug2(l,m,p1,p2) \ +{ \ + int num_tabs=l; \ + fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ + (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ +} +#endif /* (PNG_DEBUG > 1) */ +#endif /* _MSC_VER */ +#endif /* (PNG_DEBUG > 0) */ +#endif /* PNG_DEBUG */ +#ifndef png_debug +#define png_debug(l, m) +#endif +#ifndef png_debug1 +#define png_debug1(l, m, p1) +#endif +#ifndef png_debug2 +#define png_debug2(l, m, p1, p2) +#endif + +extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr)); + +#ifdef PNG_MNG_FEATURES_SUPPORTED +extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp + png_ptr, png_uint_32 mng_features_permitted)); +#endif + +/* For use in png_set_keep_unknown, added to version 1.2.6 */ +#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 +#define PNG_HANDLE_CHUNK_NEVER 1 +#define PNG_HANDLE_CHUNK_IF_SAFE 2 +#define PNG_HANDLE_CHUNK_ALWAYS 3 + +/* Added to version 1.2.0 */ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if defined(PNG_MMX_CODE_SUPPORTED) +#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 +#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08 +#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10 +#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20 +#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40 +#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80 +#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ + +#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ + | PNG_ASM_FLAG_MMX_READ_INTERLACE \ + | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \ + | PNG_ASM_FLAG_MMX_READ_FILTER_UP \ + | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \ + | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ) +#define PNG_MMX_WRITE_FLAGS ( 0 ) + +#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \ + | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \ + | PNG_MMX_READ_FLAGS \ + | PNG_MMX_WRITE_FLAGS ) + +#define PNG_SELECT_READ 1 +#define PNG_SELECT_WRITE 2 +#endif /* PNG_MMX_CODE_SUPPORTED */ + +#if !defined(PNG_1_0_X) +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) + PNGARG((int flag_select, int *compilerID)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask) + PNGARG((int flag_select)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flags) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold) + PNGARG((png_structp png_ptr)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_asm_flags) + PNGARG((png_structp png_ptr, png_uint_32 asm_flags)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_mmx_thresholds) + PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold, + png_uint_32 mmx_rowbytes_threshold)); + +#endif /* PNG_1_0_X */ + +#if !defined(PNG_1_0_X) +/* png.c, pnggccrd.c, or pngvcrd.c */ +extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + +/* Strip the prepended error numbers ("#nnn ") from error and warning + * messages before passing them to the error or warning handler. */ +#ifdef PNG_ERROR_NUMBERS_SUPPORTED +extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp + png_ptr, png_uint_32 strip_mode)); +#endif + +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.2.6 */ +#ifdef PNG_SET_USER_LIMITS_SUPPORTED +extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp + png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max)); +extern PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp + png_ptr)); +extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp + png_ptr)); +#endif + + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ + +#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED +/* With these routines we avoid an integer divide, which will be slower on + * most machines. However, it does take more operations than the corresponding + * divide method, so it may be slower on a few RISC systems. There are two + * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. + * + * Note that the rounding factors are NOT supposed to be the same! 128 and + * 32768 are correct for the NODIV code; 127 and 32767 are correct for the + * standard method. + * + * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] + */ + + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + +# define png_composite(composite, fg, alpha, bg) \ + { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \ + + (png_uint_16)(bg)*(png_uint_16)(255 - \ + (png_uint_16)(alpha)) + (png_uint_16)128); \ + (composite) = (png_byte)((temp + (temp >> 8)) >> 8); } + +# define png_composite_16(composite, fg, alpha, bg) \ + { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \ + + (png_uint_32)(bg)*(png_uint_32)(65535L - \ + (png_uint_32)(alpha)) + (png_uint_32)32768L); \ + (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } + +#else /* standard method using integer division */ + +# define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + (png_uint_16)127) / 255) + +# define png_composite_16(composite, fg, alpha, bg) \ + (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ + (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ + (png_uint_32)32767) / (png_uint_32)65535L) + +#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ + +/* Inline macros to do direct reads of bytes from the input buffer. These + * require that you are using an architecture that uses PNG byte ordering + * (MSB first) and supports unaligned data storage. I think that PowerPC + * in big-endian mode and 680x0 are the only ones that will support this. + * The x86 line of processors definitely do not. The png_get_int_32() + * routine also assumes we are using two's complement format for negative + * values, which is almost certainly true. + */ +#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED) +# define png_get_uint_32(buf) ( *((png_uint_32p) (buf))) +# define png_get_uint_16(buf) ( *((png_uint_16p) (buf))) +# define png_get_int_32(buf) ( *((png_int_32p) (buf))) +#else +extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf)); +#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ +extern PNG_EXPORT(png_uint_32,png_get_uint_31) + PNGARG((png_structp png_ptr, png_bytep buf)); +/* No png_get_int_16 -- may be added if there's a real need for it. */ + +/* Place a 32-bit number into a buffer in PNG byte order (big-endian). + */ +extern PNG_EXPORT(void,png_save_uint_32) + PNGARG((png_bytep buf, png_uint_32 i)); +extern PNG_EXPORT(void,png_save_int_32) + PNGARG((png_bytep buf, png_int_32 i)); + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +extern PNG_EXPORT(void,png_save_uint_16) + PNGARG((png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ + +/* ************************************************************************* */ + +/* These next functions are used internally in the code. They generally + * shouldn't be used unless you are writing code to add or replace some + * functionality in libpng. More information about most functions can + * be found in the files where the functions are located. + */ + + +/* Various modes of operation, that are visible to applications because + * they are used for unknown chunk location. + */ +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_HAVE_IDAT 0x04 +#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */ +#define PNG_HAVE_IEND 0x10 + +#if defined(PNG_INTERNAL) + +/* More modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. + */ +#define PNG_HAVE_gAMA 0x20 +#define PNG_HAVE_cHRM 0x40 +#define PNG_HAVE_sRGB 0x80 +#define PNG_HAVE_CHUNK_HEADER 0x100 +#define PNG_WROTE_tIME 0x200 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 +#define PNG_BACKGROUND_IS_GRAY 0x800 +#define PNG_HAVE_PNG_SIGNATURE 0x1000 +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ + +/* flags for the transformations the PNG library does on the image data */ +#define PNG_BGR 0x0001 +#define PNG_INTERLACE 0x0002 +#define PNG_PACK 0x0004 +#define PNG_SHIFT 0x0008 +#define PNG_SWAP_BYTES 0x0010 +#define PNG_INVERT_MONO 0x0020 +#define PNG_DITHER 0x0040 +#define PNG_BACKGROUND 0x0080 +#define PNG_BACKGROUND_EXPAND 0x0100 + /* 0x0200 unused */ +#define PNG_16_TO_8 0x0400 +#define PNG_RGBA 0x0800 +#define PNG_EXPAND 0x1000 +#define PNG_GAMMA 0x2000 +#define PNG_GRAY_TO_RGB 0x4000 +#define PNG_FILLER 0x8000L +#define PNG_PACKSWAP 0x10000L +#define PNG_SWAP_ALPHA 0x20000L +#define PNG_STRIP_ALPHA 0x40000L +#define PNG_INVERT_ALPHA 0x80000L +#define PNG_USER_TRANSFORM 0x100000L +#define PNG_RGB_TO_GRAY_ERR 0x200000L +#define PNG_RGB_TO_GRAY_WARN 0x400000L +#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ + /* 0x800000L Unused */ +#define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +/* flags for png_create_struct */ +#define PNG_STRUCT_PNG 0x0001 +#define PNG_STRUCT_INFO 0x0002 + +/* Scaling factor for filter heuristic weighting calculations */ +#define PNG_WEIGHT_SHIFT 8 +#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) +#define PNG_COST_SHIFT 3 +#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) + +/* flags for the png_ptr->flags rather than declaring a byte for each one */ +#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 +#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 +#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 +#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008 +#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010 +#define PNG_FLAG_ZLIB_FINISHED 0x0020 +#define PNG_FLAG_ROW_INIT 0x0040 +#define PNG_FLAG_FILLER_AFTER 0x0080 +#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100 +#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200 +#define PNG_FLAG_CRC_CRITICAL_USE 0x0400 +#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800 +#define PNG_FLAG_FREE_PLTE 0x1000 +#define PNG_FLAG_FREE_TRNS 0x2000 +#define PNG_FLAG_FREE_HIST 0x4000 +#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L +#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L +#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L +#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L +#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L +#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L +#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */ +#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */ + /* 0x800000L unused */ + /* 0x1000000L unused */ + /* 0x2000000L unused */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ + +#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ + PNG_FLAG_CRC_ANCILLARY_NOWARN) + +#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ + PNG_FLAG_CRC_CRITICAL_IGNORE) + +#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ + PNG_FLAG_CRC_CRITICAL_MASK) + +/* save typing and make code easier to understand */ + +#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ + abs((int)((c1).green) - (int)((c2).green)) + \ + abs((int)((c1).blue) - (int)((c2).blue))) + +/* Added to libpng-1.2.6 JB */ +#define PNG_ROWBYTES(pixel_bits, width) \ + ((pixel_bits) >= 8 ? \ + ((width) * (((png_uint_32)(pixel_bits)) >> 3)) : \ + (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) ) + +/* PNG_OUT_OF_RANGE returns true if value is outside the range + ideal-delta..ideal+delta. Each argument is evaluated twice. + "ideal" and "delta" should be constants, normally simple + integers, "value" a variable. Added to libpng-1.2.6 JB */ +#define PNG_OUT_OF_RANGE(value, ideal, delta) \ + ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) + +/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) +/* place to hold the signature string for a PNG file. */ +#ifdef PNG_USE_GLOBAL_ARRAYS + PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8]; +#else +#endif +#endif /* PNG_NO_EXTERN */ + +/* Constant strings for known chunk types. If you need to add a chunk, + * define the name here, and add an invocation of the macro in png.c and + * wherever it's needed. + */ +#define PNG_IHDR png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} +#define PNG_IDAT png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} +#define PNG_IEND png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} +#define PNG_PLTE png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} +#define PNG_bKGD png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} +#define PNG_cHRM png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} +#define PNG_gAMA png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} +#define PNG_hIST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} +#define PNG_iCCP png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} +#define PNG_iTXt png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} +#define PNG_oFFs png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} +#define PNG_pCAL png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} +#define PNG_sCAL png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} +#define PNG_pHYs png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} +#define PNG_sBIT png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} +#define PNG_sPLT png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} +#define PNG_sRGB png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} +#define PNG_tEXt png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} +#define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} +#define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} +#define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} + +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5]; +#endif /* PNG_USE_GLOBAL_ARRAYS */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for reading, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_read_struct instead). + */ +extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)); +#undef png_read_init +#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Initialize png_ptr struct for writing, and allocate any other memory. + * (old interface - DEPRECATED - use png_create_write_struct instead). + */ +extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)); +#undef png_write_init +#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ + PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + +extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size)); +extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr, + png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t + png_info_size)); + +/* Allocate memory for an internal libpng struct */ +PNG_EXTERN png_voidp png_create_struct PNGARG((int type)); + +/* Free memory from internal libpng struct */ +PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); + +PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr + malloc_fn, png_voidp mem_ptr)); +PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, + png_free_ptr free_fn, png_voidp mem_ptr)); + +/* Free any memory that info_ptr points to and reset struct. */ +PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +#ifndef PNG_1_0_X +/* Function to allocate memory for zlib. */ +PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); + +/* Function to free memory for zlib */ +PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); + +#ifdef PNG_SIZE_T +/* Function to convert a sizeof an item to png_sizeof item */ + PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); +#endif + +/* Next four functions are used internally as callbacks. PNGAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ + +PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif + +PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +#if !defined(PNG_NO_STDIO) +PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr)); +#endif +#endif +#else /* PNG_1_0_X */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif +#endif /* PNG_1_0_X */ + +/* Reset the CRC variable */ +PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); + +/* Write the "data" buffer to whatever output you are using. */ +PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read data from whatever input you are using into the "data" buffer */ +PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +/* Read bytes into buf, and update png_ptr->crc */ +PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, + png_size_t length)); + +/* Decompress data in a chunk that uses compression */ +#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \ + defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) +PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr, + int comp_type, png_size_t chunklength, + png_size_t prefix_length, png_size_t *data_length)); +#endif + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); + +/* Read the CRC from the file and compare it to the libpng calculated CRC */ +PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); + +/* Calculate the CRC over a section of data. Note that we are only + * passing a maximum of 64K on systems that have this as a memory limit, + * since this is the maximum buffer size we can specify. + */ +PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, + png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); +#endif + +/* simple function to write the signature */ +PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)); + +/* write various chunks */ + +/* Write the IHDR chunk, and update the png_struct with the necessary + * information. + */ +PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, + png_uint_32 height, + int bit_depth, int color_type, int compression_method, int filter_method, + int interlace_method)); + +PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette, + png_uint_32 num_pal)); + +PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, + png_size_t length)); + +PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); + +#if defined(PNG_WRITE_gAMA_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point + file_gamma)); +#endif +#endif + +#if defined(PNG_WRITE_sBIT_SUPPORTED) +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit, + int color_type)); +#endif + +#if defined(PNG_WRITE_cHRM_SUPPORTED) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr, + double white_x, double white_y, + double red_x, double red_y, double green_x, double green_y, + double blue_x, double blue_y)); +#endif +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); +#endif +#endif + +#if defined(PNG_WRITE_sRGB_SUPPORTED) +PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, + int intent)); +#endif + +#if defined(PNG_WRITE_iCCP_SUPPORTED) +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, + png_charp name, int compression_type, + png_charp profile, int proflen)); + /* Note to maintainer: profile should be png_bytep */ +#endif + +#if defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, + png_sPLT_tp palette)); +#endif + +#if defined(PNG_WRITE_tRNS_SUPPORTED) +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans, + png_color_16p values, int number, int color_type)); +#endif + +#if defined(PNG_WRITE_bKGD_SUPPORTED) +PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, + png_color_16p values, int color_type)); +#endif + +#if defined(PNG_WRITE_hIST_SUPPORTED) +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, + int num_hist)); +#endif + +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, + png_charp key, png_charpp new_key)); +#endif + +#if defined(PNG_WRITE_tEXt_SUPPORTED) +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len)); +#endif + +#if defined(PNG_WRITE_zTXt_SUPPORTED) +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, + png_charp text, png_size_t text_len, int compression)); +#endif + +#if defined(PNG_WRITE_iTXt_SUPPORTED) +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, + int compression, png_charp key, png_charp lang, png_charp lang_key, + png_charp text)); +#endif + +#if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */ +PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + +#if defined(PNG_WRITE_oFFs_SUPPORTED) +PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, + png_int_32 x_offset, png_int_32 y_offset, int unit_type)); +#endif + +#if defined(PNG_WRITE_pCAL_SUPPORTED) +PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose, + png_int_32 X0, png_int_32 X1, int type, int nparams, + png_charp units, png_charpp params)); +#endif + +#if defined(PNG_WRITE_pHYs_SUPPORTED) +PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type)); +#endif + +#if defined(PNG_WRITE_tIME_SUPPORTED) +PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, + png_timep mod_time)); +#endif + +#if defined(PNG_WRITE_sCAL_SUPPORTED) +#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) +PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, + int unit, double width, double height)); +#else +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, + int unit, png_charp width, png_charp height)); +#endif +#endif +#endif + +/* Called when finished processing a row of data */ +PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); + +/* Internal use only. Called before first row of data */ +PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)); +#endif + +/* combine a row of data, dealing with alpha, etc. if requested */ +PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, + int mask)); + +#if defined(PNG_READ_INTERLACING_SUPPORTED) +/* expand an interlaced row */ +/* OLD pre-1.0.9 interface: +PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass, png_uint_32 transformations)); + */ +PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); +#endif + +/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ + +#if defined(PNG_WRITE_INTERLACING_SUPPORTED) +/* grab pixels out of a row for an interlaced pass */ +PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, + png_bytep row, int pass)); +#endif + +/* unfilter a row */ +PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, + png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter)); + +/* Choose the best filter to use and filter the row data */ +PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, + png_row_infop row_info)); + +/* Write out the filtered row. */ +PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr, + png_bytep filtered_row)); +/* finish a row while reading, dealing with interlacing passes, etc. */ +PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); + +/* initialize the row buffers, etc. */ +PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); +/* optional call to update the users info structure */ +PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); + +/* these are the functions that do the transformations */ +#if defined(PNG_READ_FILLER_SUPPORTED) +PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 filler, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ + defined(PNG_READ_STRIP_ALPHA_SUPPORTED) +PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 flags)); +#endif + +#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) +PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) +PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) +PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop + row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_READ_PACK_SUPPORTED) +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p sig_bits)); +#endif + +#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) +PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_16_TO_8_SUPPORTED) +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_READ_DITHER_SUPPORTED) +PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info, + png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup)); + +# if defined(PNG_CORRECT_PALETTE_SUPPORTED) +PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, + png_colorp palette, int num_palette)); +# endif +#endif + +#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) +PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row)); +#endif + +#if defined(PNG_WRITE_PACK_SUPPORTED) +PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, + png_bytep row, png_uint_32 bit_depth)); +#endif + +#if defined(PNG_WRITE_SHIFT_SUPPORTED) +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row, + png_color_8p bit_depth)); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background, + png_color_16p background_1, + png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, + png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, + png_uint_16pp gamma_16_to_1, int gamma_shift)); +#else +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, + png_color_16p trans_values, png_color_16p background)); +#endif +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row, + png_bytep gamma_table, png_uint_16pp gamma_16_table, + int gamma_shift)); +#endif + +#if defined(PNG_READ_EXPAND_SUPPORTED) +PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, + png_bytep row, png_colorp palette, png_bytep trans, int num_trans)); +PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, + png_bytep row, png_color_16p trans_value)); +#endif + +/* The following decodes the appropriate chunks, and does error correction, + * then calls the appropriate callback for the chunk if it is valid. + */ + +/* decode the IHDR chunk */ +PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); + +#if defined(PNG_READ_bKGD_SUPPORTED) +PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_cHRM_SUPPORTED) +PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_gAMA_SUPPORTED) +PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_hIST_SUPPORTED) +PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_iCCP_SUPPORTED) +extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_oFFs_SUPPORTED) +PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pCAL_SUPPORTED) +PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_pHYs_SUPPORTED) +PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sBIT_SUPPORTED) +PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_sPLT_SUPPORTED) +extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_sPLT_SUPPORTED */ + +#if defined(PNG_READ_sRGB_SUPPORTED) +PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tIME_SUPPORTED) +PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_tRNS_SUPPORTED) +PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + +PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); + +PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, + png_bytep chunk_name)); + +/* handle the transformations for reading and writing */ +PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); + +PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, + png_uint_32 length)); +PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t buffer_length)); +PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); +PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); +PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, + png_infop info_ptr)); +PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); +#if defined(PNG_READ_tEXt_SUPPORTED) +PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif + +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + +#ifdef PNG_MNG_FEATURES_SUPPORTED +PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, + png_bytep row)); +#endif + +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if defined(PNG_MMX_CODE_SUPPORTED) +/* png.c */ /* PRIVATE */ +PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)); +#endif +#endif + +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_pHYs_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pHYs_dpi PNGARG((png_structp png_ptr, +png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); +#endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ + +/* Read the chunk header (length + type name) */ +PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr)); + +/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#endif /* PNG_INTERNAL */ + +#ifdef __cplusplus +} +#endif + +#endif /* PNG_VERSION_INFO_ONLY */ +/* do not put anything past this line */ +#endif /* PNG_H */ diff --git a/utils/openttd/pngconf.h b/utils/openttd/pngconf.h new file mode 100644 index 00000000000..231777be366 --- /dev/null +++ b/utils/openttd/pngconf.h @@ -0,0 +1,1481 @@ + +/* pngconf.h - machine configurable file for libpng + * + * libpng version 1.2.32 - September 18, 2008 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1998-2008 Glenn Randers-Pehrson + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + */ + +/* Any machine specific code is near the front of this file, so if you + * are configuring libpng for a machine, you may want to read the section + * starting here down to where it starts to typedef png_color, png_text, + * and png_info. + */ + +#ifndef PNGCONF_H +#define PNGCONF_H + +#define PNG_1_2_X + +/* + * PNG_USER_CONFIG has to be defined on the compiler command line. This + * includes the resource compiler for Windows DLL configurations. + */ +#ifdef PNG_USER_CONFIG +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD +# endif +#include "pngusr.h" +#endif + +/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */ +#ifdef PNG_CONFIGURE_LIBPNG +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#endif + +/* + * Added at libpng-1.2.8 + * + * If you create a private DLL you need to define in "pngusr.h" the followings: + * #define PNG_USER_PRIVATEBUILD <Describes by whom and why this version of + * the DLL was built> + * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons." + * #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to + * distinguish your DLL from those of the official release. These + * correspond to the trailing letters that come after the version + * number and must match your private DLL name> + * e.g. // private DLL "libpng13gx.dll" + * #define PNG_USER_DLLFNAME_POSTFIX "gx" + * + * The following macros are also at your disposal if you want to complete the + * DLL VERSIONINFO structure. + * - PNG_USER_VERSIONINFO_COMMENTS + * - PNG_USER_VERSIONINFO_COMPANYNAME + * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS + */ + +#ifdef __STDC__ +#ifdef SPECIALBUILD +# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\ + are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.") +#endif + +#ifdef PRIVATEBUILD +# pragma message("PRIVATEBUILD is deprecated.\ + Use PNG_USER_PRIVATEBUILD instead.") +# define PNG_USER_PRIVATEBUILD PRIVATEBUILD +#endif +#endif /* __STDC__ */ + +#ifndef PNG_VERSION_INFO_ONLY + +/* End of material added to libpng-1.2.8 */ + +/* Added at libpng-1.2.19, removed at libpng-1.2.20 because it caused trouble + Restored at libpng-1.2.21 */ +#if !defined(PNG_NO_WARN_UNINITIALIZED_ROW) && \ + !defined(PNG_WARN_UNINITIALIZED_ROW) +# define PNG_WARN_UNINITIALIZED_ROW 1 +#endif +/* End of material added at libpng-1.2.19/1.2.21 */ + +/* This is the size of the compression buffer, and thus the size of + * an IDAT chunk. Make this whatever size you feel is best for your + * machine. One of these will be allocated per png_struct. When this + * is full, it writes the data to the disk, and does some other + * calculations. Making this an extremely small size will slow + * the library down, but you may want to experiment to determine + * where it becomes significant, if you are concerned with memory + * usage. Note that zlib allocates at least 32Kb also. For readers, + * this describes the size of the buffer available to read the data in. + * Unless this gets smaller than the size of a row (compressed), + * it should not make much difference how big this is. + */ + +#ifndef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 8192 +#endif + +/* Enable if you want a write-only libpng */ + +#ifndef PNG_NO_READ_SUPPORTED +# define PNG_READ_SUPPORTED +#endif + +/* Enable if you want a read-only libpng */ + +#ifndef PNG_NO_WRITE_SUPPORTED +# define PNG_WRITE_SUPPORTED +#endif + +/* Enabled by default in 1.2.0. You can disable this if you don't need to + support PNGs that are embedded in MNG datastreams */ +#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES) +# ifndef PNG_MNG_FEATURES_SUPPORTED +# define PNG_MNG_FEATURES_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_FLOATING_POINT_SUPPORTED +# ifndef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FLOATING_POINT_SUPPORTED +# endif +#endif + +/* If you are running on a machine where you cannot allocate more + * than 64K of memory at once, uncomment this. While libpng will not + * normally need that much memory in a chunk (unless you load up a very + * large file), zlib needs to know how big of a chunk it can use, and + * libpng thus makes sure to check any memory allocation to verify it + * will fit into memory. +#define PNG_MAX_MALLOC_64K + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +/* Special munging to support doing things the 'cygwin' way: + * 'Normal' png-on-win32 defines/defaults: + * PNG_BUILD_DLL -- building dll + * PNG_USE_DLL -- building an application, linking to dll + * (no define) -- building static library, or building an + * application and linking to the static lib + * 'Cygwin' defines/defaults: + * PNG_BUILD_DLL -- (ignored) building the dll + * (no define) -- (ignored) building an application, linking to the dll + * PNG_STATIC -- (ignored) building the static lib, or building an + * application that links to the static lib. + * ALL_STATIC -- (ignored) building various static libs, or building an + * application that links to the static libs. + * Thus, + * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and + * this bit of #ifdefs will define the 'correct' config variables based on + * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but + * unnecessary. + * + * Also, the precedence order is: + * ALL_STATIC (since we can't #undef something outside our namespace) + * PNG_BUILD_DLL + * PNG_STATIC + * (nothing) == PNG_USE_DLL + * + * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent + * of auto-import in binutils, we no longer need to worry about + * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore, + * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes + * to __declspec() stuff. However, we DO need to worry about + * PNG_BUILD_DLL and PNG_STATIC because those change some defaults + * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed. + */ +#if defined(__CYGWIN__) +# if defined(ALL_STATIC) +# if defined(PNG_BUILD_DLL) +# undef PNG_BUILD_DLL +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# if !defined(PNG_STATIC) +# define PNG_STATIC +# endif +# else +# if defined (PNG_BUILD_DLL) +# if defined(PNG_STATIC) +# undef PNG_STATIC +# endif +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# else +# if defined(PNG_STATIC) +# if defined(PNG_USE_DLL) +# undef PNG_USE_DLL +# endif +# if defined(PNG_DLL) +# undef PNG_DLL +# endif +# else +# if !defined(PNG_USE_DLL) +# define PNG_USE_DLL +# endif +# if !defined(PNG_DLL) +# define PNG_DLL +# endif +# endif +# endif +# endif +#endif + +/* This protects us against compilers that run on a windowing system + * and thus don't have or would rather us not use the stdio types: + * stdin, stdout, and stderr. The only one currently used is stderr + * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will + * prevent these from being compiled and used. #defining PNG_NO_STDIO + * will also prevent these, plus will prevent the entire set of stdio + * macros and functions (FILE *, printf, etc.) from being compiled and used, + * unless (PNG_DEBUG > 0) has been #defined. + * + * #define PNG_NO_CONSOLE_IO + * #define PNG_NO_STDIO + */ + +#if defined(_WIN32_WCE) +# include <windows.h> + /* Console I/O functions are not supported on WindowsCE */ +# define PNG_NO_CONSOLE_IO +# ifdef PNG_DEBUG +# undef PNG_DEBUG +# endif +#endif + +#ifdef PNG_BUILD_DLL +# ifndef PNG_CONSOLE_IO_SUPPORTED +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# endif +#endif + +# ifdef PNG_NO_STDIO +# ifndef PNG_NO_CONSOLE_IO +# define PNG_NO_CONSOLE_IO +# endif +# ifdef PNG_DEBUG +# if (PNG_DEBUG > 0) +# include <stdio.h> +# endif +# endif +# else +# if !defined(_WIN32_WCE) +/* "stdio.h" functions are not supported on WindowsCE */ +# include <stdio.h> +# endif +# endif + +/* This macro protects us against machines that don't have function + * prototypes (ie K&R style headers). If your compiler does not handle + * function prototypes, define this macro and use the included ansi2knr. + * I've always been able to use _NO_PROTO as the indicator, but you may + * need to drag the empty declaration out in front of here, or change the + * ifdef to suit your own needs. + */ +#ifndef PNGARG + +#ifdef OF /* zlib prototype munger */ +# define PNGARG(arglist) OF(arglist) +#else + +#ifdef _NO_PROTO +# define PNGARG(arglist) () +# ifndef PNG_TYPECAST_NULL +# define PNG_TYPECAST_NULL +# endif +#else +# define PNGARG(arglist) arglist +#endif /* _NO_PROTO */ + + +#endif /* OF */ + +#endif /* PNGARG */ + +/* Try to determine if we are compiling on a Mac. Note that testing for + * just __MWERKS__ is not good enough, because the Codewarrior is now used + * on non-Mac platforms. + */ +#ifndef MACOS +# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) +# define MACOS +# endif +#endif + +/* enough people need this for various reasons to include it here */ +#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE) +# include <sys/types.h> +#endif + +#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED) +# define PNG_SETJMP_SUPPORTED +#endif + +#ifdef PNG_SETJMP_SUPPORTED +/* This is an attempt to force a single setjmp behaviour on Linux. If + * the X config stuff didn't define _BSD_SOURCE we wouldn't need this. + */ + +# ifdef __linux__ +# ifdef _BSD_SOURCE +# define PNG_SAVE_BSD_SOURCE +# undef _BSD_SOURCE +# endif +# ifdef _SETJMP_H + /* If you encounter a compiler error here, see the explanation + * near the end of INSTALL. + */ + __pngconf.h__ already includes setjmp.h; + __dont__ include it again.; +# endif +# endif /* __linux__ */ + + /* include setjmp.h for error handling */ +# include <setjmp.h> + +# ifdef __linux__ +# ifdef PNG_SAVE_BSD_SOURCE +# ifndef _BSD_SOURCE +# define _BSD_SOURCE +# endif +# undef PNG_SAVE_BSD_SOURCE +# endif +# endif /* __linux__ */ +#endif /* PNG_SETJMP_SUPPORTED */ + +#ifdef BSD +# include <strings.h> +#else +# include <string.h> +#endif + +/* Other defines for things like memory and the like can go here. */ +#ifdef PNG_INTERNAL + +#include <stdlib.h> + +/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which + * aren't usually used outside the library (as far as I know), so it is + * debatable if they should be exported at all. In the future, when it is + * possible to have run-time registry of chunk-handling functions, some of + * these will be made available again. +#define PNG_EXTERN extern + */ +#define PNG_EXTERN + +/* Other defines specific to compilers can go here. Try to keep + * them inside an appropriate ifdef/endif pair for portability. + */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) +# if defined(MACOS) + /* We need to check that <math.h> hasn't already been included earlier + * as it seems it doesn't agree with <fp.h>, yet we should really use + * <fp.h> if possible. + */ +# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) +# include <fp.h> +# endif +# else +# include <math.h> +# endif +# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) + /* Amiga SAS/C: We must include builtin FPU functions when compiling using + * MATH=68881 + */ +# include <m68881.h> +# endif +#endif + +/* Codewarrior on NT has linking problems without this. */ +#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__) +# define PNG_ALWAYS_EXTERN +#endif + +/* This provides the non-ANSI (far) memory allocation routines. */ +#if defined(__TURBOC__) && defined(__MSDOS__) +# include <mem.h> +# include <alloc.h> +#endif + +/* I have no idea why is this necessary... */ +#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \ + defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__)) +# include <malloc.h> +#endif + +/* This controls how fine the dithering gets. As this allocates + * a largish chunk of memory (32K), those who are not as concerned + * with dithering quality can decrease some or all of these. + */ +#ifndef PNG_DITHER_RED_BITS +# define PNG_DITHER_RED_BITS 5 +#endif +#ifndef PNG_DITHER_GREEN_BITS +# define PNG_DITHER_GREEN_BITS 5 +#endif +#ifndef PNG_DITHER_BLUE_BITS +# define PNG_DITHER_BLUE_BITS 5 +#endif + +/* This controls how fine the gamma correction becomes when you + * are only interested in 8 bits anyway. Increasing this value + * results in more memory being used, and more pow() functions + * being called to fill in the gamma tables. Don't set this value + * less then 8, and even that may not work (I haven't tested it). + */ + +#ifndef PNG_MAX_GAMMA_8 +# define PNG_MAX_GAMMA_8 11 +#endif + +/* This controls how much a difference in gamma we can tolerate before + * we actually start doing gamma conversion. + */ +#ifndef PNG_GAMMA_THRESHOLD +# define PNG_GAMMA_THRESHOLD 0.05 +#endif + +#endif /* PNG_INTERNAL */ + +/* The following uses const char * instead of char * for error + * and warning message functions, so some compilers won't complain. + * If you do not want to use const, define PNG_NO_CONST here. + */ + +#ifndef PNG_NO_CONST +# define PNG_CONST const +#else +# define PNG_CONST +#endif + +/* The following defines give you the ability to remove code from the + * library that you will not be using. I wish I could figure out how to + * automate this, but I can't do that without making it seriously hard + * on the users. So if you are not using an ability, change the #define + * to and #undef, and that part of the library will not be compiled. If + * your linker can't find a function, you may want to make sure the + * ability is defined here. Some of these depend upon some others being + * defined. I haven't figured out all the interactions here, so you may + * have to experiment awhile to get everything to compile. If you are + * creating or using a shared library, you probably shouldn't touch this, + * as it will affect the size of the structures, and this will cause bad + * things to happen if the library and/or application ever change. + */ + +/* Any features you will not be using can be undef'ed here */ + +/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user + * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS + * on the compile line, then pick and choose which ones to define without + * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED + * if you only want to have a png-compliant reader/writer but don't need + * any of the extra transformations. This saves about 80 kbytes in a + * typical installation of the library. (PNG_NO_* form added in version + * 1.0.1c, for consistency) + */ + +/* The size of the png_text structure changed in libpng-1.0.6 when + * iTXt support was added. iTXt support was turned off by default through + * libpng-1.2.x, to support old apps that malloc the png_text structure + * instead of calling png_set_text() and letting libpng malloc it. It + * was turned on by default in libpng-1.3.0. + */ + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +# ifndef PNG_NO_iTXt_SUPPORTED +# define PNG_NO_iTXt_SUPPORTED +# endif +# ifndef PNG_NO_READ_iTXt +# define PNG_NO_READ_iTXt +# endif +# ifndef PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_iTXt +# endif +#endif + +#if !defined(PNG_NO_iTXt_SUPPORTED) +# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt) +# define PNG_READ_iTXt +# endif +# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt) +# define PNG_WRITE_iTXt +# endif +#endif + +/* The following support, added after version 1.0.0, can be turned off here en + * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility + * with old applications that require the length of png_struct and png_info + * to remain unchanged. + */ + +#ifdef PNG_LEGACY_SUPPORTED +# define PNG_NO_FREE_ME +# define PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_NO_READ_USER_CHUNKS +# define PNG_NO_READ_iCCP +# define PNG_NO_WRITE_iCCP +# define PNG_NO_READ_iTXt +# define PNG_NO_WRITE_iTXt +# define PNG_NO_READ_sCAL +# define PNG_NO_WRITE_sCAL +# define PNG_NO_READ_sPLT +# define PNG_NO_WRITE_sPLT +# define PNG_NO_INFO_IMAGE +# define PNG_NO_READ_RGB_TO_GRAY +# define PNG_NO_READ_USER_TRANSFORM +# define PNG_NO_WRITE_USER_TRANSFORM +# define PNG_NO_USER_MEM +# define PNG_NO_READ_EMPTY_PLTE +# define PNG_NO_MNG_FEATURES +# define PNG_NO_FIXED_POINT_SUPPORTED +#endif + +/* Ignore attempt to turn off both floating and fixed point support */ +#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \ + !defined(PNG_NO_FIXED_POINT_SUPPORTED) +# define PNG_FIXED_POINT_SUPPORTED +#endif + +#ifndef PNG_NO_FREE_ME +# define PNG_FREE_ME_SUPPORTED +#endif + +#if defined(PNG_READ_SUPPORTED) + +#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_TRANSFORMS) +# define PNG_READ_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_READ_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_READ_EXPAND +# define PNG_READ_EXPAND_SUPPORTED +# endif +# ifndef PNG_NO_READ_SHIFT +# define PNG_READ_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACK +# define PNG_READ_PACK_SUPPORTED +# endif +# ifndef PNG_NO_READ_BGR +# define PNG_READ_BGR_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP +# define PNG_READ_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_PACKSWAP +# define PNG_READ_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT +# define PNG_READ_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_READ_DITHER +# define PNG_READ_DITHER_SUPPORTED +# endif +# ifndef PNG_NO_READ_BACKGROUND +# define PNG_READ_BACKGROUND_SUPPORTED +# endif +# ifndef PNG_NO_READ_16_TO_8 +# define PNG_READ_16_TO_8_SUPPORTED +# endif +# ifndef PNG_NO_READ_FILLER +# define PNG_READ_FILLER_SUPPORTED +# endif +# ifndef PNG_NO_READ_GAMMA +# define PNG_READ_GAMMA_SUPPORTED +# endif +# ifndef PNG_NO_READ_GRAY_TO_RGB +# define PNG_READ_GRAY_TO_RGB_SUPPORTED +# endif +# ifndef PNG_NO_READ_SWAP_ALPHA +# define PNG_READ_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_INVERT_ALPHA +# define PNG_READ_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_STRIP_ALPHA +# define PNG_READ_STRIP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_READ_USER_TRANSFORM +# define PNG_READ_USER_TRANSFORM_SUPPORTED +# endif +# ifndef PNG_NO_READ_RGB_TO_GRAY +# define PNG_READ_RGB_TO_GRAY_SUPPORTED +# endif +#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_PROGRESSIVE_READ) && \ + !defined(PNG_PROGRESSIVE_READ_SUPPORTED) /* if you don't do progressive */ +# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */ +#endif /* about interlacing capability! You'll */ + /* still have interlacing unless you change the following line: */ + +#define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */ + +#ifndef PNG_NO_READ_COMPOSITE_NODIV +# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */ +# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */ +# endif +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, will be removed from version 2.0.0. + Use PNG_MNG_FEATURES_SUPPORTED instead. */ +#ifndef PNG_NO_READ_EMPTY_PLTE +# define PNG_READ_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_READ_SUPPORTED */ + +#if defined(PNG_WRITE_SUPPORTED) + +# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_TRANSFORMS) +# define PNG_WRITE_TRANSFORMS_SUPPORTED +#endif + +#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED +# ifndef PNG_NO_WRITE_SHIFT +# define PNG_WRITE_SHIFT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACK +# define PNG_WRITE_PACK_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_BGR +# define PNG_WRITE_BGR_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_SWAP +# define PNG_WRITE_SWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_PACKSWAP +# define PNG_WRITE_PACKSWAP_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT +# define PNG_WRITE_INVERT_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_FILLER +# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */ +# endif +# ifndef PNG_NO_WRITE_SWAP_ALPHA +# define PNG_WRITE_SWAP_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_INVERT_ALPHA +# define PNG_WRITE_INVERT_ALPHA_SUPPORTED +# endif +# ifndef PNG_NO_WRITE_USER_TRANSFORM +# define PNG_WRITE_USER_TRANSFORM_SUPPORTED +# endif +#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ + +#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \ + !defined(PNG_WRITE_INTERLACING_SUPPORTED) +#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant + encoders, but can cause trouble + if left undefined */ +#endif + +#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \ + !defined(PNG_WRITE_WEIGHTED_FILTER) && \ + defined(PNG_FLOATING_POINT_SUPPORTED) +# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED +#endif + +#ifndef PNG_NO_WRITE_FLUSH +# define PNG_WRITE_FLUSH_SUPPORTED +#endif + +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */ +#ifndef PNG_NO_WRITE_EMPTY_PLTE +# define PNG_WRITE_EMPTY_PLTE_SUPPORTED +#endif +#endif + +#endif /* PNG_WRITE_SUPPORTED */ + +#ifndef PNG_1_0_X +# ifndef PNG_NO_ERROR_NUMBERS +# define PNG_ERROR_NUMBERS_SUPPORTED +# endif +#endif /* PNG_1_0_X */ + +#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) +# ifndef PNG_NO_USER_TRANSFORM_PTR +# define PNG_USER_TRANSFORM_PTR_SUPPORTED +# endif +#endif + +#ifndef PNG_NO_STDIO +# define PNG_TIME_RFC1123_SUPPORTED +#endif + +/* This adds extra functions in pngget.c for accessing data from the + * info pointer (added in version 0.99) + * png_get_image_width() + * png_get_image_height() + * png_get_bit_depth() + * png_get_color_type() + * png_get_compression_type() + * png_get_filter_type() + * png_get_interlace_type() + * png_get_pixel_aspect_ratio() + * png_get_pixels_per_meter() + * png_get_x_offset_pixels() + * png_get_y_offset_pixels() + * png_get_x_offset_microns() + * png_get_y_offset_microns() + */ +#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED) +# define PNG_EASY_ACCESS_SUPPORTED +#endif + +/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 + * and removed from version 1.2.20. The following will be removed + * from libpng-1.4.0 +*/ + +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE) +# ifndef PNG_OPTIMIZED_CODE_SUPPORTED +# define PNG_OPTIMIZED_CODE_SUPPORTED +# endif +#endif + +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) +# ifndef PNG_ASSEMBLER_CODE_SUPPORTED +# define PNG_ASSEMBLER_CODE_SUPPORTED +# endif + +# if defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4) + /* work around 64-bit gcc compiler bugs in gcc-3.x */ +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if defined(__APPLE__) +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if (defined(__MWERKS__) && ((__MWERKS__ < 0x0900) || macintosh)) +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_MMX_CODE_SUPPORTED +# endif + +#endif +/* end of obsolete code to be removed from libpng-1.4.0 */ + +#if !defined(PNG_1_0_X) +#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) +# define PNG_USER_MEM_SUPPORTED +#endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.2.6 */ +#if !defined(PNG_1_0_X) +#ifndef PNG_SET_USER_LIMITS_SUPPORTED +#if !defined(PNG_NO_SET_USER_LIMITS) && !defined(PNG_SET_USER_LIMITS_SUPPORTED) +# define PNG_SET_USER_LIMITS_SUPPORTED +#endif +#endif +#endif /* PNG_1_0_X */ + +/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGS no matter + * how large, set these limits to 0x7fffffffL + */ +#ifndef PNG_USER_WIDTH_MAX +# define PNG_USER_WIDTH_MAX 1000000L +#endif +#ifndef PNG_USER_HEIGHT_MAX +# define PNG_USER_HEIGHT_MAX 1000000L +#endif + +/* These are currently experimental features, define them if you want */ + +/* very little testing */ +/* +#ifdef PNG_READ_SUPPORTED +# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED +# endif +#endif +*/ + +/* This is only for PowerPC big-endian and 680x0 systems */ +/* some testing */ +/* +#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED +# define PNG_READ_BIG_ENDIAN_SUPPORTED +#endif +*/ + +/* Buggy compilers (e.g., gcc 2.7.2.2) need this */ +/* +#define PNG_NO_POINTER_INDEXING +*/ + +/* These functions are turned off by default, as they will be phased out. */ +/* +#define PNG_USELESS_TESTS_SUPPORTED +#define PNG_CORRECT_PALETTE_SUPPORTED +*/ + +/* Any chunks you are not interested in, you can undef here. The + * ones that allocate memory may be expecially important (hIST, + * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info + * a bit smaller. + */ + +#if defined(PNG_READ_SUPPORTED) && \ + !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_READ_ANCILLARY_CHUNKS) +# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#if defined(PNG_WRITE_SUPPORTED) && \ + !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ + !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS) +# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED +#endif + +#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_READ_TEXT +# define PNG_NO_READ_iTXt +# define PNG_NO_READ_tEXt +# define PNG_NO_READ_zTXt +#endif +#ifndef PNG_NO_READ_bKGD +# define PNG_READ_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +#endif +#ifndef PNG_NO_READ_cHRM +# define PNG_READ_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +#endif +#ifndef PNG_NO_READ_gAMA +# define PNG_READ_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +#endif +#ifndef PNG_NO_READ_hIST +# define PNG_READ_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +#endif +#ifndef PNG_NO_READ_iCCP +# define PNG_READ_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +#endif +#ifndef PNG_NO_READ_iTXt +# ifndef PNG_READ_iTXt_SUPPORTED +# define PNG_READ_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_READ_oFFs +# define PNG_READ_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +#endif +#ifndef PNG_NO_READ_pCAL +# define PNG_READ_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_sCAL +# define PNG_READ_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_pHYs +# define PNG_READ_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +#endif +#ifndef PNG_NO_READ_sBIT +# define PNG_READ_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sPLT +# define PNG_READ_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sRGB +# define PNG_READ_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +#endif +#ifndef PNG_NO_READ_tEXt +# define PNG_READ_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_tIME +# define PNG_READ_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +#endif +#ifndef PNG_NO_READ_tRNS +# define PNG_READ_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +#endif +#ifndef PNG_NO_READ_zTXt +# define PNG_READ_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +#endif +#ifndef PNG_NO_READ_UNKNOWN_CHUNKS +# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +#endif +#if !defined(PNG_NO_READ_USER_CHUNKS) && \ + defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +# define PNG_READ_USER_CHUNKS_SUPPORTED +# define PNG_USER_CHUNKS_SUPPORTED +# ifdef PNG_NO_READ_UNKNOWN_CHUNKS +# undef PNG_NO_READ_UNKNOWN_CHUNKS +# endif +# ifdef PNG_NO_HANDLE_AS_UNKNOWN +# undef PNG_NO_HANDLE_AS_UNKNOWN +# endif +#endif +#ifndef PNG_NO_READ_OPT_PLTE +# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */ +#endif /* optional PLTE chunk in RGB and RGBA images */ +#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \ + defined(PNG_READ_zTXt_SUPPORTED) +# define PNG_READ_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +#endif + +#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ + +#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED + +#ifdef PNG_NO_WRITE_TEXT +# define PNG_NO_WRITE_iTXt +# define PNG_NO_WRITE_tEXt +# define PNG_NO_WRITE_zTXt +#endif +#ifndef PNG_NO_WRITE_bKGD +# define PNG_WRITE_bKGD_SUPPORTED +# ifndef PNG_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_cHRM +# define PNG_WRITE_cHRM_SUPPORTED +# ifndef PNG_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_gAMA +# define PNG_WRITE_gAMA_SUPPORTED +# ifndef PNG_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_hIST +# define PNG_WRITE_hIST_SUPPORTED +# ifndef PNG_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iCCP +# define PNG_WRITE_iCCP_SUPPORTED +# ifndef PNG_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_iTXt +# ifndef PNG_WRITE_iTXt_SUPPORTED +# define PNG_WRITE_iTXt_SUPPORTED +# endif +# ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_oFFs +# define PNG_WRITE_oFFs_SUPPORTED +# ifndef PNG_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pCAL +# define PNG_WRITE_pCAL_SUPPORTED +# ifndef PNG_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sCAL +# define PNG_WRITE_sCAL_SUPPORTED +# ifndef PNG_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_pHYs +# define PNG_WRITE_pHYs_SUPPORTED +# ifndef PNG_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sBIT +# define PNG_WRITE_sBIT_SUPPORTED +# ifndef PNG_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sPLT +# define PNG_WRITE_sPLT_SUPPORTED +# ifndef PNG_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_sRGB +# define PNG_WRITE_sRGB_SUPPORTED +# ifndef PNG_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tEXt +# define PNG_WRITE_tEXt_SUPPORTED +# ifndef PNG_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tIME +# define PNG_WRITE_tIME_SUPPORTED +# ifndef PNG_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_tRNS +# define PNG_WRITE_tRNS_SUPPORTED +# ifndef PNG_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_zTXt +# define PNG_WRITE_zTXt_SUPPORTED +# ifndef PNG_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +# endif +#endif +#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED +# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED +# define PNG_UNKNOWN_CHUNKS_SUPPORTED +# endif +# ifndef PNG_NO_HANDLE_AS_UNKNOWN +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif +# endif +#endif +#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ + defined(PNG_WRITE_zTXt_SUPPORTED) +# define PNG_WRITE_TEXT_SUPPORTED +# ifndef PNG_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +# endif +#endif + +#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ + +/* Turn this off to disable png_read_png() and + * png_write_png() and leave the row_pointers member + * out of the info structure. + */ +#ifndef PNG_NO_INFO_IMAGE +# define PNG_INFO_IMAGE_SUPPORTED +#endif + +/* need the time information for reading tIME chunks */ +#if defined(PNG_tIME_SUPPORTED) +# if !defined(_WIN32_WCE) + /* "time.h" functions are not supported on WindowsCE */ +# include <time.h> +# endif +#endif + +/* Some typedefs to get us started. These should be safe on most of the + * common platforms. The typedefs should be at least as large as the + * numbers suggest (a png_uint_32 must be at least 32 bits long), but they + * don't have to be exactly that size. Some compilers dislike passing + * unsigned shorts as function parameters, so you may be better off using + * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may + * want to have unsigned int for png_uint_32 instead of unsigned long. + */ + +typedef unsigned long png_uint_32; +typedef long png_int_32; +typedef unsigned short png_uint_16; +typedef short png_int_16; +typedef unsigned char png_byte; + +/* This is usually size_t. It is typedef'ed just in case you need it to + change (I'm not sure if you will or not, so I thought I'd be safe) */ +#ifdef PNG_SIZE_T + typedef PNG_SIZE_T png_size_t; +# define png_sizeof(x) png_convert_size(sizeof(x)) +#else + typedef size_t png_size_t; +# define png_sizeof(x) sizeof(x) +#endif + +/* The following is needed for medium model support. It cannot be in the + * PNG_INTERNAL section. Needs modification for other compilers besides + * MSC. Model independent support declares all arrays and pointers to be + * large using the far keyword. The zlib version used must also support + * model independent data. As of version zlib 1.0.4, the necessary changes + * have been made in zlib. The USE_FAR_KEYWORD define triggers other + * changes that are needed. (Tim Wegner) + */ + +/* Separate compiler dependencies (problem here is that zlib.h always + defines FAR. (SJT) */ +#ifdef __BORLANDC__ +# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__) +# define LDATA 1 +# else +# define LDATA 0 +# endif + /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ +# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) +# define PNG_MAX_MALLOC_64K +# if (LDATA != 1) +# ifndef FAR +# define FAR __far +# endif +# define USE_FAR_KEYWORD +# endif /* LDATA != 1 */ + /* Possibly useful for moving data out of default segment. + * Uncomment it if you want. Could also define FARDATA as + * const if your compiler supports it. (SJT) +# define FARDATA FAR + */ +# endif /* __WIN32__, __FLAT__, __CYGWIN__ */ +#endif /* __BORLANDC__ */ + + +/* Suggest testing for specific compiler first before testing for + * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM, + * making reliance oncertain keywords suspect. (SJT) + */ + +/* MSC Medium model */ +#if defined(FAR) +# if defined(M_I86MM) +# define USE_FAR_KEYWORD +# define FARDATA FAR +# include <dos.h> +# endif +#endif + +/* SJT: default case */ +#ifndef FAR +# define FAR +#endif + +/* At this point FAR is always defined */ +#ifndef FARDATA +# define FARDATA +#endif + +/* Typedef for floating-point numbers that are converted + to fixed-point with a multiple of 100,000, e.g., int_gamma */ +typedef png_int_32 png_fixed_point; + +/* Add typedefs for pointers */ +typedef void FAR * png_voidp; +typedef png_byte FAR * png_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST char FAR * png_const_charp; +typedef char FAR * png_charp; +typedef png_fixed_point FAR * png_fixed_point_p; + +#ifndef PNG_NO_STDIO +#if defined(_WIN32_WCE) +typedef HANDLE png_FILE_p; +#else +typedef FILE * png_FILE_p; +#endif +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * png_doublep; +#endif + +/* Pointers to pointers; i.e. arrays */ +typedef png_byte FAR * FAR * png_bytepp; +typedef png_uint_32 FAR * FAR * png_uint_32pp; +typedef png_int_32 FAR * FAR * png_int_32pp; +typedef png_uint_16 FAR * FAR * png_uint_16pp; +typedef png_int_16 FAR * FAR * png_int_16pp; +typedef PNG_CONST char FAR * FAR * png_const_charpp; +typedef char FAR * FAR * png_charpp; +typedef png_fixed_point FAR * FAR * png_fixed_point_pp; +#ifdef PNG_FLOATING_POINT_SUPPORTED +typedef double FAR * FAR * png_doublepp; +#endif + +/* Pointers to pointers to pointers; i.e., pointer to array */ +typedef char FAR * FAR * FAR * png_charppp; + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* SPC - Is this stuff deprecated? */ +/* It'll be removed as of libpng-1.3.0 - GR-P */ +/* libpng typedefs for types in zlib. If zlib changes + * or another compression library is used, then change these. + * Eliminates need to change all the source files. + */ +typedef charf * png_zcharp; +typedef charf * FAR * png_zcharpp; +typedef z_stream FAR * png_zstreamp; +#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */ + +/* + * Define PNG_BUILD_DLL if the module being built is a Windows + * LIBPNG DLL. + * + * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL. + * It is equivalent to Microsoft predefined macro _DLL that is + * automatically defined when you compile using the share + * version of the CRT (C Run-Time library) + * + * The cygwin mods make this behavior a little different: + * Define PNG_BUILD_DLL if you are building a dll for use with cygwin + * Define PNG_STATIC if you are building a static library for use with cygwin, + * -or- if you are building an application that you want to link to the + * static library. + * PNG_USE_DLL is defined by default (no user action needed) unless one of + * the other flags is defined. + */ + +#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL)) +# define PNG_DLL +#endif +/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib. + * When building a static lib, default to no GLOBAL ARRAYS, but allow + * command-line override + */ +#if defined(__CYGWIN__) +# if !defined(PNG_STATIC) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +# else +# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS) +# if defined(PNG_USE_GLOBAL_ARRAYS) +# undef PNG_USE_GLOBAL_ARRAYS +# endif +# endif +# endif +# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# define PNG_USE_LOCAL_ARRAYS +# endif +#endif + +/* Do not use global arrays (helps with building DLL's) + * They are no longer used in libpng itself, since version 1.0.5c, + * but might be required for some pre-1.0.5c applications. + */ +#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) +# if defined(PNG_NO_GLOBAL_ARRAYS) || \ + (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER) +# define PNG_USE_LOCAL_ARRAYS +# else +# define PNG_USE_GLOBAL_ARRAYS +# endif +#endif + +#if defined(__CYGWIN__) +# undef PNGAPI +# define PNGAPI __cdecl +# undef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall", + * you may get warnings regarding the linkage of png_zalloc and png_zfree. + * Don't ignore those warnings; you must also reset the default calling + * convention in your compiler to match your PNGAPI, and you must build + * zlib and your applications the same way you build libpng. + */ + +#if defined(__MINGW32__) && !defined(PNG_MODULEDEF) +# ifndef PNG_NO_MODULEDEF +# define PNG_NO_MODULEDEF +# endif +#endif + +#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF) +# define PNG_IMPEXP +#endif + +#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \ + (( defined(_Windows) || defined(_WINDOWS) || \ + defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) + +# ifndef PNGAPI +# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) +# define PNGAPI __cdecl +# else +# define PNGAPI _cdecl +# endif +# endif + +# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \ + 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */) +# define PNG_IMPEXP +# endif + +# if !defined(PNG_IMPEXP) + +# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol +# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol + + /* Borland/Microsoft */ +# if defined(_MSC_VER) || defined(__BORLANDC__) +# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500) +# define PNG_EXPORT PNG_EXPORT_TYPE1 +# else +# define PNG_EXPORT PNG_EXPORT_TYPE2 +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __export +# else +# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in + VC++ */ +# endif /* Exists in Borland C++ for + C++ classes (== huge) */ +# endif +# endif + +# if !defined(PNG_IMPEXP) +# if defined(PNG_BUILD_DLL) +# define PNG_IMPEXP __declspec(dllexport) +# else +# define PNG_IMPEXP __declspec(dllimport) +# endif +# endif +# endif /* PNG_IMPEXP */ +#else /* !(DLL || non-cygwin WINDOWS) */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# ifndef PNGAPI +# define PNGAPI _System +# endif +# else +# if 0 /* ... other platforms, with other meanings */ +# endif +# endif +#endif + +#ifndef PNGAPI +# define PNGAPI +#endif +#ifndef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +#ifdef PNG_BUILDSYMS +# ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END +# endif +# ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT +# endif +# endif +#endif + +#ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol +#endif + +#ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type +# endif +#endif + +/* User may want to use these so they are not in PNG_INTERNAL. Any library + * functions that are passed far data must be model independent. + */ + +#ifndef PNG_ABORT +# define PNG_ABORT() abort() +#endif + +#ifdef PNG_SETJMP_SUPPORTED +# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) +#else +# define png_jmpbuf(png_ptr) \ + (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED) +#endif + +#if defined(USE_FAR_KEYWORD) /* memory model independent fns */ +/* use this to make far-to-near assignments */ +# define CHECK 1 +# define NOCHECK 0 +# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +# define png_snprintf _fsnprintf /* Added to v 1.2.19 */ +# define png_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +#else /* use the usual functions */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# ifndef PNG_NO_SNPRINTF +# ifdef _MSC_VER +# define png_snprintf _snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 _snprintf +# define png_snprintf6 _snprintf +# else +# define png_snprintf snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 snprintf +# define png_snprintf6 snprintf +# endif +# else + /* You don't have or don't want to use snprintf(). Caution: Using + * sprintf instead of snprintf exposes your application to accidental + * or malevolent buffer overflows. If you don't have snprintf() + * as a general rule you should provide one (you can get one from + * Portable OpenSSH). */ +# define png_snprintf(s1,n,fmt,x1) sprintf(s1,fmt,x1) +# define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2) +# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \ + sprintf(s1,fmt,x1,x2,x3,x4,x5,x6) +# endif +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +#endif +/* End of memory model independent support */ + +/* Just a little check that someone hasn't tried to define something + * contradictory. + */ +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536L +#endif + +/* Added at libpng-1.2.8 */ +#endif /* PNG_VERSION_INFO_ONLY */ + +#endif /* PNGCONF_H */ diff --git a/utils/openttd/unicode/brkiter.h b/utils/openttd/unicode/brkiter.h new file mode 100644 index 00000000000..7df5f140838 --- /dev/null +++ b/utils/openttd/unicode/brkiter.h @@ -0,0 +1,557 @@ +/* +******************************************************************************** +* Copyright (C) 1997-2007, International Business Machines +* Corporation and others. All Rights Reserved. +******************************************************************************** +* +* File brkiter.h +* +* Modification History: +* +* Date Name Description +* 02/18/97 aliu Added typedef for TextCount. Made DONE const. +* 05/07/97 aliu Fixed DLL declaration. +* 07/09/97 jfitz Renamed BreakIterator and interface synced with JDK +* 08/11/98 helena Sync-up JDK1.2. +* 01/13/2000 helena Added UErrorCode parameter to createXXXInstance methods. +******************************************************************************** +*/ + +#ifndef BRKITER_H +#define BRKITER_H + +#include "unicode/utypes.h" + +/** + * \file + * \brief C++ API: Break Iterator. + */ + +#if UCONFIG_NO_BREAK_ITERATION + +U_NAMESPACE_BEGIN + +/* + * Allow the declaration of APIs with pointers to BreakIterator + * even when break iteration is removed from the build. + */ +class BreakIterator; + +U_NAMESPACE_END + +#else + +#include "unicode/uobject.h" +#include "unicode/unistr.h" +#include "unicode/chariter.h" +#include "unicode/locid.h" +#include "unicode/ubrk.h" +#include "unicode/strenum.h" +#include "unicode/utext.h" +#include "unicode/umisc.h" + +U_NAMESPACE_BEGIN + +/** + * The BreakIterator class implements methods for finding the location + * of boundaries in text. BreakIterator is an abstract base class. + * Instances of BreakIterator maintain a current position and scan over + * text returning the index of characters where boundaries occur. + * <p> + * Line boundary analysis determines where a text string can be broken + * when line-wrapping. The mechanism correctly handles punctuation and + * hyphenated words. + * <p> + * Sentence boundary analysis allows selection with correct + * interpretation of periods within numbers and abbreviations, and + * trailing punctuation marks such as quotation marks and parentheses. + * <p> + * Word boundary analysis is used by search and replace functions, as + * well as within text editing applications that allow the user to + * select words with a double click. Word selection provides correct + * interpretation of punctuation marks within and following + * words. Characters that are not part of a word, such as symbols or + * punctuation marks, have word-breaks on both sides. + * <p> + * Character boundary analysis allows users to interact with + * characters as they expect to, for example, when moving the cursor + * through a text string. Character boundary analysis provides correct + * navigation of through character strings, regardless of how the + * character is stored. For example, an accented character might be + * stored as a base character and a diacritical mark. What users + * consider to be a character can differ between languages. + * <p> + * The text boundary positions are found according to the rules + * described in Unicode Standard Annex #29, Text Boundaries, and + * Unicode Standard Annex #14, Line Breaking Properties. These + * are available at http://www.unicode.org/reports/tr14/ and + * http://www.unicode.org/reports/tr29/. + * <p> + * In addition to the C++ API defined in this header file, a + * plain C API with equivalent functionality is defined in the + * file ubrk.h + * <p> + * Code snippits illustrating the use of the Break Iterator APIs + * are available in the ICU User Guide, + * http://icu-project.org/userguide/boundaryAnalysis.html + * and in the sample program icu/source/samples/break/break.cpp" + * + */ +class U_COMMON_API BreakIterator : public UObject { +public: + /** + * destructor + * @stable ICU 2.0 + */ + virtual ~BreakIterator(); + + /** + * Return true if another object is semantically equal to this + * one. The other object should be an instance of the same subclass of + * BreakIterator. Objects of different subclasses are considered + * unequal. + * <P> + * Return true if this BreakIterator is at the same position in the + * same text, and is the same class and type (word, line, etc.) of + * BreakIterator, as the argument. Text is considered the same if + * it contains the same characters, it need not be the same + * object, and styles are not considered. + * @stable ICU 2.0 + */ + virtual UBool operator==(const BreakIterator&) const = 0; + + /** + * Returns the complement of the result of operator== + * @param rhs The BreakIterator to be compared for inequality + * @return the complement of the result of operator== + * @stable ICU 2.0 + */ + UBool operator!=(const BreakIterator& rhs) const { return !operator==(rhs); } + + /** + * Return a polymorphic copy of this object. This is an abstract + * method which subclasses implement. + * @stable ICU 2.0 + */ + virtual BreakIterator* clone(void) const = 0; + + /** + * Return a polymorphic class ID for this object. Different subclasses + * will return distinct unequal values. + * @stable ICU 2.0 + */ + virtual UClassID getDynamicClassID(void) const = 0; + + /** + * Return a CharacterIterator over the text being analyzed. + * @stable ICU 2.0 + */ + virtual CharacterIterator& getText(void) const = 0; + + + /** + * Get a UText for the text being analyzed. + * The returned UText is a shallow clone of the UText used internally + * by the break iterator implementation. It can safely be used to + * access the text without impacting any break iterator operations, + * but the underlying text itself must not be altered. + * + * @param fillIn A UText to be filled in. If NULL, a new UText will be + * allocated to hold the result. + * @param status receives any error codes. + * @return The current UText for this break iterator. If an input + * UText was provided, it will always be returned. + * @stable ICU 3.4 + */ + virtual UText *getUText(UText *fillIn, UErrorCode &status) const = 0; + + /** + * Change the text over which this operates. The text boundary is + * reset to the start. + * @param text The UnicodeString used to change the text. + * @stable ICU 2.0 + */ + virtual void setText(const UnicodeString &text) = 0; + + /** + * Reset the break iterator to operate over the text represented by + * the UText. The iterator position is reset to the start. + * + * This function makes a shallow clone of the supplied UText. This means + * that the caller is free to immediately close or otherwise reuse the + * Utext that was passed as a parameter, but that the underlying text itself + * must not be altered while being referenced by the break iterator. + * + * @param text The UText used to change the text. + * @param status receives any error codes. + * @stable ICU 3.4 + */ + virtual void setText(UText *text, UErrorCode &status) = 0; + + /** + * Change the text over which this operates. The text boundary is + * reset to the start. + * Note that setText(UText *) provides similar functionality to this function, + * and is more efficient. + * @param it The CharacterIterator used to change the text. + * @stable ICU 2.0 + */ + virtual void adoptText(CharacterIterator* it) = 0; + + enum { + /** + * DONE is returned by previous() and next() after all valid + * boundaries have been returned. + * @stable ICU 2.0 + */ + DONE = (int32_t)-1 + }; + + /** + * Return the index of the first character in the text being scanned. + * @stable ICU 2.0 + */ + virtual int32_t first(void) = 0; + + /** + * Return the index immediately BEYOND the last character in the text being scanned. + * @stable ICU 2.0 + */ + virtual int32_t last(void) = 0; + + /** + * Return the boundary preceding the current boundary. + * @return The character index of the previous text boundary or DONE if all + * boundaries have been returned. + * @stable ICU 2.0 + */ + virtual int32_t previous(void) = 0; + + /** + * Return the boundary following the current boundary. + * @return The character index of the next text boundary or DONE if all + * boundaries have been returned. + * @stable ICU 2.0 + */ + virtual int32_t next(void) = 0; + + /** + * Return character index of the current interator position within the text. + * @return The boundary most recently returned. + * @stable ICU 2.0 + */ + virtual int32_t current(void) const = 0; + + /** + * Return the first boundary following the specified offset. + * The value returned is always greater than the offset or + * the value BreakIterator.DONE + * @param offset the offset to begin scanning. + * @return The first boundary after the specified offset. + * @stable ICU 2.0 + */ + virtual int32_t following(int32_t offset) = 0; + + /** + * Return the first boundary preceding the specified offset. + * The value returned is always smaller than the offset or + * the value BreakIterator.DONE + * @param offset the offset to begin scanning. + * @return The first boundary before the specified offset. + * @stable ICU 2.0 + */ + virtual int32_t preceding(int32_t offset) = 0; + + /** + * Return true if the specfied position is a boundary position. + * As a side effect, the current position of the iterator is set + * to the first boundary position at or following the specified offset. + * @param offset the offset to check. + * @return True if "offset" is a boundary position. + * @stable ICU 2.0 + */ + virtual UBool isBoundary(int32_t offset) = 0; + + /** + * Return the nth boundary from the current boundary + * @param n which boundary to return. A value of 0 + * does nothing. Negative values move to previous boundaries + * and positive values move to later boundaries. + * @return The index of the nth boundary from the current position, or + * DONE if there are fewer than |n| boundaries in the specfied direction. + * @stable ICU 2.0 + */ + virtual int32_t next(int32_t n) = 0; + + /** + * Create BreakIterator for word-breaks using the given locale. + * Returns an instance of a BreakIterator implementing word breaks. + * WordBreak is useful for word selection (ex. double click) + * @param where the locale. + * @param status the error code + * @return A BreakIterator for word-breaks. The UErrorCode& status + * parameter is used to return status information to the user. + * To check whether the construction succeeded or not, you should check + * the value of U_SUCCESS(err). If you wish more detailed information, you + * can check for informational error results which still indicate success. + * U_USING_FALLBACK_WARNING indicates that a fall back locale was used. For + * example, 'de_CH' was requested, but nothing was found there, so 'de' was + * used. U_USING_DEFAULT_WARNING indicates that the default locale data was + * used; neither the requested locale nor any of its fall back locales + * could be found. + * The caller owns the returned object and is responsible for deleting it. + * @stable ICU 2.0 + */ + static BreakIterator* U_EXPORT2 + createWordInstance(const Locale& where, UErrorCode& status); + + /** + * Create BreakIterator for line-breaks using specified locale. + * Returns an instance of a BreakIterator implementing line breaks. Line + * breaks are logically possible line breaks, actual line breaks are + * usually determined based on display width. + * LineBreak is useful for word wrapping text. + * @param where the locale. + * @param status The error code. + * @return A BreakIterator for line-breaks. The UErrorCode& status + * parameter is used to return status information to the user. + * To check whether the construction succeeded or not, you should check + * the value of U_SUCCESS(err). If you wish more detailed information, you + * can check for informational error results which still indicate success. + * U_USING_FALLBACK_WARNING indicates that a fall back locale was used. For + * example, 'de_CH' was requested, but nothing was found there, so 'de' was + * used. U_USING_DEFAULT_WARNING indicates that the default locale data was + * used; neither the requested locale nor any of its fall back locales + * could be found. + * The caller owns the returned object and is responsible for deleting it. + * @stable ICU 2.0 + */ + static BreakIterator* U_EXPORT2 + createLineInstance(const Locale& where, UErrorCode& status); + + /** + * Create BreakIterator for character-breaks using specified locale + * Returns an instance of a BreakIterator implementing character breaks. + * Character breaks are boundaries of combining character sequences. + * @param where the locale. + * @param status The error code. + * @return A BreakIterator for character-breaks. The UErrorCode& status + * parameter is used to return status information to the user. + * To check whether the construction succeeded or not, you should check + * the value of U_SUCCESS(err). If you wish more detailed information, you + * can check for informational error results which still indicate success. + * U_USING_FALLBACK_WARNING indicates that a fall back locale was used. For + * example, 'de_CH' was requested, but nothing was found there, so 'de' was + * used. U_USING_DEFAULT_WARNING indicates that the default locale data was + * used; neither the requested locale nor any of its fall back locales + * could be found. + * The caller owns the returned object and is responsible for deleting it. + * @stable ICU 2.0 + */ + static BreakIterator* U_EXPORT2 + createCharacterInstance(const Locale& where, UErrorCode& status); + + /** + * Create BreakIterator for sentence-breaks using specified locale + * Returns an instance of a BreakIterator implementing sentence breaks. + * @param where the locale. + * @param status The error code. + * @return A BreakIterator for sentence-breaks. The UErrorCode& status + * parameter is used to return status information to the user. + * To check whether the construction succeeded or not, you should check + * the value of U_SUCCESS(err). If you wish more detailed information, you + * can check for informational error results which still indicate success. + * U_USING_FALLBACK_WARNING indicates that a fall back locale was used. For + * example, 'de_CH' was requested, but nothing was found there, so 'de' was + * used. U_USING_DEFAULT_WARNING indicates that the default locale data was + * used; neither the requested locale nor any of its fall back locales + * could be found. + * The caller owns the returned object and is responsible for deleting it. + * @stable ICU 2.0 + */ + static BreakIterator* U_EXPORT2 + createSentenceInstance(const Locale& where, UErrorCode& status); + + /** + * Create BreakIterator for title-casing breaks using the specified locale + * Returns an instance of a BreakIterator implementing title breaks. + * The iterator returned locates title boundaries as described for + * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration, + * please use Word Boundary iterator.{@link #createWordInstance } + * + * @param where the locale. + * @param status The error code. + * @return A BreakIterator for title-breaks. The UErrorCode& status + * parameter is used to return status information to the user. + * To check whether the construction succeeded or not, you should check + * the value of U_SUCCESS(err). If you wish more detailed information, you + * can check for informational error results which still indicate success. + * U_USING_FALLBACK_WARNING indicates that a fall back locale was used. For + * example, 'de_CH' was requested, but nothing was found there, so 'de' was + * used. U_USING_DEFAULT_WARNING indicates that the default locale data was + * used; neither the requested locale nor any of its fall back locales + * could be found. + * The caller owns the returned object and is responsible for deleting it. + * @stable ICU 2.1 + */ + static BreakIterator* U_EXPORT2 + createTitleInstance(const Locale& where, UErrorCode& status); + + /** + * Get the set of Locales for which TextBoundaries are installed. + * <p><b>Note:</b> this will not return locales added through the register + * call. To see the registered locales too, use the getAvailableLocales + * function that returns a StringEnumeration object </p> + * @param count the output parameter of number of elements in the locale list + * @return available locales + * @stable ICU 2.0 + */ + static const Locale* U_EXPORT2 getAvailableLocales(int32_t& count); + + /** + * Get name of the object for the desired Locale, in the desired langauge. + * @param objectLocale must be from getAvailableLocales. + * @param displayLocale specifies the desired locale for output. + * @param name the fill-in parameter of the return value + * Uses best match. + * @return user-displayable name + * @stable ICU 2.0 + */ + static UnicodeString& U_EXPORT2 getDisplayName(const Locale& objectLocale, + const Locale& displayLocale, + UnicodeString& name); + + /** + * Get name of the object for the desired Locale, in the langauge of the + * default locale. + * @param objectLocale must be from getMatchingLocales + * @param name the fill-in parameter of the return value + * @return user-displayable name + * @stable ICU 2.0 + */ + static UnicodeString& U_EXPORT2 getDisplayName(const Locale& objectLocale, + UnicodeString& name); + + /** + * Thread safe client-buffer-based cloning operation + * Do NOT call delete on a safeclone, since 'new' is not used to create it. + * @param stackBuffer user allocated space for the new clone. If NULL new memory will be allocated. + * If buffer is not large enough, new memory will be allocated. + * @param BufferSize reference to size of allocated space. + * If BufferSize == 0, a sufficient size for use in cloning will + * be returned ('pre-flighting') + * If BufferSize is not enough for a stack-based safe clone, + * new memory will be allocated. + * @param status to indicate whether the operation went on smoothly or there were errors + * An informational status value, U_SAFECLONE_ALLOCATED_ERROR, is used if any allocations were + * necessary. + * @return pointer to the new clone + * + * @stable ICU 2.0 + */ + virtual BreakIterator * createBufferClone(void *stackBuffer, + int32_t &BufferSize, + UErrorCode &status) = 0; + + /** + * Determine whether the BreakIterator was created in user memory by + * createBufferClone(), and thus should not be deleted. Such objects + * must be closed by an explicit call to the destructor (not delete). + * @stable ICU 2.0 + */ + inline UBool isBufferClone(void); + +#if !UCONFIG_NO_SERVICE + /** + * Register a new break iterator of the indicated kind, to use in the given locale. + * The break iterator will be adopted. Clones of the iterator will be returned + * if a request for a break iterator of the given kind matches or falls back to + * this locale. + * @param toAdopt the BreakIterator instance to be adopted + * @param locale the Locale for which this instance is to be registered + * @param kind the type of iterator for which this instance is to be registered + * @param status the in/out status code, no special meanings are assigned + * @return a registry key that can be used to unregister this instance + * @stable ICU 2.4 + */ + static URegistryKey U_EXPORT2 registerInstance(BreakIterator* toAdopt, + const Locale& locale, + UBreakIteratorType kind, + UErrorCode& status); + + /** + * Unregister a previously-registered BreakIterator using the key returned from the + * register call. Key becomes invalid after a successful call and should not be used again. + * The BreakIterator corresponding to the key will be deleted. + * @param key the registry key returned by a previous call to registerInstance + * @param status the in/out status code, no special meanings are assigned + * @return TRUE if the iterator for the key was successfully unregistered + * @stable ICU 2.4 + */ + static UBool U_EXPORT2 unregister(URegistryKey key, UErrorCode& status); + + /** + * Return a StringEnumeration over the locales available at the time of the call, + * including registered locales. + * @return a StringEnumeration over the locales available at the time of the call + * @stable ICU 2.4 + */ + static StringEnumeration* U_EXPORT2 getAvailableLocales(void); +#endif + + /** + * Returns the locale for this break iterator. Two flavors are available: valid and + * actual locale. + * @stable ICU 2.8 + */ + Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const; + + /** Get the locale for this break iterator object. You can choose between valid and actual locale. + * @param type type of the locale we're looking for (valid or actual) + * @param status error code for the operation + * @return the locale + * @internal + */ + const char *getLocaleID(ULocDataLocaleType type, UErrorCode& status) const; + + private: + static BreakIterator* buildInstance(const Locale& loc, const char *type, int32_t kind, UErrorCode& status); + static BreakIterator* createInstance(const Locale& loc, int32_t kind, UErrorCode& status); + static BreakIterator* makeInstance(const Locale& loc, int32_t kind, UErrorCode& status); + + friend class ICUBreakIteratorFactory; + friend class ICUBreakIteratorService; + +protected: + /** @internal */ + BreakIterator(); + /** @internal */ + UBool fBufferClone; + /** @internal */ + BreakIterator (const BreakIterator &other) : UObject(other), fBufferClone(FALSE) {} + +private: + + /** @internal */ + char actualLocale[ULOC_FULLNAME_CAPACITY]; + char validLocale[ULOC_FULLNAME_CAPACITY]; + + /** + * The assignment operator has no real implementation. + * It's provided to make the compiler happy. Do not call. + */ + BreakIterator& operator=(const BreakIterator&); +}; + +inline UBool BreakIterator::isBufferClone() +{ + return fBufferClone; +} + +U_NAMESPACE_END + +#endif /* #if !UCONFIG_NO_BREAK_ITERATION */ + +#endif // _BRKITER +//eof + diff --git a/utils/openttd/unicode/caniter.h b/utils/openttd/unicode/caniter.h new file mode 100644 index 00000000000..84a65958d16 --- /dev/null +++ b/utils/openttd/unicode/caniter.h @@ -0,0 +1,201 @@ +/* + ******************************************************************************* + * Copyright (C) 1996-2006, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ + +#ifndef CANITER_H +#define CANITER_H + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_NORMALIZATION + +#include "unicode/uobject.h" +#include "unicode/unistr.h" + +/** + * \file + * \brief C++ API: Canonical Iterator + */ + +/** Should permutation skip characters with combining class zero + * Should be either TRUE or FALSE. This is a compile time option + * @stable ICU 2.4 + */ +#ifndef CANITER_SKIP_ZEROES +#define CANITER_SKIP_ZEROES TRUE +#endif + +U_NAMESPACE_BEGIN + +class Hashtable; + +/** + * This class allows one to iterate through all the strings that are canonically equivalent to a given + * string. For example, here are some sample results: +Results for: {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA} +1: \\u0041\\u030A\\u0064\\u0307\\u0327 + = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA} +2: \\u0041\\u030A\\u0064\\u0327\\u0307 + = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D}{COMBINING CEDILLA}{COMBINING DOT ABOVE} +3: \\u0041\\u030A\\u1E0B\\u0327 + = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D WITH DOT ABOVE}{COMBINING CEDILLA} +4: \\u0041\\u030A\\u1E11\\u0307 + = {LATIN CAPITAL LETTER A}{COMBINING RING ABOVE}{LATIN SMALL LETTER D WITH CEDILLA}{COMBINING DOT ABOVE} +5: \\u00C5\\u0064\\u0307\\u0327 + = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA} +6: \\u00C5\\u0064\\u0327\\u0307 + = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D}{COMBINING CEDILLA}{COMBINING DOT ABOVE} +7: \\u00C5\\u1E0B\\u0327 + = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D WITH DOT ABOVE}{COMBINING CEDILLA} +8: \\u00C5\\u1E11\\u0307 + = {LATIN CAPITAL LETTER A WITH RING ABOVE}{LATIN SMALL LETTER D WITH CEDILLA}{COMBINING DOT ABOVE} +9: \\u212B\\u0064\\u0307\\u0327 + = {ANGSTROM SIGN}{LATIN SMALL LETTER D}{COMBINING DOT ABOVE}{COMBINING CEDILLA} +10: \\u212B\\u0064\\u0327\\u0307 + = {ANGSTROM SIGN}{LATIN SMALL LETTER D}{COMBINING CEDILLA}{COMBINING DOT ABOVE} +11: \\u212B\\u1E0B\\u0327 + = {ANGSTROM SIGN}{LATIN SMALL LETTER D WITH DOT ABOVE}{COMBINING CEDILLA} +12: \\u212B\\u1E11\\u0307 + = {ANGSTROM SIGN}{LATIN SMALL LETTER D WITH CEDILLA}{COMBINING DOT ABOVE} + *<br>Note: the code is intended for use with small strings, and is not suitable for larger ones, + * since it has not been optimized for that situation. + * Note, CanonicalIterator is not intended to be subclassed. + * @author M. Davis + * @author C++ port by V. Weinstein + * @stable ICU 2.4 + */ +class U_COMMON_API CanonicalIterator : public UObject { +public: + /** + * Construct a CanonicalIterator object + * @param source string to get results for + * @param status Fill-in parameter which receives the status of this operation. + * @stable ICU 2.4 + */ + CanonicalIterator(const UnicodeString &source, UErrorCode &status); + + /** Destructor + * Cleans pieces + * @stable ICU 2.4 + */ + virtual ~CanonicalIterator(); + + /** + * Gets the NFD form of the current source we are iterating over. + * @return gets the source: NOTE: it is the NFD form of source + * @stable ICU 2.4 + */ + UnicodeString getSource(); + + /** + * Resets the iterator so that one can start again from the beginning. + * @stable ICU 2.4 + */ + void reset(); + + /** + * Get the next canonically equivalent string. + * <br><b>Warning: The strings are not guaranteed to be in any particular order.</b> + * @return the next string that is canonically equivalent. A bogus string is returned when + * the iteration is done. + * @stable ICU 2.4 + */ + UnicodeString next(); + + /** + * Set a new source for this iterator. Allows object reuse. + * @param newSource the source string to iterate against. This allows the same iterator to be used + * while changing the source string, saving object creation. + * @param status Fill-in parameter which receives the status of this operation. + * @stable ICU 2.4 + */ + void setSource(const UnicodeString &newSource, UErrorCode &status); + + /** + * Dumb recursive implementation of permutation. + * TODO: optimize + * @param source the string to find permutations for + * @param skipZeros determine if skip zeros + * @param result the results in a set. + * @param status Fill-in parameter which receives the status of this operation. + * @internal + */ + static void U_EXPORT2 permute(UnicodeString &source, UBool skipZeros, Hashtable *result, UErrorCode &status); + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.2 + */ + static UClassID U_EXPORT2 getStaticClassID(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.2 + */ + virtual UClassID getDynamicClassID() const; + +private: + // ===================== PRIVATES ============================== + // private default constructor + CanonicalIterator(); + + + /** + * Copy constructor. Private for now. + * @internal + */ + CanonicalIterator(const CanonicalIterator& other); + + /** + * Assignment operator. Private for now. + * @internal + */ + CanonicalIterator& operator=(const CanonicalIterator& other); + + // fields + UnicodeString source; + UBool done; + + // 2 dimensional array holds the pieces of the string with + // their different canonically equivalent representations + UnicodeString **pieces; + int32_t pieces_length; + int32_t *pieces_lengths; + + // current is used in iterating to combine pieces + int32_t *current; + int32_t current_length; + + // transient fields + UnicodeString buffer; + + // we have a segment, in NFD. Find all the strings that are canonically equivalent to it. + UnicodeString *getEquivalents(const UnicodeString &segment, int32_t &result_len, UErrorCode &status); //private String[] getEquivalents(String segment) + + //Set getEquivalents2(String segment); + Hashtable *getEquivalents2(Hashtable *fillinResult, const UChar *segment, int32_t segLen, UErrorCode &status); + //Hashtable *getEquivalents2(const UnicodeString &segment, int32_t segLen, UErrorCode &status); + + /** + * See if the decomposition of cp2 is at segment starting at segmentPos + * (with canonical rearrangment!) + * If so, take the remainder, and return the equivalents + */ + //Set extract(int comp, String segment, int segmentPos, StringBuffer buffer); + Hashtable *extract(Hashtable *fillinResult, UChar32 comp, const UChar *segment, int32_t segLen, int32_t segmentPos, UErrorCode &status); + //Hashtable *extract(UChar32 comp, const UnicodeString &segment, int32_t segLen, int32_t segmentPos, UErrorCode &status); + + void cleanPieces(); + +}; + +U_NAMESPACE_END + +#endif /* #if !UCONFIG_NO_NORMALIZATION */ + +#endif diff --git a/utils/openttd/unicode/chariter.h b/utils/openttd/unicode/chariter.h new file mode 100644 index 00000000000..12fc9248a23 --- /dev/null +++ b/utils/openttd/unicode/chariter.h @@ -0,0 +1,716 @@ +/* +******************************************************************** +* +* Copyright (C) 1997-2005, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************** +*/ + +#ifndef CHARITER_H +#define CHARITER_H + +#include "unicode/utypes.h" +#include "unicode/uobject.h" +#include "unicode/unistr.h" +/** + * \file + * \brief C++ API: Character Iterator + */ + +U_NAMESPACE_BEGIN +/** + * Abstract class that defines an API for forward-only iteration + * on text objects. + * This is a minimal interface for iteration without random access + * or backwards iteration. It is especially useful for wrapping + * streams with converters into an object for collation or + * normalization. + * + * <p>Characters can be accessed in two ways: as code units or as + * code points. + * Unicode code points are 21-bit integers and are the scalar values + * of Unicode characters. ICU uses the type UChar32 for them. + * Unicode code units are the storage units of a given + * Unicode/UCS Transformation Format (a character encoding scheme). + * With UTF-16, all code points can be represented with either one + * or two code units ("surrogates"). + * String storage is typically based on code units, while properties + * of characters are typically determined using code point values. + * Some processes may be designed to work with sequences of code units, + * or it may be known that all characters that are important to an + * algorithm can be represented with single code units. + * Other processes will need to use the code point access functions.</p> + * + * <p>ForwardCharacterIterator provides nextPostInc() to access + * a code unit and advance an internal position into the text object, + * similar to a <code>return text[position++]</code>.<br> + * It provides next32PostInc() to access a code point and advance an internal + * position.</p> + * + * <p>next32PostInc() assumes that the current position is that of + * the beginning of a code point, i.e., of its first code unit. + * After next32PostInc(), this will be true again. + * In general, access to code units and code points in the same + * iteration loop should not be mixed. In UTF-16, if the current position + * is on a second code unit (Low Surrogate), then only that code unit + * is returned even by next32PostInc().</p> + * + * <p>For iteration with either function, there are two ways to + * check for the end of the iteration. When there are no more + * characters in the text object: + * <ul> + * <li>The hasNext() function returns FALSE.</li> + * <li>nextPostInc() and next32PostInc() return DONE + * when one attempts to read beyond the end of the text object.</li> + * </ul> + * + * Example: + * \code + * void function1(ForwardCharacterIterator &it) { + * UChar32 c; + * while(it.hasNext()) { + * c=it.next32PostInc(); + * // use c + * } + * } + * + * void function1(ForwardCharacterIterator &it) { + * UChar c; + * while((c=it.nextPostInc())!=ForwardCharacterIterator::DONE) { + * // use c + * } + * } + * \endcode + * </p> + * + * @stable ICU 2.0 + */ +class U_COMMON_API ForwardCharacterIterator : public UObject { +public: + /** + * Value returned by most of ForwardCharacterIterator's functions + * when the iterator has reached the limits of its iteration. + * @stable ICU 2.0 + */ + enum { DONE = 0xffff }; + + /** + * Destructor. + * @stable ICU 2.0 + */ + virtual ~ForwardCharacterIterator(); + + /** + * Returns true when both iterators refer to the same + * character in the same character-storage object. + * @param that The ForwardCharacterIterator to be compared for equality + * @return true when both iterators refer to the same + * character in the same character-storage object + * @stable ICU 2.0 + */ + virtual UBool operator==(const ForwardCharacterIterator& that) const = 0; + + /** + * Returns true when the iterators refer to different + * text-storage objects, or to different characters in the + * same text-storage object. + * @param that The ForwardCharacterIterator to be compared for inequality + * @return true when the iterators refer to different + * text-storage objects, or to different characters in the + * same text-storage object + * @stable ICU 2.0 + */ + inline UBool operator!=(const ForwardCharacterIterator& that) const; + + /** + * Generates a hash code for this iterator. + * @return the hash code. + * @stable ICU 2.0 + */ + virtual int32_t hashCode(void) const = 0; + + /** + * Returns a UClassID for this ForwardCharacterIterator ("poor man's + * RTTI").<P> Despite the fact that this function is public, + * DO NOT CONSIDER IT PART OF CHARACTERITERATOR'S API! + * @return a UClassID for this ForwardCharacterIterator + * @stable ICU 2.0 + */ + virtual UClassID getDynamicClassID(void) const = 0; + + /** + * Gets the current code unit for returning and advances to the next code unit + * in the iteration range + * (toward endIndex()). If there are + * no more code units to return, returns DONE. + * @return the current code unit. + * @stable ICU 2.0 + */ + virtual UChar nextPostInc(void) = 0; + + /** + * Gets the current code point for returning and advances to the next code point + * in the iteration range + * (toward endIndex()). If there are + * no more code points to return, returns DONE. + * @return the current code point. + * @stable ICU 2.0 + */ + virtual UChar32 next32PostInc(void) = 0; + + /** + * Returns FALSE if there are no more code units or code points + * at or after the current position in the iteration range. + * This is used with nextPostInc() or next32PostInc() in forward + * iteration. + * @returns FALSE if there are no more code units or code points + * at or after the current position in the iteration range. + * @stable ICU 2.0 + */ + virtual UBool hasNext() = 0; + +protected: + /** Default constructor to be overridden in the implementing class. @stable ICU 2.0*/ + ForwardCharacterIterator(); + + /** Copy constructor to be overridden in the implementing class. @stable ICU 2.0*/ + ForwardCharacterIterator(const ForwardCharacterIterator &other); + + /** + * Assignment operator to be overridden in the implementing class. + * @stable ICU 2.0 + */ + ForwardCharacterIterator &operator=(const ForwardCharacterIterator&) { return *this; } +}; + +/** + * Abstract class that defines an API for iteration + * on text objects. + * This is an interface for forward and backward iteration + * and random access into a text object. + * + * <p>The API provides backward compatibility to the Java and older ICU + * CharacterIterator classes but extends them significantly: + * <ol> + * <li>CharacterIterator is now a subclass of ForwardCharacterIterator.</li> + * <li>While the old API functions provided forward iteration with + * "pre-increment" semantics, the new one also provides functions + * with "post-increment" semantics. They are more efficient and should + * be the preferred iterator functions for new implementations. + * The backward iteration always had "pre-decrement" semantics, which + * are efficient.</li> + * <li>Just like ForwardCharacterIterator, it provides access to + * both code units and code points. Code point access versions are available + * for the old and the new iteration semantics.</li> + * <li>There are new functions for setting and moving the current position + * without returning a character, for efficiency.</li> + * </ol> + * + * See ForwardCharacterIterator for examples for using the new forward iteration + * functions. For backward iteration, there is also a hasPrevious() function + * that can be used analogously to hasNext(). + * The old functions work as before and are shown below.</p> + * + * <p>Examples for some of the new functions:</p> + * + * Forward iteration with hasNext(): + * \code + * void forward1(CharacterIterator &it) { + * UChar32 c; + * for(it.setToStart(); it.hasNext();) { + * c=it.next32PostInc(); + * // use c + * } + * } + * \endcode + * Forward iteration more similar to loops with the old forward iteration, + * showing a way to convert simple for() loops: + * \code + * void forward2(CharacterIterator &it) { + * UChar c; + * for(c=it.firstPostInc(); c!=CharacterIterator::DONE; c=it.nextPostInc()) { + * // use c + * } + * } + * \endcode + * Backward iteration with setToEnd() and hasPrevious(): + * \code + * void backward1(CharacterIterator &it) { + * UChar32 c; + * for(it.setToEnd(); it.hasPrevious();) { + * c=it.previous32(); + * // use c + * } + * } + * \endcode + * Backward iteration with a more traditional for() loop: + * \code + * void backward2(CharacterIterator &it) { + * UChar c; + * for(c=it.last(); c!=CharacterIterator::DONE; c=it.previous()) { + * // use c + * } + * } + * \endcode + * + * Example for random access: + * \code + * void random(CharacterIterator &it) { + * // set to the third code point from the beginning + * it.move32(3, CharacterIterator::kStart); + * // get a code point from here without moving the position + * UChar32 c=it.current32(); + * // get the position + * int32_t pos=it.getIndex(); + * // get the previous code unit + * UChar u=it.previous(); + * // move back one more code unit + * it.move(-1, CharacterIterator::kCurrent); + * // set the position back to where it was + * // and read the same code point c and move beyond it + * it.setIndex(pos); + * if(c!=it.next32PostInc()) { + * exit(1); // CharacterIterator inconsistent + * } + * } + * \endcode + * + * <p>Examples, especially for the old API:</p> + * + * Function processing characters, in this example simple output + * <pre> + * \code + * void processChar( UChar c ) + * { + * cout << " " << c; + * } + * \endcode + * </pre> + * Traverse the text from start to finish + * <pre> + * \code + * void traverseForward(CharacterIterator& iter) + * { + * for(UChar c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) { + * processChar(c); + * } + * } + * \endcode + * </pre> + * Traverse the text backwards, from end to start + * <pre> + * \code + * void traverseBackward(CharacterIterator& iter) + * { + * for(UChar c = iter.last(); c != CharacterIterator.DONE; c = iter.previous()) { + * processChar(c); + * } + * } + * \endcode + * </pre> + * Traverse both forward and backward from a given position in the text. + * Calls to notBoundary() in this example represents some additional stopping criteria. + * <pre> + * \code + * void traverseOut(CharacterIterator& iter, int32_t pos) + * { + * UChar c; + * for (c = iter.setIndex(pos); + * c != CharacterIterator.DONE && (Unicode::isLetter(c) || Unicode::isDigit(c)); + * c = iter.next()) {} + * int32_t end = iter.getIndex(); + * for (c = iter.setIndex(pos); + * c != CharacterIterator.DONE && (Unicode::isLetter(c) || Unicode::isDigit(c)); + * c = iter.previous()) {} + * int32_t start = iter.getIndex() + 1; + * + * cout << "start: " << start << " end: " << end << endl; + * for (c = iter.setIndex(start); iter.getIndex() < end; c = iter.next() ) { + * processChar(c); + * } + * } + * \endcode + * </pre> + * Creating a StringCharacterIterator and calling the test functions + * <pre> + * \code + * void CharacterIterator_Example( void ) + * { + * cout << endl << "===== CharacterIterator_Example: =====" << endl; + * UnicodeString text("Ein kleiner Satz."); + * StringCharacterIterator iterator(text); + * cout << "----- traverseForward: -----------" << endl; + * traverseForward( iterator ); + * cout << endl << endl << "----- traverseBackward: ----------" << endl; + * traverseBackward( iterator ); + * cout << endl << endl << "----- traverseOut: ---------------" << endl; + * traverseOut( iterator, 7 ); + * cout << endl << endl << "-----" << endl; + * } + * \endcode + * </pre> + * + * @stable ICU 2.0 + */ +class U_COMMON_API CharacterIterator : public ForwardCharacterIterator { +public: + /** + * Origin enumeration for the move() and move32() functions. + * @stable ICU 2.0 + */ + enum EOrigin { kStart, kCurrent, kEnd }; + + /** + * Returns a pointer to a new CharacterIterator of the same + * concrete class as this one, and referring to the same + * character in the same text-storage object as this one. The + * caller is responsible for deleting the new clone. + * @return a pointer to a new CharacterIterator + * @stable ICU 2.0 + */ + virtual CharacterIterator* clone(void) const = 0; + + /** + * Sets the iterator to refer to the first code unit in its + * iteration range, and returns that code unit. + * This can be used to begin an iteration with next(). + * @return the first code unit in its iteration range. + * @stable ICU 2.0 + */ + virtual UChar first(void) = 0; + + /** + * Sets the iterator to refer to the first code unit in its + * iteration range, returns that code unit, and moves the position + * to the second code unit. This is an alternative to setToStart() + * for forward iteration with nextPostInc(). + * @return the first code unit in its iteration range. + * @stable ICU 2.0 + */ + virtual UChar firstPostInc(void); + + /** + * Sets the iterator to refer to the first code point in its + * iteration range, and returns that code unit, + * This can be used to begin an iteration with next32(). + * Note that an iteration with next32PostInc(), beginning with, + * e.g., setToStart() or firstPostInc(), is more efficient. + * @return the first code point in its iteration range. + * @stable ICU 2.0 + */ + virtual UChar32 first32(void) = 0; + + /** + * Sets the iterator to refer to the first code point in its + * iteration range, returns that code point, and moves the position + * to the second code point. This is an alternative to setToStart() + * for forward iteration with next32PostInc(). + * @return the first code point in its iteration range. + * @stable ICU 2.0 + */ + virtual UChar32 first32PostInc(void); + + /** + * Sets the iterator to refer to the first code unit or code point in its + * iteration range. This can be used to begin a forward + * iteration with nextPostInc() or next32PostInc(). + * @return the start position of the iteration range + * @stable ICU 2.0 + */ + inline int32_t setToStart(); + + /** + * Sets the iterator to refer to the last code unit in its + * iteration range, and returns that code unit. + * This can be used to begin an iteration with previous(). + * @return the last code unit. + * @stable ICU 2.0 + */ + virtual UChar last(void) = 0; + + /** + * Sets the iterator to refer to the last code point in its + * iteration range, and returns that code unit. + * This can be used to begin an iteration with previous32(). + * @return the last code point. + * @stable ICU 2.0 + */ + virtual UChar32 last32(void) = 0; + + /** + * Sets the iterator to the end of its iteration range, just behind + * the last code unit or code point. This can be used to begin a backward + * iteration with previous() or previous32(). + * @return the end position of the iteration range + * @stable ICU 2.0 + */ + inline int32_t setToEnd(); + + /** + * Sets the iterator to refer to the "position"-th code unit + * in the text-storage object the iterator refers to, and + * returns that code unit. + * @param position the "position"-th code unit in the text-storage object + * @return the "position"-th code unit. + * @stable ICU 2.0 + */ + virtual UChar setIndex(int32_t position) = 0; + + /** + * Sets the iterator to refer to the beginning of the code point + * that contains the "position"-th code unit + * in the text-storage object the iterator refers to, and + * returns that code point. + * The current position is adjusted to the beginning of the code point + * (its first code unit). + * @param position the "position"-th code unit in the text-storage object + * @return the "position"-th code point. + * @stable ICU 2.0 + */ + virtual UChar32 setIndex32(int32_t position) = 0; + + /** + * Returns the code unit the iterator currently refers to. + * @return the current code unit. + * @stable ICU 2.0 + */ + virtual UChar current(void) const = 0; + + /** + * Returns the code point the iterator currently refers to. + * @return the current code point. + * @stable ICU 2.0 + */ + virtual UChar32 current32(void) const = 0; + + /** + * Advances to the next code unit in the iteration range + * (toward endIndex()), and returns that code unit. If there are + * no more code units to return, returns DONE. + * @return the next code unit. + * @stable ICU 2.0 + */ + virtual UChar next(void) = 0; + + /** + * Advances to the next code point in the iteration range + * (toward endIndex()), and returns that code point. If there are + * no more code points to return, returns DONE. + * Note that iteration with "pre-increment" semantics is less + * efficient than iteration with "post-increment" semantics + * that is provided by next32PostInc(). + * @return the next code point. + * @stable ICU 2.0 + */ + virtual UChar32 next32(void) = 0; + + /** + * Advances to the previous code unit in the iteration range + * (toward startIndex()), and returns that code unit. If there are + * no more code units to return, returns DONE. + * @return the previous code unit. + * @stable ICU 2.0 + */ + virtual UChar previous(void) = 0; + + /** + * Advances to the previous code point in the iteration range + * (toward startIndex()), and returns that code point. If there are + * no more code points to return, returns DONE. + * @return the previous code point. + * @stable ICU 2.0 + */ + virtual UChar32 previous32(void) = 0; + + /** + * Returns FALSE if there are no more code units or code points + * before the current position in the iteration range. + * This is used with previous() or previous32() in backward + * iteration. + * @return FALSE if there are no more code units or code points + * before the current position in the iteration range, return TRUE otherwise. + * @stable ICU 2.0 + */ + virtual UBool hasPrevious() = 0; + + /** + * Returns the numeric index in the underlying text-storage + * object of the character returned by first(). Since it's + * possible to create an iterator that iterates across only + * part of a text-storage object, this number isn't + * necessarily 0. + * @returns the numeric index in the underlying text-storage + * object of the character returned by first(). + * @stable ICU 2.0 + */ + inline int32_t startIndex(void) const; + + /** + * Returns the numeric index in the underlying text-storage + * object of the position immediately BEYOND the character + * returned by last(). + * @return the numeric index in the underlying text-storage + * object of the position immediately BEYOND the character + * returned by last(). + * @stable ICU 2.0 + */ + inline int32_t endIndex(void) const; + + /** + * Returns the numeric index in the underlying text-storage + * object of the character the iterator currently refers to + * (i.e., the character returned by current()). + * @return the numberic index in the text-storage object of + * the character the iterator currently refers to + * @stable ICU 2.0 + */ + inline int32_t getIndex(void) const; + + /** + * Returns the length of the entire text in the underlying + * text-storage object. + * @return the length of the entire text in the text-storage object + * @stable ICU 2.0 + */ + inline int32_t getLength() const; + + /** + * Moves the current position relative to the start or end of the + * iteration range, or relative to the current position itself. + * The movement is expressed in numbers of code units forward + * or backward by specifying a positive or negative delta. + * @param delta the position relative to origin. A positive delta means forward; + * a negative delta means backward. + * @param origin Origin enumeration {kStart, kCurrent, kEnd} + * @return the new position + * @stable ICU 2.0 + */ + virtual int32_t move(int32_t delta, EOrigin origin) = 0; + + /** + * Moves the current position relative to the start or end of the + * iteration range, or relative to the current position itself. + * The movement is expressed in numbers of code points forward + * or backward by specifying a positive or negative delta. + * @param delta the position relative to origin. A positive delta means forward; + * a negative delta means backward. + * @param origin Origin enumeration {kStart, kCurrent, kEnd} + * @return the new position + * @stable ICU 2.0 + */ + virtual int32_t move32(int32_t delta, EOrigin origin) = 0; + + /** + * Copies the text under iteration into the UnicodeString + * referred to by "result". + * @param result Receives a copy of the text under iteration. + * @stable ICU 2.0 + */ + virtual void getText(UnicodeString& result) = 0; + +protected: + /** + * Empty constructor. + * @stable ICU 2.0 + */ + CharacterIterator(); + + /** + * Constructor, just setting the length field in this base class. + * @stable ICU 2.0 + */ + CharacterIterator(int32_t length); + + /** + * Constructor, just setting the length and position fields in this base class. + * @stable ICU 2.0 + */ + CharacterIterator(int32_t length, int32_t position); + + /** + * Constructor, just setting the length, start, end, and position fields in this base class. + * @stable ICU 2.0 + */ + CharacterIterator(int32_t length, int32_t textBegin, int32_t textEnd, int32_t position); + + /** + * Copy constructor. + * + * @param that The CharacterIterator to be copied + * @stable ICU 2.0 + */ + CharacterIterator(const CharacterIterator &that); + + /** + * Assignment operator. Sets this CharacterIterator to have the same behavior, + * as the one passed in. + * @param that The CharacterIterator passed in. + * @return the newly set CharacterIterator. + * @stable ICU 2.0 + */ + CharacterIterator &operator=(const CharacterIterator &that); + + /** + * Base class text length field. + * Necessary this for correct getText() and hashCode(). + * @stable ICU 2.0 + */ + int32_t textLength; + + /** + * Base class field for the current position. + * @stable ICU 2.0 + */ + int32_t pos; + + /** + * Base class field for the start of the iteration range. + * @stable ICU 2.0 + */ + int32_t begin; + + /** + * Base class field for the end of the iteration range. + * @stable ICU 2.0 + */ + int32_t end; +}; + +inline UBool +ForwardCharacterIterator::operator!=(const ForwardCharacterIterator& that) const { + return !operator==(that); +} + +inline int32_t +CharacterIterator::setToStart() { + return move(0, kStart); +} + +inline int32_t +CharacterIterator::setToEnd() { + return move(0, kEnd); +} + +inline int32_t +CharacterIterator::startIndex(void) const { + return begin; +} + +inline int32_t +CharacterIterator::endIndex(void) const { + return end; +} + +inline int32_t +CharacterIterator::getIndex(void) const { + return pos; +} + +inline int32_t +CharacterIterator::getLength(void) const { + return textLength; +} + +U_NAMESPACE_END +#endif diff --git a/utils/openttd/unicode/dbbi.h b/utils/openttd/unicode/dbbi.h new file mode 100644 index 00000000000..c7984ef862f --- /dev/null +++ b/utils/openttd/unicode/dbbi.h @@ -0,0 +1,41 @@ +/* +********************************************************************** +* Copyright (C) 1999-2006 IBM Corp. All rights reserved. +********************************************************************** +* Date Name Description +* 12/1/99 rgillam Complete port from Java. +* 01/13/2000 helena Added UErrorCode to ctors. +********************************************************************** +*/ + +#ifndef DBBI_H +#define DBBI_H + +#include "unicode/rbbi.h" + +#if !UCONFIG_NO_BREAK_ITERATION + +/** + * \file + * \brief C++ API: Dictionary Based Break Iterator + */ + +U_NAMESPACE_BEGIN + +/** + * An obsolete subclass of RuleBasedBreakIterator. Handling of dictionary- + * based break iteration has been folded into the base class. This class + * is deprecated as of ICU 3.6. + */ + +#ifndef U_HIDE_DEPRECATED_API + +typedef RuleBasedBreakIterator DictionaryBasedBreakIterator; + +#endif + +U_NAMESPACE_END + +#endif /* #if !UCONFIG_NO_BREAK_ITERATION */ + +#endif diff --git a/utils/openttd/unicode/docmain.h b/utils/openttd/unicode/docmain.h new file mode 100644 index 00000000000..973ebea7a4a --- /dev/null +++ b/utils/openttd/unicode/docmain.h @@ -0,0 +1,202 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 1997-2007, International Business Machines Corporation and + * others. All Rights Reserved. + * + * FILE NAME: DOCMAIN.h + * + * Date Name Description + * 12/11/2000 Ram Creation. + */ + +/* This file contains documentation for Doxygen and doesnot have + * any significance with respect to C or C++ API + */ + +/*! \mainpage + * + * \section API API Reference Usage + * + * <h3>C++ Programmers:</h3> + * <p>Use <a href="hierarchy.html">Class Hierarchy</a> or <a href="classes.html"> Alphabetical List </a> + * or <a href="annotated.html"> Compound List</a> + * to find the class you are interested in. For example, to find BreakIterator, + * you can go to the <a href="classes.html"> Alphabetical List</a>, then click on + * "BreakIterator". Once you are at the class, you will find an inheritance + * chart, a list of the public members, a detailed description of the class, + * then detailed member descriptions.</p> + * + * <h3>C Programmers:</h3> + * <p>Use <a href="#Module">Module List</a> or <a href="globals.html">File Members</a> + * to find a list of all the functions and constants. + * For example, to find BreakIterator functions you would click on + * <a href="files.html"> File List</a>, + * then find "ubrk.h" and click on it. You will find descriptions of Defines, + * Typedefs, Enumerations, and Functions, with detailed descriptions below. + * If you want to find a specific function, such as ubrk_next(), then click + * first on <a href="globals.html"> File Members</a>, then use your browser + * Find dialog to search for "ubrk_next()".</p> + * + * + * <h3>API References for Previous Releases</h3> + * <p>The API References for each release of ICU are also available as + * a zip file from the ICU + * <a href="http://icu-project.org/download/">download page</a>.</p> + * + * <hr> + * + * <h2>Architecture (User's Guide)</h2> + * <ul> + * <li><a href="http://icu-project.org/userguide/">Introduction</a></li> + * <li><a href="http://icu-project.org/userguide/i18n.html">Internationalization</a></li> + * <li><a href="http://icu-project.org/userguide/design.html">Locale Model</a></li> + * <li><a href="http://icu-project.org/userguide/design.html">Multithreading</a></li> + * <li><a href="http://icu-project.org/userguide/conversion.html">Conversion</a></li> + * <li><a href="http://icu-project.org/userguide/design.html">Error Handling</a></li> + * </ul> + * + * <hr> + *\htmlonly <h2><a NAME="Module">Module List</a></h2> \endhtmlonly + * <table border="1" cols="3" align="center"> + * <tr> + * <td><strong>Module Name</strong></td> + * <td><strong>C</strong></td> + * <td><strong>C++</strong></td> + * </tr> + * <tr> + * <td>Basic Types and Constants</td> + * <td>utypes.h</td> + * <td>utypes.h</td> + * </tr> + * <tr> + * <td>Strings and Character Iteration</td> + * <td>ustring.h, utf.h</td> + * <td>UnicodeString, CharacterIterator</td> + * </tr> + * <tr> + * <td>Unicode Character<br>Properties and Names</td> + * <td>uchar.h</td> + * <td>uchar.h C API</td> + * </tr> + * <tr> + * <td>Codepage Conversion</td> + * <td>ucnv.h</td> + * <td>ucnv.h C API</td> + * </tr> + * <tr> + * <td>Unicode Text Compression</td> + * <td>ucnv.h <br> (encoding name "SCSU" or "BOCU-1")</td> + * <td>ucnv.h C API</td> + * </tr> + * <tr> + * <td>Locales </td> + * <td>uloc.h</a></td> + * <td>Locale</td> + * </tr> + * <tr> + * <td>Resource Bundles</td> + * <td>ures.h</td> + * <td>ResourceBundle</td> + * </tr> + * <tr> + * <td>Normalization</td> + * <td>unorm.h</td> + * <td>Normalizer</td> + * </tr> + * <tr> + * <td>Calendars</td> + * <td>ucal.h</td> + * <td>Calendar</td> + * </tr> + * <tr> + * <td>Date and Time Formatting</td> + * <td>udat.h</td> + * <td>DateFormat</td> + * </tr> + * <tr> + * <td>Message Formatting</td> + * <td>umsg.h</td> + * <td>MessageFormat</td> + * </tr> + * <tr> + * <td>Number Formatting</td> + * <td>unum.h</td> + * <td>NumberFormat</td> + * </tr> + * <tr> + * <td>Number Spellout <br> (Rule Based Number Formatting)</td> + * <td>unum.h <br> (use UNUM_SPELLOUT)</td> + * <td>RuleBasedNumberFormat</td> + * </tr> + * <tr> + * <td>Text Transformation <br> (Transliteration)</td> + * <td>utrans.h</td> + * <td>Transliterator</td> + * </tr> + * <tr> + * <td>Bidirectional Algorithm</td> + * <td>ubidi.h</td> + * <td>ubidi.h C API</td> + * </tr> + * <tr> + * <td>Arabic Shaping</td> + * <td>ushape.h</td> + * <td>ushape.h C API</td> + * </tr> + * <tr> + * <td>Collation</td> + * <td>ucol.h</td> + * <td>Collator</td> + * </tr> + * <tr> + * <td>String Searching</td> + * <td>usearch.h</td> + * <td>StringSearch</td> + * </tr> + * <tr> + * <td>Text Boundary Analysis <br> (Break Iteration)</td> + * <td>ubrk.h</td> + * <td>BreakIterator</td> + * </tr> + * <tr> + * <td>Unicode Set</td> + * <td>uset.h</td> + * <td>UnicodeSet</td> + * </tr> + * <tr> + * <td>Regular Expressions</td> + * <td>uregex.h</td> + * <td>RegexPattern, RegexMatcher</td> + * </tr> + * <tr> + * <td>StringPrep</td> + * <td>usprep.h</td> + * <td>usprep.h C API</td> + * </tr> + * <tr> + * <td>International Domain Names in Applications</td> + * <td>uidna.h</td> + * <td>uidna.h C API</td> + * </tr> + * <tr> + * <td>Universal Time Scale</td> + * <td>utmscale.h</td> + * <td>utmscale.h C API</td> + * </tr> + * <tr> + * <td>Basic Layout Engine Types and Constants</td> + * <td>(no C API)</td> + * <td>LETypes.h</td> + * </tr> + * <tr> + * <td>Complex Text Layout</td> + * <td>(no C API)</td> + * <td>LayoutEngine, ParagraphLayout</td> + * </tr> + * <tr> + * <td>ICU I/O</td> + * <td>ustdio.h</td> + * <td>ustream.h</td> + * </tr> + * </table> + */ diff --git a/utils/openttd/unicode/locid.h b/utils/openttd/unicode/locid.h new file mode 100644 index 00000000000..a3cc23b31fa --- /dev/null +++ b/utils/openttd/unicode/locid.h @@ -0,0 +1,765 @@ +/* +****************************************************************************** +* +* Copyright (C) 1996-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +****************************************************************************** +* +* File locid.h +* +* Created by: Helena Shih +* +* Modification History: +* +* Date Name Description +* 02/11/97 aliu Changed gLocPath to fgLocPath and added methods to +* get and set it. +* 04/02/97 aliu Made operator!= inline; fixed return value of getName(). +* 04/15/97 aliu Cleanup for AIX/Win32. +* 04/24/97 aliu Numerous changes per code review. +* 08/18/98 stephen Added tokenizeString(),changed getDisplayName() +* 09/08/98 stephen Moved definition of kEmptyString for Mac Port +* 11/09/99 weiv Added const char * getName() const; +* 04/12/00 srl removing unicodestring api's and cached hash code +* 08/10/01 grhoten Change the static Locales to accessor functions +****************************************************************************** +*/ + +#ifndef LOCID_H +#define LOCID_H + +#include "unicode/utypes.h" +#include "unicode/uobject.h" +#include "unicode/unistr.h" +#include "unicode/putil.h" +#include "unicode/uloc.h" +#include "unicode/strenum.h" + +/** + * \file + * \brief C++ API: Locale ID object. + */ + +/** + * A <code>Locale</code> object represents a specific geographical, political, + * or cultural region. An operation that requires a <code>Locale</code> to perform + * its task is called <em>locale-sensitive</em> and uses the <code>Locale</code> + * to tailor information for the user. For example, displaying a number + * is a locale-sensitive operation--the number should be formatted + * according to the customs/conventions of the user's native country, + * region, or culture. + * + * The Locale class is not suitable for subclassing. + * + * <P> + * You can create a <code>Locale</code> object using the constructor in + * this class: + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * Locale( const char* language, + * const char* country, + * const char* variant); + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * The first argument to the constructors is a valid <STRONG>ISO + * Language Code.</STRONG> These codes are the lower-case two-letter + * codes as defined by ISO-639. + * You can find a full list of these codes at: + * <BR><a href ="http://www.loc.gov/standards/iso639-2/"> + * http://www.loc.gov/standards/iso639-2/</a> + * + * <P> + * The second argument to the constructors is a valid <STRONG>ISO Country + * Code.</STRONG> These codes are the upper-case two-letter codes + * as defined by ISO-3166. + * You can find a full list of these codes at a number of sites, such as: + * <BR><a href="http://www.iso.org/iso/en/prods-services/iso3166ma/index.html"> + * http://www.iso.org/iso/en/prods-services/iso3166ma/index.html</a> + * + * <P> + * The third constructor requires a third argument--the <STRONG>Variant.</STRONG> + * The Variant codes are vendor and browser-specific. + * For example, use REVISED for a langauge's revised script orthography, and POSIX for POSIX. + * Where there are two variants, separate them with an underscore, and + * put the most important one first. For + * example, a Traditional Spanish collation might be referenced, with + * "ES", "ES", "Traditional_POSIX". + * + * <P> + * Because a <code>Locale</code> object is just an identifier for a region, + * no validity check is performed when you construct a <code>Locale</code>. + * If you want to see whether particular resources are available for the + * <code>Locale</code> you construct, you must query those resources. For + * example, ask the <code>NumberFormat</code> for the locales it supports + * using its <code>getAvailableLocales</code> method. + * <BR><STRONG>Note:</STRONG> When you ask for a resource for a particular + * locale, you get back the best available match, not necessarily + * precisely what you asked for. For more information, look at + * <code>ResourceBundle</code>. + * + * <P> + * The <code>Locale</code> class provides a number of convenient constants + * that you can use to create <code>Locale</code> objects for commonly used + * locales. For example, the following refers to a <code>Locale</code> object + * for the United States: + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * Locale::getUS() + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * + * <P> + * Once you've created a <code>Locale</code> you can query it for information about + * itself. Use <code>getCountry</code> to get the ISO Country Code and + * <code>getLanguage</code> to get the ISO Language Code. You can + * use <code>getDisplayCountry</code> to get the + * name of the country suitable for displaying to the user. Similarly, + * you can use <code>getDisplayLanguage</code> to get the name of + * the language suitable for displaying to the user. Interestingly, + * the <code>getDisplayXXX</code> methods are themselves locale-sensitive + * and have two versions: one that uses the default locale and one + * that takes a locale as an argument and displays the name or country in + * a language appropriate to that locale. + * + * <P> + * ICU provides a number of classes that perform locale-sensitive + * operations. For example, the <code>NumberFormat</code> class formats + * numbers, currency, or percentages in a locale-sensitive manner. Classes + * such as <code>NumberFormat</code> have a number of convenience methods + * for creating a default object of that type. For example, the + * <code>NumberFormat</code> class provides these three convenience methods + * for creating a default <code>NumberFormat</code> object: + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * UErrorCode success = U_ZERO_ERROR; + * Locale myLocale; + * NumberFormat *nf; + * + * nf = NumberFormat::createInstance( success ); delete nf; + * nf = NumberFormat::createCurrencyInstance( success ); delete nf; + * nf = NumberFormat::createPercentInstance( success ); delete nf; + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * Each of these methods has two variants; one with an explicit locale + * and one without; the latter using the default locale. + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * nf = NumberFormat::createInstance( myLocale, success ); delete nf; + * nf = NumberFormat::createCurrencyInstance( myLocale, success ); delete nf; + * nf = NumberFormat::createPercentInstance( myLocale, success ); delete nf; + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * A <code>Locale</code> is the mechanism for identifying the kind of object + * (<code>NumberFormat</code>) that you would like to get. The locale is + * <STRONG>just</STRONG> a mechanism for identifying objects, + * <STRONG>not</STRONG> a container for the objects themselves. + * + * <P> + * Each class that performs locale-sensitive operations allows you + * to get all the available objects of that type. You can sift + * through these objects by language, country, or variant, + * and use the display names to present a menu to the user. + * For example, you can create a menu of all the collation objects + * suitable for a given language. Such classes implement these + * three class methods: + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * static Locale* getAvailableLocales(int32_t& numLocales) + * static UnicodeString& getDisplayName(const Locale& objectLocale, + * const Locale& displayLocale, + * UnicodeString& displayName) + * static UnicodeString& getDisplayName(const Locale& objectLocale, + * UnicodeString& displayName) + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * + * @stable ICU 2.0 + * @see ResourceBundle + */ +U_NAMESPACE_BEGIN +class U_COMMON_API Locale : public UObject { +public: + /** Useful constant for this language. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getEnglish(void); + /** Useful constant for this language. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getFrench(void); + /** Useful constant for this language. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getGerman(void); + /** Useful constant for this language. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getItalian(void); + /** Useful constant for this language. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getJapanese(void); + /** Useful constant for this language. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getKorean(void); + /** Useful constant for this language. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getChinese(void); + /** Useful constant for this language. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getSimplifiedChinese(void); + /** Useful constant for this language. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getTraditionalChinese(void); + + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getFrance(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getGermany(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getItaly(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getJapan(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getKorea(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getChina(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getPRC(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getTaiwan(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getUK(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getUS(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getCanada(void); + /** Useful constant for this country/region. @stable ICU 2.0 */ + static const Locale &U_EXPORT2 getCanadaFrench(void); + + + /** + * Construct a default locale object, a Locale for the default locale ID. + * + * @see getDefault + * @see uloc_getDefault + * @stable ICU 2.0 + */ + Locale(); + + /** + * Construct a locale from language, country, variant. + * If an error occurs, then the constructed object will be "bogus" + * (isBogus() will return TRUE). + * + * @param language Lowercase two-letter or three-letter ISO-639 code. + * This parameter can instead be an ICU style C locale (e.g. "en_US"), + * but the other parameters must not be used. + * This parameter can be NULL; if so, + * the locale is initialized to match the current default locale. + * (This is the same as using the default constructor.) + * Please note: The Java Locale class does NOT accept the form + * 'new Locale("en_US")' but only 'new Locale("en","US")' + * + * @param country Uppercase two-letter ISO-3166 code. (optional) + * @param variant Uppercase vendor and browser specific code. See class + * description. (optional) + * @param keywordsAndValues A string consisting of keyword/values pairs, such as + * "collation=phonebook;currency=euro" + * + * @see getDefault + * @see uloc_getDefault + * @stable ICU 2.0 + */ + Locale( const char * language, + const char * country = 0, + const char * variant = 0, + const char * keywordsAndValues = 0); + + /** + * Initializes a Locale object from another Locale object. + * + * @param other The Locale object being copied in. + * @stable ICU 2.0 + */ + Locale(const Locale& other); + + + /** + * Destructor + * @stable ICU 2.0 + */ + virtual ~Locale() ; + + /** + * Replaces the entire contents of *this with the specified value. + * + * @param other The Locale object being copied in. + * @return *this + * @stable ICU 2.0 + */ + Locale& operator=(const Locale& other); + + /** + * Checks if two locale keys are the same. + * + * @param other The locale key object to be compared with this. + * @return True if the two locale keys are the same, false otherwise. + * @stable ICU 2.0 + */ + UBool operator==(const Locale& other) const; + + /** + * Checks if two locale keys are not the same. + * + * @param other The locale key object to be compared with this. + * @return True if the two locale keys are not the same, false + * otherwise. + * @stable ICU 2.0 + */ + UBool operator!=(const Locale& other) const; + + /** + * Clone this object. + * Clones can be used concurrently in multiple threads. + * If an error occurs, then NULL is returned. + * The caller must delete the clone. + * + * @return a clone of this object + * + * @see getDynamicClassID + * @stable ICU 2.8 + */ + Locale *clone() const; + + /** + * Common methods of getting the current default Locale. Used for the + * presentation: menus, dialogs, etc. Generally set once when your applet or + * application is initialized, then never reset. (If you do reset the + * default locale, you probably want to reload your GUI, so that the change + * is reflected in your interface.) + * + * More advanced programs will allow users to use different locales for + * different fields, e.g. in a spreadsheet. + * + * Note that the initial setting will match the host system. + * @return a reference to the Locale object for the default locale ID + * @system + * @stable ICU 2.0 + */ + static const Locale& U_EXPORT2 getDefault(void); + + /** + * Sets the default. Normally set once at the beginning of a process, + * then never reset. + * setDefault() only changes ICU's default locale ID, <strong>not</strong> + * the default locale ID of the runtime environment. + * + * @param newLocale Locale to set to. If NULL, set to the value obtained + * from the runtime environement. + * @param success The error code. + * @system + * @stable ICU 2.0 + */ + static void U_EXPORT2 setDefault(const Locale& newLocale, + UErrorCode& success); + + /** + * Creates a locale which has had minimal canonicalization + * as per uloc_getName(). + * @param name The name to create from. If name is null, + * the default Locale is used. + * @return new locale object + * @stable ICU 2.0 + * @see uloc_getName + */ + static Locale U_EXPORT2 createFromName(const char *name); + + /** + * Creates a locale from the given string after canonicalizing + * the string by calling uloc_canonicalize(). + * @param name the locale ID to create from. Must not be NULL. + * @return a new locale object corresponding to the given name + * @stable ICU 3.0 + * @see uloc_canonicalize + */ + static Locale U_EXPORT2 createCanonical(const char* name); + + /** + * Returns the locale's ISO-639 language code. + * @return An alias to the code + * @stable ICU 2.0 + */ + inline const char * getLanguage( ) const; + + /** + * Returns the locale's ISO-15924 abbreviation script code. + * @return An alias to the code + * @see uscript_getShortName + * @see uscript_getCode + * @stable ICU 2.8 + */ + inline const char * getScript( ) const; + + /** + * Returns the locale's ISO-3166 country code. + * @return An alias to the code + * @stable ICU 2.0 + */ + inline const char * getCountry( ) const; + + /** + * Returns the locale's variant code. + * @return An alias to the code + * @stable ICU 2.0 + */ + inline const char * getVariant( ) const; + + /** + * Returns the programmatic name of the entire locale, with the language, + * country and variant separated by underbars. If a field is missing, up + * to two leading underbars will occur. Example: "en", "de_DE", "en_US_WIN", + * "de__POSIX", "fr__MAC", "__MAC", "_MT", "_FR_EURO" + * @return A pointer to "name". + * @stable ICU 2.0 + */ + inline const char * getName() const; + + /** + * Returns the programmatic name of the entire locale as getName would return, + * but without keywords. + * @return A pointer to "name". + * @see getName + * @stable ICU 2.8 + */ + const char * getBaseName() const; + + + /** + * Gets the list of keywords for the specified locale. + * + * @return pointer to StringEnumeration class. Client must dispose of it by calling delete. + * @param status Returns any error information while performing this operation. + * @stable ICU 2.8 + */ + StringEnumeration * createKeywords(UErrorCode &status) const; + + /** + * Get the value for a keyword. + * + * @param keywordName name of the keyword for which we want the value. Case insensitive. + * @param status Returns any error information while performing this operation. + * @param buffer The buffer to receive the keyword value. + * @param bufferCapacity The capacity of receiving buffer + * @return the length of keyword value + * + * @stable ICU 2.8 + */ + int32_t getKeywordValue(const char* keywordName, char *buffer, int32_t bufferCapacity, UErrorCode &status) const; + + /** + * returns the locale's three-letter language code, as specified + * in ISO draft standard ISO-639-2. + * @return An alias to the code, or NULL + * @stable ICU 2.0 + */ + const char * getISO3Language() const; + + /** + * Fills in "name" with the locale's three-letter ISO-3166 country code. + * @return An alias to the code, or NULL + * @stable ICU 2.0 + */ + const char * getISO3Country() const; + + /** + * Returns the Windows LCID value corresponding to this locale. + * This value is stored in the resource data for the locale as a one-to-four-digit + * hexadecimal number. If the resource is missing, in the wrong format, or + * there is no Windows LCID value that corresponds to this locale, returns 0. + * @stable ICU 2.0 + */ + uint32_t getLCID(void) const; + + /** + * Fills in "dispLang" with the name of this locale's language in a format suitable for + * user display in the default locale. For example, if the locale's language code is + * "fr" and the default locale's language code is "en", this function would set + * dispLang to "French". + * @param dispLang Receives the language's display name. + * @return A reference to "dispLang". + * @stable ICU 2.0 + */ + UnicodeString& getDisplayLanguage(UnicodeString& dispLang) const; + + /** + * Fills in "dispLang" with the name of this locale's language in a format suitable for + * user display in the locale specified by "displayLocale". For example, if the locale's + * language code is "en" and displayLocale's language code is "fr", this function would set + * dispLang to "Anglais". + * @param displayLocale Specifies the locale to be used to display the name. In other words, + * if the locale's language code is "en", passing Locale::getFrench() for + * displayLocale would result in "Anglais", while passing Locale::getGerman() + * for displayLocale would result in "Englisch". + * @param dispLang Receives the language's display name. + * @return A reference to "dispLang". + * @stable ICU 2.0 + */ + UnicodeString& getDisplayLanguage( const Locale& displayLocale, + UnicodeString& dispLang) const; + + /** + * Fills in "dispScript" with the name of this locale's script in a format suitable + * for user display in the default locale. For example, if the locale's script code + * is "LATN" and the default locale's language code is "en", this function would set + * dispScript to "Latin". + * @param dispScript Receives the scripts's display name. + * @return A reference to "dispScript". + * @stable ICU 2.8 + */ + UnicodeString& getDisplayScript( UnicodeString& dispScript) const; + + /** + * Fills in "dispScript" with the name of this locale's country in a format suitable + * for user display in the locale specified by "displayLocale". For example, if the locale's + * script code is "LATN" and displayLocale's language code is "en", this function would set + * dispScript to "Latin". + * @param displayLocale Specifies the locale to be used to display the name. In other + * words, if the locale's script code is "LATN", passing + * Locale::getFrench() for displayLocale would result in "", while + * passing Locale::getGerman() for displayLocale would result in + * "". + * @param dispScript Receives the scripts's display name. + * @return A reference to "dispScript". + * @stable ICU 2.8 + */ + UnicodeString& getDisplayScript( const Locale& displayLocale, + UnicodeString& dispScript) const; + + /** + * Fills in "dispCountry" with the name of this locale's country in a format suitable + * for user display in the default locale. For example, if the locale's country code + * is "FR" and the default locale's language code is "en", this function would set + * dispCountry to "France". + * @param dispCountry Receives the country's display name. + * @return A reference to "dispCountry". + * @stable ICU 2.0 + */ + UnicodeString& getDisplayCountry( UnicodeString& dispCountry) const; + + /** + * Fills in "dispCountry" with the name of this locale's country in a format suitable + * for user display in the locale specified by "displayLocale". For example, if the locale's + * country code is "US" and displayLocale's language code is "fr", this function would set + * dispCountry to "États-Unis". + * @param displayLocale Specifies the locale to be used to display the name. In other + * words, if the locale's country code is "US", passing + * Locale::getFrench() for displayLocale would result in "États-Unis", while + * passing Locale::getGerman() for displayLocale would result in + * "Vereinigte Staaten". + * @param dispCountry Receives the country's display name. + * @return A reference to "dispCountry". + * @stable ICU 2.0 + */ + UnicodeString& getDisplayCountry( const Locale& displayLocale, + UnicodeString& dispCountry) const; + + /** + * Fills in "dispVar" with the name of this locale's variant code in a format suitable + * for user display in the default locale. + * @param dispVar Receives the variant's name. + * @return A reference to "dispVar". + * @stable ICU 2.0 + */ + UnicodeString& getDisplayVariant( UnicodeString& dispVar) const; + + /** + * Fills in "dispVar" with the name of this locale's variant code in a format + * suitable for user display in the locale specified by "displayLocale". + * @param displayLocale Specifies the locale to be used to display the name. + * @param dispVar Receives the variant's display name. + * @return A reference to "dispVar". + * @stable ICU 2.0 + */ + UnicodeString& getDisplayVariant( const Locale& displayLocale, + UnicodeString& dispVar) const; + + /** + * Fills in "name" with the name of this locale in a format suitable for user display + * in the default locale. This function uses getDisplayLanguage(), getDisplayCountry(), + * and getDisplayVariant() to do its work, and outputs the display name in the format + * "language (country[,variant])". For example, if the default locale is en_US, then + * fr_FR's display name would be "French (France)", and es_MX_Traditional's display name + * would be "Spanish (Mexico,Traditional)". + * @param name Receives the locale's display name. + * @return A reference to "name". + * @stable ICU 2.0 + */ + UnicodeString& getDisplayName( UnicodeString& name) const; + + /** + * Fills in "name" with the name of this locale in a format suitable for user display + * in the locale specfied by "displayLocale". This function uses getDisplayLanguage(), + * getDisplayCountry(), and getDisplayVariant() to do its work, and outputs the display + * name in the format "language (country[,variant])". For example, if displayLocale is + * fr_FR, then en_US's display name would be "Anglais (États-Unis)", and no_NO_NY's + * display name would be "norvégien (Norvège,NY)". + * @param displayLocale Specifies the locale to be used to display the name. + * @param name Receives the locale's display name. + * @return A reference to "name". + * @stable ICU 2.0 + */ + UnicodeString& getDisplayName( const Locale& displayLocale, + UnicodeString& name) const; + + /** + * Generates a hash code for the locale. + * @stable ICU 2.0 + */ + int32_t hashCode(void) const; + + /** + * Sets the locale to bogus + * A bogus locale represents a non-existing locale associated + * with services that can be instantiated from non-locale data + * in addition to locale (for example, collation can be + * instantiated from a locale and from a rule set). + * @stable ICU 2.1 + */ + void setToBogus(); + + /** + * Gets the bogus state. Locale object can be bogus if it doesn't exist + * @return FALSE if it is a real locale, TRUE if it is a bogus locale + * @stable ICU 2.1 + */ + UBool isBogus(void) const; + + /** + * Returns a list of all installed locales. + * @param count Receives the number of locales in the list. + * @return A pointer to an array of Locale objects. This array is the list + * of all locales with installed resource files. The called does NOT + * get ownership of this list, and must NOT delete it. + * @stable ICU 2.0 + */ + static const Locale* U_EXPORT2 getAvailableLocales(int32_t& count); + + /** + * Gets a list of all available 2-letter country codes defined in ISO 639. This is a + * pointer to an array of pointers to arrays of char. All of these pointers are + * owned by ICU-- do not delete them, and do not write through them. The array is + * terminated with a null pointer. + * @return a list of all available country codes + * @stable ICU 2.0 + */ + static const char* const* U_EXPORT2 getISOCountries(); + + /** + * Gets a list of all available language codes defined in ISO 639. This is a pointer + * to an array of pointers to arrays of char. All of these pointers are owned + * by ICU-- do not delete them, and do not write through them. The array is + * terminated with a null pointer. + * @return a list of all available language codes + * @stable ICU 2.0 + */ + static const char* const* U_EXPORT2 getISOLanguages(); + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.2 + */ + static UClassID U_EXPORT2 getStaticClassID(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.2 + */ + virtual UClassID getDynamicClassID() const; + +protected: /* only protected for testing purposes. DO NOT USE. */ + /** + * Set this from a single POSIX style locale string. + * @internal + */ + void setFromPOSIXID(const char *posixID); + +private: + /** + * Initialize the locale object with a new name. + * Was deprecated - used in implementation - moved internal + * + * @param cLocaleID The new locale name. + */ + Locale& init(const char* cLocaleID, UBool canonicalize); + + /* + * Internal constructor to allow construction of a locale object with + * NO side effects. (Default constructor tries to get + * the default locale.) + */ + enum ELocaleType { + eBOGUS + }; + Locale(ELocaleType); + + /** + * Initialize the locale cache for commonly used locales + */ + static Locale *getLocaleCache(void); + + char language[ULOC_LANG_CAPACITY]; + char script[ULOC_SCRIPT_CAPACITY]; + char country[ULOC_COUNTRY_CAPACITY]; + int32_t variantBegin; + char* fullName; + char fullNameBuffer[ULOC_FULLNAME_CAPACITY]; + // name without keywords + char* baseName; + char baseNameBuffer[ULOC_FULLNAME_CAPACITY]; + + UBool fIsBogus; + + static const Locale &getLocale(int locid); + + /** + * A friend to allow the default locale to be set by either the C or C++ API. + * @internal + */ + friend void locale_set_default_internal(const char *); +}; + +inline UBool +Locale::operator!=(const Locale& other) const +{ + return !operator==(other); +} + +inline const char * +Locale::getCountry() const +{ + return country; +} + +inline const char * +Locale::getLanguage() const +{ + return language; +} + +inline const char * +Locale::getScript() const +{ + return script; +} + +inline const char * +Locale::getVariant() const +{ + return &fullName[variantBegin]; +} + +inline const char * +Locale::getName() const +{ + return fullName; +} + +inline UBool +Locale::isBogus(void) const { + return fIsBogus; +} + +U_NAMESPACE_END + +#endif + diff --git a/utils/openttd/unicode/normlzr.h b/utils/openttd/unicode/normlzr.h new file mode 100644 index 00000000000..7974f1ac4dd --- /dev/null +++ b/utils/openttd/unicode/normlzr.h @@ -0,0 +1,823 @@ +/* + ******************************************************************** + * COPYRIGHT: + * Copyright (c) 1996-2006, International Business Machines Corporation and + * others. All Rights Reserved. + ******************************************************************** + */ + +#ifndef NORMLZR_H +#define NORMLZR_H + +#include "unicode/utypes.h" + +/** + * \file + * \brief C++ API: Unicode Normalization + */ + +#if !UCONFIG_NO_NORMALIZATION + +#include "unicode/uobject.h" +#include "unicode/unistr.h" +#include "unicode/chariter.h" +#include "unicode/unorm.h" + + +struct UCharIterator; +typedef struct UCharIterator UCharIterator; /**< C typedef for struct UCharIterator. @stable ICU 2.1 */ + +U_NAMESPACE_BEGIN +/** + * The Normalizer class supports the standard normalization forms described in + * <a href="http://www.unicode.org/unicode/reports/tr15/" target="unicode"> + * Unicode Standard Annex #15: Unicode Normalization Forms</a>. + * + * The Normalizer class consists of two parts: + * - static functions that normalize strings or test if strings are normalized + * - a Normalizer object is an iterator that takes any kind of text and + * provides iteration over its normalized form + * + * The Normalizer class is not suitable for subclassing. + * + * The static functions are basically wrappers around the C implementation, + * using UnicodeString instead of UChar*. + * For basic information about normalization forms and details about the C API + * please see the documentation in unorm.h. + * + * The iterator API with the Normalizer constructors and the non-static functions + * uses a CharacterIterator as input. It is possible to pass a string which + * is then internally wrapped in a CharacterIterator. + * The input text is not normalized all at once, but incrementally where needed + * (providing efficient random access). + * This allows to pass in a large text but spend only a small amount of time + * normalizing a small part of that text. + * However, if the entire text is normalized, then the iterator will be + * slower than normalizing the entire text at once and iterating over the result. + * A possible use of the Normalizer iterator is also to report an index into the + * original text that is close to where the normalized characters come from. + * + * <em>Important:</em> The iterator API was cleaned up significantly for ICU 2.0. + * The earlier implementation reported the getIndex() inconsistently, + * and previous() could not be used after setIndex(), next(), first(), and current(). + * + * Normalizer allows to start normalizing from anywhere in the input text by + * calling setIndexOnly(), first(), or last(). + * Without calling any of these, the iterator will start at the beginning of the text. + * + * At any time, next() returns the next normalized code point (UChar32), + * with post-increment semantics (like CharacterIterator::next32PostInc()). + * previous() returns the previous normalized code point (UChar32), + * with pre-decrement semantics (like CharacterIterator::previous32()). + * + * current() returns the current code point + * (respectively the one at the newly set index) without moving + * the getIndex(). Note that if the text at the current position + * needs to be normalized, then these functions will do that. + * (This is why current() is not const.) + * It is more efficient to call setIndexOnly() instead, which does not + * normalize. + * + * getIndex() always refers to the position in the input text where the normalized + * code points are returned from. It does not always change with each returned + * code point. + * The code point that is returned from any of the functions + * corresponds to text at or after getIndex(), according to the + * function's iteration semantics (post-increment or pre-decrement). + * + * next() returns a code point from at or after the getIndex() + * from before the next() call. After the next() call, the getIndex() + * might have moved to where the next code point will be returned from + * (from a next() or current() call). + * This is semantically equivalent to array access with array[index++] + * (post-increment semantics). + * + * previous() returns a code point from at or after the getIndex() + * from after the previous() call. + * This is semantically equivalent to array access with array[--index] + * (pre-decrement semantics). + * + * Internally, the Normalizer iterator normalizes a small piece of text + * starting at the getIndex() and ending at a following "safe" index. + * The normalized results is stored in an internal string buffer, and + * the code points are iterated from there. + * With multiple iteration calls, this is repeated until the next piece + * of text needs to be normalized, and the getIndex() needs to be moved. + * + * The following "safe" index, the internal buffer, and the secondary + * iteration index into that buffer are not exposed on the API. + * This also means that it is currently not practical to return to + * a particular, arbitrary position in the text because one would need to + * know, and be able to set, in addition to the getIndex(), at least also the + * current index into the internal buffer. + * It is currently only possible to observe when getIndex() changes + * (with careful consideration of the iteration semantics), + * at which time the internal index will be 0. + * For example, if getIndex() is different after next() than before it, + * then the internal index is 0 and one can return to this getIndex() + * later with setIndexOnly(). + * + * @author Laura Werner, Mark Davis, Markus Scherer + * @stable ICU 2.0 + */ +class U_COMMON_API Normalizer : public UObject { +public: + /** + * If DONE is returned from an iteration function that returns a code point, + * then there are no more normalization results available. + * @stable ICU 2.0 + */ + enum { + DONE=0xffff + }; + + // Constructors + + /** + * Creates a new <code>Normalizer</code> object for iterating over the + * normalized form of a given string. + * <p> + * @param str The string to be normalized. The normalization + * will start at the beginning of the string. + * + * @param mode The normalization mode. + * @stable ICU 2.0 + */ + Normalizer(const UnicodeString& str, UNormalizationMode mode); + + /** + * Creates a new <code>Normalizer</code> object for iterating over the + * normalized form of a given string. + * <p> + * @param str The string to be normalized. The normalization + * will start at the beginning of the string. + * + * @param length Length of the string, or -1 if NUL-terminated. + * @param mode The normalization mode. + * @stable ICU 2.0 + */ + Normalizer(const UChar* str, int32_t length, UNormalizationMode mode); + + /** + * Creates a new <code>Normalizer</code> object for iterating over the + * normalized form of the given text. + * <p> + * @param iter The input text to be normalized. The normalization + * will start at the beginning of the string. + * + * @param mode The normalization mode. + * @stable ICU 2.0 + */ + Normalizer(const CharacterIterator& iter, UNormalizationMode mode); + + /** + * Copy constructor. + * @param copy The object to be copied. + * @stable ICU 2.0 + */ + Normalizer(const Normalizer& copy); + + /** + * Destructor + * @stable ICU 2.0 + */ + virtual ~Normalizer(); + + + //------------------------------------------------------------------------- + // Static utility methods + //------------------------------------------------------------------------- + + /** + * Normalizes a <code>UnicodeString</code> according to the specified normalization mode. + * This is a wrapper for unorm_normalize(), using UnicodeString's. + * + * The <code>options</code> parameter specifies which optional + * <code>Normalizer</code> features are to be enabled for this operation. + * + * @param source the input string to be normalized. + * @param mode the normalization mode + * @param options the optional features to be enabled (0 for no options) + * @param result The normalized string (on output). + * @param status The error code. + * @stable ICU 2.0 + */ + static void U_EXPORT2 normalize(const UnicodeString& source, + UNormalizationMode mode, int32_t options, + UnicodeString& result, + UErrorCode &status); + + /** + * Compose a <code>UnicodeString</code>. + * This is equivalent to normalize() with mode UNORM_NFC or UNORM_NFKC. + * This is a wrapper for unorm_normalize(), using UnicodeString's. + * + * The <code>options</code> parameter specifies which optional + * <code>Normalizer</code> features are to be enabled for this operation. + * + * @param source the string to be composed. + * @param compat Perform compatibility decomposition before composition. + * If this argument is <code>FALSE</code>, only canonical + * decomposition will be performed. + * @param options the optional features to be enabled (0 for no options) + * @param result The composed string (on output). + * @param status The error code. + * @stable ICU 2.0 + */ + static void U_EXPORT2 compose(const UnicodeString& source, + UBool compat, int32_t options, + UnicodeString& result, + UErrorCode &status); + + /** + * Static method to decompose a <code>UnicodeString</code>. + * This is equivalent to normalize() with mode UNORM_NFD or UNORM_NFKD. + * This is a wrapper for unorm_normalize(), using UnicodeString's. + * + * The <code>options</code> parameter specifies which optional + * <code>Normalizer</code> features are to be enabled for this operation. + * + * @param source the string to be decomposed. + * @param compat Perform compatibility decomposition. + * If this argument is <code>FALSE</code>, only canonical + * decomposition will be performed. + * @param options the optional features to be enabled (0 for no options) + * @param result The decomposed string (on output). + * @param status The error code. + * @stable ICU 2.0 + */ + static void U_EXPORT2 decompose(const UnicodeString& source, + UBool compat, int32_t options, + UnicodeString& result, + UErrorCode &status); + + /** + * Performing quick check on a string, to quickly determine if the string is + * in a particular normalization format. + * This is a wrapper for unorm_quickCheck(), using a UnicodeString. + * + * Three types of result can be returned UNORM_YES, UNORM_NO or + * UNORM_MAYBE. Result UNORM_YES indicates that the argument + * string is in the desired normalized format, UNORM_NO determines that + * argument string is not in the desired normalized format. A + * UNORM_MAYBE result indicates that a more thorough check is required, + * the user may have to put the string in its normalized form and compare the + * results. + * @param source string for determining if it is in a normalized format + * @param mode normalization format + * @param status A reference to a UErrorCode to receive any errors + * @return UNORM_YES, UNORM_NO or UNORM_MAYBE + * + * @see isNormalized + * @stable ICU 2.0 + */ + static inline UNormalizationCheckResult + quickCheck(const UnicodeString &source, UNormalizationMode mode, UErrorCode &status); + + /** + * Performing quick check on a string; same as the other version of quickCheck + * but takes an extra options parameter like most normalization functions. + * + * @param source string for determining if it is in a normalized format + * @param mode normalization format + * @param options the optional features to be enabled (0 for no options) + * @param status A reference to a UErrorCode to receive any errors + * @return UNORM_YES, UNORM_NO or UNORM_MAYBE + * + * @see isNormalized + * @stable ICU 2.6 + */ + static inline UNormalizationCheckResult + quickCheck(const UnicodeString &source, UNormalizationMode mode, int32_t options, UErrorCode &status); + + /** + * Test if a string is in a given normalization form. + * This is semantically equivalent to source.equals(normalize(source, mode)) . + * + * Unlike unorm_quickCheck(), this function returns a definitive result, + * never a "maybe". + * For NFD, NFKD, and FCD, both functions work exactly the same. + * For NFC and NFKC where quickCheck may return "maybe", this function will + * perform further tests to arrive at a TRUE/FALSE result. + * + * @param src String that is to be tested if it is in a normalization format. + * @param mode Which normalization form to test for. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Boolean value indicating whether the source string is in the + * "mode" normalization form. + * + * @see quickCheck + * @stable ICU 2.2 + */ + static inline UBool + isNormalized(const UnicodeString &src, UNormalizationMode mode, UErrorCode &errorCode); + + /** + * Test if a string is in a given normalization form; same as the other version of isNormalized + * but takes an extra options parameter like most normalization functions. + * + * @param src String that is to be tested if it is in a normalization format. + * @param mode Which normalization form to test for. + * @param options the optional features to be enabled (0 for no options) + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Boolean value indicating whether the source string is in the + * "mode" normalization form. + * + * @see quickCheck + * @stable ICU 2.6 + */ + static inline UBool + isNormalized(const UnicodeString &src, UNormalizationMode mode, int32_t options, UErrorCode &errorCode); + + /** + * Concatenate normalized strings, making sure that the result is normalized as well. + * + * If both the left and the right strings are in + * the normalization form according to "mode/options", + * then the result will be + * + * \code + * dest=normalize(left+right, mode, options) + * \endcode + * + * For details see unorm_concatenate in unorm.h. + * + * @param left Left source string. + * @param right Right source string. + * @param result The output string. + * @param mode The normalization mode. + * @param options A bit set of normalization options. + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return result + * + * @see unorm_concatenate + * @see normalize + * @see unorm_next + * @see unorm_previous + * + * @stable ICU 2.1 + */ + static UnicodeString & + U_EXPORT2 concatenate(UnicodeString &left, UnicodeString &right, + UnicodeString &result, + UNormalizationMode mode, int32_t options, + UErrorCode &errorCode); + + /** + * Compare two strings for canonical equivalence. + * Further options include case-insensitive comparison and + * code point order (as opposed to code unit order). + * + * Canonical equivalence between two strings is defined as their normalized + * forms (NFD or NFC) being identical. + * This function compares strings incrementally instead of normalizing + * (and optionally case-folding) both strings entirely, + * improving performance significantly. + * + * Bulk normalization is only necessary if the strings do not fulfill the FCD + * conditions. Only in this case, and only if the strings are relatively long, + * is memory allocated temporarily. + * For FCD strings and short non-FCD strings there is no memory allocation. + * + * Semantically, this is equivalent to + * strcmp[CodePointOrder](NFD(foldCase(s1)), NFD(foldCase(s2))) + * where code point order and foldCase are all optional. + * + * UAX 21 2.5 Caseless Matching specifies that for a canonical caseless match + * the case folding must be performed first, then the normalization. + * + * @param s1 First source string. + * @param s2 Second source string. + * + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Case-sensitive comparison in code unit order, and the input strings + * are quick-checked for FCD. + * + * - UNORM_INPUT_IS_FCD + * Set if the caller knows that both s1 and s2 fulfill the FCD conditions. + * If not set, the function will quickCheck for FCD + * and normalize if necessary. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_COMPARE_IGNORE_CASE + * Set to compare strings case-insensitively using case folding, + * instead of case-sensitively. + * If set, then the following case folding options are used. + * + * - Options as used with case-insensitive comparisons, currently: + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * (see u_strCaseCompare for details) + * + * - regular normalization options shifted left by UNORM_COMPARE_NORM_OPTIONS_SHIFT + * + * @param errorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return <0 or 0 or >0 as usual for string comparisons + * + * @see unorm_compare + * @see normalize + * @see UNORM_FCD + * @see u_strCompare + * @see u_strCaseCompare + * + * @stable ICU 2.2 + */ + static inline int32_t + compare(const UnicodeString &s1, const UnicodeString &s2, + uint32_t options, + UErrorCode &errorCode); + + //------------------------------------------------------------------------- + // Iteration API + //------------------------------------------------------------------------- + + /** + * Return the current character in the normalized text. + * current() may need to normalize some text at getIndex(). + * The getIndex() is not changed. + * + * @return the current normalized code point + * @stable ICU 2.0 + */ + UChar32 current(void); + + /** + * Return the first character in the normalized text. + * This is equivalent to setIndexOnly(startIndex()) followed by next(). + * (Post-increment semantics.) + * + * @return the first normalized code point + * @stable ICU 2.0 + */ + UChar32 first(void); + + /** + * Return the last character in the normalized text. + * This is equivalent to setIndexOnly(endIndex()) followed by previous(). + * (Pre-decrement semantics.) + * + * @return the last normalized code point + * @stable ICU 2.0 + */ + UChar32 last(void); + + /** + * Return the next character in the normalized text. + * (Post-increment semantics.) + * If the end of the text has already been reached, DONE is returned. + * The DONE value could be confused with a U+FFFF non-character code point + * in the text. If this is possible, you can test getIndex()<endIndex() + * before calling next(), or (getIndex()<endIndex() || last()!=DONE) + * after calling next(). (Calling last() will change the iterator state!) + * + * The C API unorm_next() is more efficient and does not have this ambiguity. + * + * @return the next normalized code point + * @stable ICU 2.0 + */ + UChar32 next(void); + + /** + * Return the previous character in the normalized text and decrement. + * (Pre-decrement semantics.) + * If the beginning of the text has already been reached, DONE is returned. + * The DONE value could be confused with a U+FFFF non-character code point + * in the text. If this is possible, you can test + * (getIndex()>startIndex() || first()!=DONE). (Calling first() will change + * the iterator state!) + * + * The C API unorm_previous() is more efficient and does not have this ambiguity. + * + * @return the previous normalized code point + * @stable ICU 2.0 + */ + UChar32 previous(void); + + /** + * Set the iteration position in the input text that is being normalized, + * without any immediate normalization. + * After setIndexOnly(), getIndex() will return the same index that is + * specified here. + * + * @param index the desired index in the input text. + * @stable ICU 2.0 + */ + void setIndexOnly(int32_t index); + + /** + * Reset the index to the beginning of the text. + * This is equivalent to setIndexOnly(startIndex)). + * @stable ICU 2.0 + */ + void reset(void); + + /** + * Retrieve the current iteration position in the input text that is + * being normalized. + * + * A following call to next() will return a normalized code point from + * the input text at or after this index. + * + * After a call to previous(), getIndex() will point at or before the + * position in the input text where the normalized code point + * was returned from with previous(). + * + * @return the current index in the input text + * @stable ICU 2.0 + */ + int32_t getIndex(void) const; + + /** + * Retrieve the index of the start of the input text. This is the begin index + * of the <code>CharacterIterator</code> or the start (i.e. index 0) of the string + * over which this <code>Normalizer</code> is iterating. + * + * @return the smallest index in the input text where the Normalizer operates + * @stable ICU 2.0 + */ + int32_t startIndex(void) const; + + /** + * Retrieve the index of the end of the input text. This is the end index + * of the <code>CharacterIterator</code> or the length of the string + * over which this <code>Normalizer</code> is iterating. + * This end index is exclusive, i.e., the Normalizer operates only on characters + * before this index. + * + * @return the first index in the input text where the Normalizer does not operate + * @stable ICU 2.0 + */ + int32_t endIndex(void) const; + + /** + * Returns TRUE when both iterators refer to the same character in the same + * input text. + * + * @param that a Normalizer object to compare this one to + * @return comparison result + * @stable ICU 2.0 + */ + UBool operator==(const Normalizer& that) const; + + /** + * Returns FALSE when both iterators refer to the same character in the same + * input text. + * + * @param that a Normalizer object to compare this one to + * @return comparison result + * @stable ICU 2.0 + */ + inline UBool operator!=(const Normalizer& that) const; + + /** + * Returns a pointer to a new Normalizer that is a clone of this one. + * The caller is responsible for deleting the new clone. + * @return a pointer to a new Normalizer + * @stable ICU 2.0 + */ + Normalizer* clone(void) const; + + /** + * Generates a hash code for this iterator. + * + * @return the hash code + * @stable ICU 2.0 + */ + int32_t hashCode(void) const; + + //------------------------------------------------------------------------- + // Property access methods + //------------------------------------------------------------------------- + + /** + * Set the normalization mode for this object. + * <p> + * <b>Note:</b>If the normalization mode is changed while iterating + * over a string, calls to {@link #next() } and {@link #previous() } may + * return previously buffers characters in the old normalization mode + * until the iteration is able to re-sync at the next base character. + * It is safest to call {@link #setIndexOnly }, {@link #reset() }, + * {@link #setText }, {@link #first() }, + * {@link #last() }, etc. after calling <code>setMode</code>. + * <p> + * @param newMode the new mode for this <code>Normalizer</code>. + * @see #getUMode + * @stable ICU 2.0 + */ + void setMode(UNormalizationMode newMode); + + /** + * Return the normalization mode for this object. + * + * This is an unusual name because there used to be a getMode() that + * returned a different type. + * + * @return the mode for this <code>Normalizer</code> + * @see #setMode + * @stable ICU 2.0 + */ + UNormalizationMode getUMode(void) const; + + /** + * Set options that affect this <code>Normalizer</code>'s operation. + * Options do not change the basic composition or decomposition operation + * that is being performed, but they control whether + * certain optional portions of the operation are done. + * Currently the only available option is obsolete. + * + * It is possible to specify multiple options that are all turned on or off. + * + * @param option the option(s) whose value is/are to be set. + * @param value the new setting for the option. Use <code>TRUE</code> to + * turn the option(s) on and <code>FALSE</code> to turn it/them off. + * + * @see #getOption + * @stable ICU 2.0 + */ + void setOption(int32_t option, + UBool value); + + /** + * Determine whether an option is turned on or off. + * If multiple options are specified, then the result is TRUE if any + * of them are set. + * <p> + * @param option the option(s) that are to be checked + * @return TRUE if any of the option(s) are set + * @see #setOption + * @stable ICU 2.0 + */ + UBool getOption(int32_t option) const; + + /** + * Set the input text over which this <code>Normalizer</code> will iterate. + * The iteration position is set to the beginning. + * + * @param newText a string that replaces the current input text + * @param status a UErrorCode + * @stable ICU 2.0 + */ + void setText(const UnicodeString& newText, + UErrorCode &status); + + /** + * Set the input text over which this <code>Normalizer</code> will iterate. + * The iteration position is set to the beginning. + * + * @param newText a CharacterIterator object that replaces the current input text + * @param status a UErrorCode + * @stable ICU 2.0 + */ + void setText(const CharacterIterator& newText, + UErrorCode &status); + + /** + * Set the input text over which this <code>Normalizer</code> will iterate. + * The iteration position is set to the beginning. + * + * @param newText a string that replaces the current input text + * @param length the length of the string, or -1 if NUL-terminated + * @param status a UErrorCode + * @stable ICU 2.0 + */ + void setText(const UChar* newText, + int32_t length, + UErrorCode &status); + /** + * Copies the input text into the UnicodeString argument. + * + * @param result Receives a copy of the text under iteration. + * @stable ICU 2.0 + */ + void getText(UnicodeString& result); + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * @returns a UClassID for this class. + * @stable ICU 2.2 + */ + static UClassID U_EXPORT2 getStaticClassID(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * @return a UClassID for the actual class. + * @stable ICU 2.2 + */ + virtual UClassID getDynamicClassID() const; + +private: + //------------------------------------------------------------------------- + // Private functions + //------------------------------------------------------------------------- + + Normalizer(); // default constructor not implemented + Normalizer &operator=(const Normalizer &that); // assignment operator not implemented + + // Private utility methods for iteration + // For documentation, see the source code + UBool nextNormalize(); + UBool previousNormalize(); + + void init(CharacterIterator *iter); + void clearBuffer(void); + + //------------------------------------------------------------------------- + // Private data + //------------------------------------------------------------------------- + + UNormalizationMode fUMode; + int32_t fOptions; + + // The input text and our position in it + UCharIterator *text; + + // The normalization buffer is the result of normalization + // of the source in [currentIndex..nextIndex[ . + int32_t currentIndex, nextIndex; + + // A buffer for holding intermediate results + UnicodeString buffer; + int32_t bufferPos; + +}; + +//------------------------------------------------------------------------- +// Inline implementations +//------------------------------------------------------------------------- + +inline UBool +Normalizer::operator!= (const Normalizer& other) const +{ return ! operator==(other); } + +inline UNormalizationCheckResult +Normalizer::quickCheck(const UnicodeString& source, + UNormalizationMode mode, + UErrorCode &status) { + if(U_FAILURE(status)) { + return UNORM_MAYBE; + } + + return unorm_quickCheck(source.getBuffer(), source.length(), + mode, &status); +} + +inline UNormalizationCheckResult +Normalizer::quickCheck(const UnicodeString& source, + UNormalizationMode mode, int32_t options, + UErrorCode &status) { + if(U_FAILURE(status)) { + return UNORM_MAYBE; + } + + return unorm_quickCheckWithOptions(source.getBuffer(), source.length(), + mode, options, &status); +} + +inline UBool +Normalizer::isNormalized(const UnicodeString& source, + UNormalizationMode mode, + UErrorCode &status) { + if(U_FAILURE(status)) { + return FALSE; + } + + return unorm_isNormalized(source.getBuffer(), source.length(), + mode, &status); +} + +inline UBool +Normalizer::isNormalized(const UnicodeString& source, + UNormalizationMode mode, int32_t options, + UErrorCode &status) { + if(U_FAILURE(status)) { + return FALSE; + } + + return unorm_isNormalizedWithOptions(source.getBuffer(), source.length(), + mode, options, &status); +} + +inline int32_t +Normalizer::compare(const UnicodeString &s1, const UnicodeString &s2, + uint32_t options, + UErrorCode &errorCode) { + // all argument checking is done in unorm_compare + return unorm_compare(s1.getBuffer(), s1.length(), + s2.getBuffer(), s2.length(), + options, + &errorCode); +} + +U_NAMESPACE_END + +#endif /* #if !UCONFIG_NO_NORMALIZATION */ + +#endif // NORMLZR_H diff --git a/utils/openttd/unicode/parseerr.h b/utils/openttd/unicode/parseerr.h new file mode 100644 index 00000000000..44ff00811de --- /dev/null +++ b/utils/openttd/unicode/parseerr.h @@ -0,0 +1,92 @@ +/* +********************************************************************** +* Copyright (C) 1999-2005, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* Date Name Description +* 03/14/00 aliu Creation. +* 06/27/00 aliu Change from C++ class to C struct +********************************************************************** +*/ +#ifndef PARSEERR_H +#define PARSEERR_H + +#include "unicode/utypes.h" + + +/** + * \file + * \brief C API: Parse Error Information + */ +/** + * The capacity of the context strings in UParseError. + * @stable ICU 2.0 + */ +enum { U_PARSE_CONTEXT_LEN = 16 }; + +/** + * A UParseError struct is used to returned detailed information about + * parsing errors. It is used by ICU parsing engines that parse long + * rules, patterns, or programs, where the text being parsed is long + * enough that more information than a UErrorCode is needed to + * localize the error. + * + * <p>The line, offset, and context fields are optional; parsing + * engines may choose not to use to use them. + * + * <p>The preContext and postContext strings include some part of the + * context surrounding the error. If the source text is "let for=7" + * and "for" is the error (e.g., because it is a reserved word), then + * some examples of what a parser might produce are the following: + * + * <pre> + * preContext postContext + * "" "" The parser does not support context + * "let " "=7" Pre- and post-context only + * "let " "for=7" Pre- and post-context and error text + * "" "for" Error text only + * </pre> + * + * <p>Examples of engines which use UParseError (or may use it in the + * future) are Transliterator, RuleBasedBreakIterator, and + * RegexPattern. + * + * @stable ICU 2.0 + */ +typedef struct UParseError { + + /** + * The line on which the error occured. If the parser uses this + * field, it sets it to the line number of the source text line on + * which the error appears, which will be be a value >= 1. If the + * parse does not support line numbers, the value will be <= 0. + * @stable ICU 2.0 + */ + int32_t line; + + /** + * The character offset to the error. If the line field is >= 1, + * then this is the offset from the start of the line. Otherwise, + * this is the offset from the start of the text. If the parser + * does not support this field, it will have a value < 0. + * @stable ICU 2.0 + */ + int32_t offset; + + /** + * Textual context before the error. Null-terminated. The empty + * string if not supported by parser. + * @stable ICU 2.0 + */ + UChar preContext[U_PARSE_CONTEXT_LEN]; + + /** + * The error itself and/or textual context after the error. + * Null-terminated. The empty string if not supported by parser. + * @stable ICU 2.0 + */ + UChar postContext[U_PARSE_CONTEXT_LEN]; + +} UParseError; + +#endif diff --git a/utils/openttd/unicode/parsepos.h b/utils/openttd/unicode/parsepos.h new file mode 100644 index 00000000000..cdf49e04ec2 --- /dev/null +++ b/utils/openttd/unicode/parsepos.h @@ -0,0 +1,230 @@ +/* +* Copyright (C) 1997-2005, International Business Machines Corporation and others. All Rights Reserved. +******************************************************************************* +* +* File PARSEPOS.H +* +* Modification History: +* +* Date Name Description +* 07/09/97 helena Converted from java. +* 07/17/98 stephen Added errorIndex support. +* 05/11/99 stephen Cleaned up. +******************************************************************************* +*/ + +#ifndef PARSEPOS_H +#define PARSEPOS_H + +#include "unicode/utypes.h" +#include "unicode/uobject.h" + + +U_NAMESPACE_BEGIN + +/** + * \file + * \brief C++ API: Canonical Iterator + */ +/** + * <code>ParsePosition</code> is a simple class used by <code>Format</code> + * and its subclasses to keep track of the current position during parsing. + * The <code>parseObject</code> method in the various <code>Format</code> + * classes requires a <code>ParsePosition</code> object as an argument. + * + * <p> + * By design, as you parse through a string with different formats, + * you can use the same <code>ParsePosition</code>, since the index parameter + * records the current position. + * + * The ParsePosition class is not suitable for subclassing. + * + * @version 1.3 10/30/97 + * @author Mark Davis, Helena Shih + * @see java.text.Format + */ + +class U_COMMON_API ParsePosition : public UObject { +public: + /** + * Default constructor, the index starts with 0 as default. + * @stable ICU 2.0 + */ + ParsePosition() + : UObject(), + index(0), + errorIndex(-1) + {} + + /** + * Create a new ParsePosition with the given initial index. + * @param newIndex the new text offset. + * @stable ICU 2.0 + */ + ParsePosition(int32_t newIndex) + : UObject(), + index(newIndex), + errorIndex(-1) + {} + + /** + * Copy constructor + * @param copy the object to be copied from. + * @stable ICU 2.0 + */ + ParsePosition(const ParsePosition& copy) + : UObject(copy), + index(copy.index), + errorIndex(copy.errorIndex) + {} + + /** + * Destructor + * @stable ICU 2.0 + */ + virtual ~ParsePosition(); + + /** + * Assignment operator + * @stable ICU 2.0 + */ + ParsePosition& operator=(const ParsePosition& copy); + + /** + * Equality operator. + * @return TRUE if the two parse positions are equal, FALSE otherwise. + * @stable ICU 2.0 + */ + UBool operator==(const ParsePosition& that) const; + + /** + * Equality operator. + * @return TRUE if the two parse positions are not equal, FALSE otherwise. + * @stable ICU 2.0 + */ + UBool operator!=(const ParsePosition& that) const; + + /** + * Clone this object. + * Clones can be used concurrently in multiple threads. + * If an error occurs, then NULL is returned. + * The caller must delete the clone. + * + * @return a clone of this object + * + * @see getDynamicClassID + * @stable ICU 2.8 + */ + ParsePosition *clone() const; + + /** + * Retrieve the current parse position. On input to a parse method, this + * is the index of the character at which parsing will begin; on output, it + * is the index of the character following the last character parsed. + * @return the current index. + * @stable ICU 2.0 + */ + int32_t getIndex(void) const; + + /** + * Set the current parse position. + * @param index the new index. + * @stable ICU 2.0 + */ + void setIndex(int32_t index); + + /** + * Set the index at which a parse error occurred. Formatters + * should set this before returning an error code from their + * parseObject method. The default value is -1 if this is not + * set. + * @stable ICU 2.0 + */ + void setErrorIndex(int32_t ei); + + /** + * Retrieve the index at which an error occurred, or -1 if the + * error index has not been set. + * @stable ICU 2.0 + */ + int32_t getErrorIndex(void) const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.2 + */ + static UClassID U_EXPORT2 getStaticClassID(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.2 + */ + virtual UClassID getDynamicClassID() const; + +private: + /** + * Input: the place you start parsing. + * <br>Output: position where the parse stopped. + * This is designed to be used serially, + * with each call setting index up for the next one. + */ + int32_t index; + + /** + * The index at which a parse error occurred. + */ + int32_t errorIndex; + +}; + +inline ParsePosition& +ParsePosition::operator=(const ParsePosition& copy) +{ + index = copy.index; + errorIndex = copy.errorIndex; + return *this; +} + +inline UBool +ParsePosition::operator==(const ParsePosition& copy) const +{ + if(index != copy.index || errorIndex != copy.errorIndex) + return FALSE; + else + return TRUE; +} + +inline UBool +ParsePosition::operator!=(const ParsePosition& copy) const +{ + return !operator==(copy); +} + +inline int32_t +ParsePosition::getIndex() const +{ + return index; +} + +inline void +ParsePosition::setIndex(int32_t offset) +{ + this->index = offset; +} + +inline int32_t +ParsePosition::getErrorIndex() const +{ + return errorIndex; +} + +inline void +ParsePosition::setErrorIndex(int32_t ei) +{ + this->errorIndex = ei; +} +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/putil.h b/utils/openttd/unicode/putil.h new file mode 100644 index 00000000000..330487788f4 --- /dev/null +++ b/utils/openttd/unicode/putil.h @@ -0,0 +1,184 @@ +/* +****************************************************************************** +* +* Copyright (C) 1997-2008, International Business Machines +* Corporation and others. All Rights Reserved. +* +****************************************************************************** +* +* FILE NAME : putil.h +* +* Date Name Description +* 05/14/98 nos Creation (content moved here from utypes.h). +* 06/17/99 erm Added IEEE_754 +* 07/22/98 stephen Added IEEEremainder, max, min, trunc +* 08/13/98 stephen Added isNegativeInfinity, isPositiveInfinity +* 08/24/98 stephen Added longBitsFromDouble +* 03/02/99 stephen Removed openFile(). Added AS400 support. +* 04/15/99 stephen Converted to C +* 11/15/99 helena Integrated S/390 changes for IEEE support. +* 01/11/00 helena Added u_getVersion. +****************************************************************************** +*/ + +#ifndef PUTIL_H +#define PUTIL_H + +#include "unicode/utypes.h" + /** + * \file + * \brief C API: Platform Utilities + */ + +/* Define this to 1 if your platform supports IEEE 754 floating point, + to 0 if it does not. */ +#ifndef IEEE_754 +# define IEEE_754 1 +#endif + +/*==========================================================================*/ +/* Platform utilities */ +/*==========================================================================*/ + +/** + * Platform utilities isolates the platform dependencies of the + * libarary. For each platform which this code is ported to, these + * functions may have to be re-implemented. + */ + +/** + * Return the ICU data directory. + * The data directory is where common format ICU data files (.dat files) + * are loaded from. Note that normal use of the built-in ICU + * facilities does not require loading of an external data file; + * unless you are adding custom data to ICU, the data directory + * does not need to be set. + * + * The data directory is determined as follows: + * If u_setDataDirectory() has been called, that is it, otherwise + * if the ICU_DATA environment variable is set, use that, otherwise + * If a data directory was specifed at ICU build time + * <code>( #define ICU_DATA_DIR "path" )</code>, use that, + * otherwise no data directory is available. + * + * @return the data directory, or an empty string ("") if no data directory has + * been specified. + * + * @stable ICU 2.0 + */ +U_STABLE const char* U_EXPORT2 u_getDataDirectory(void); + +/** + * Set the ICU data directory. + * The data directory is where common format ICU data files (.dat files) + * are loaded from. Note that normal use of the built-in ICU + * facilities does not require loading of an external data file; + * unless you are adding custom data to ICU, the data directory + * does not need to be set. + * + * This function should be called at most once in a process, before the + * first ICU operation (e.g., u_init()) that will require the loading of an + * ICU data file. + * This function is not thread-safe. Use it before calling ICU APIs from + * multiple threads. + * + * @param directory The directory to be set. + * + * @see u_init + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 u_setDataDirectory(const char *directory); + +/** + * Please use ucnv_getDefaultName() instead. + * Return the default codepage for this platform and locale. + * This function can call setlocale() on Unix platforms. Please read the + * platform documentation on setlocale() before calling this function. + * @return the default codepage for this platform + * @internal + */ +U_INTERNAL const char* U_EXPORT2 uprv_getDefaultCodepage(void); + +/** + * Please use uloc_getDefault() instead. + * Return the default locale ID string by querying ths system, or + * zero if one cannot be found. + * This function can call setlocale() on Unix platforms. Please read the + * platform documentation on setlocale() before calling this function. + * @return the default locale ID string + * @internal + */ +U_INTERNAL const char* U_EXPORT2 uprv_getDefaultLocaleID(void); + +/** + * Filesystem file and path separator characters. + * Example: '/' and ':' on Unix, '\\' and ';' on Windows. + * @stable ICU 2.0 + */ +#ifdef XP_MAC +# define U_FILE_SEP_CHAR ':' +# define U_FILE_ALT_SEP_CHAR ':' +# define U_PATH_SEP_CHAR ';' +# define U_FILE_SEP_STRING ":" +# define U_FILE_ALT_SEP_STRING ":" +# define U_PATH_SEP_STRING ";" +#elif defined(U_WINDOWS) +# define U_FILE_SEP_CHAR '\\' +# define U_FILE_ALT_SEP_CHAR '/' +# define U_PATH_SEP_CHAR ';' +# define U_FILE_SEP_STRING "\\" +# define U_FILE_ALT_SEP_STRING "/" +# define U_PATH_SEP_STRING ";" +#else +# define U_FILE_SEP_CHAR '/' +# define U_FILE_ALT_SEP_CHAR '/' +# define U_PATH_SEP_CHAR ':' +# define U_FILE_SEP_STRING "/" +# define U_FILE_ALT_SEP_STRING "/" +# define U_PATH_SEP_STRING ":" +#endif + +/** + * Convert char characters to UChar characters. + * This utility function is useful only for "invariant characters" + * that are encoded in the platform default encoding. + * They are a small, constant subset of the encoding and include + * just the latin letters, digits, and some punctuation. + * For details, see U_CHARSET_FAMILY. + * + * @param cs Input string, points to <code>length</code> + * character bytes from a subset of the platform encoding. + * @param us Output string, points to memory for <code>length</code> + * Unicode characters. + * @param length The number of characters to convert; this may + * include the terminating <code>NUL</code>. + * + * @see U_CHARSET_FAMILY + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +u_charsToUChars(const char *cs, UChar *us, int32_t length); + +/** + * Convert UChar characters to char characters. + * This utility function is useful only for "invariant characters" + * that can be encoded in the platform default encoding. + * They are a small, constant subset of the encoding and include + * just the latin letters, digits, and some punctuation. + * For details, see U_CHARSET_FAMILY. + * + * @param us Input string, points to <code>length</code> + * Unicode characters that can be encoded with the + * codepage-invariant subset of the platform encoding. + * @param cs Output string, points to memory for <code>length</code> + * character bytes. + * @param length The number of characters to convert; this may + * include the terminating <code>NUL</code>. + * + * @see U_CHARSET_FAMILY + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +u_UCharsToChars(const UChar *us, char *cs, int32_t length); + +#endif diff --git a/utils/openttd/unicode/pwin32.h b/utils/openttd/unicode/pwin32.h new file mode 100644 index 00000000000..9aad3530f0a --- /dev/null +++ b/utils/openttd/unicode/pwin32.h @@ -0,0 +1,311 @@ +/* + ****************************************************************************** + * + * Copyright (C) 1997-2007, International Business Machines + * Corporation and others. All Rights Reserved. + * + ****************************************************************************** + * + * FILE NAME : platform.h + * + * Date Name Description + * 05/13/98 nos Creation (content moved here from ptypes.h). + * 03/02/99 stephen Added AS400 support. + * 03/30/99 stephen Added Linux support. + * 04/13/99 stephen Reworked for autoconf. + ****************************************************************************** + */ + + /** + * \file + * \brief Configuration constants for the Windows platform + */ + +/* Define the platform we're on. */ +#ifndef U_WINDOWS +#define U_WINDOWS +#endif + +#if defined(__BORLANDC__) +#define U_HAVE_PLACEMENT_NEW 0 +#define U_HAVE_INTTYPES_H 1 +#define __STDC_CONSTANT_MACROS +#endif + +/* _MSC_VER is used to detect the Microsoft compiler. */ +#if defined(_MSC_VER) +#define U_INT64_IS_LONG_LONG 0 +#else +#define U_INT64_IS_LONG_LONG 1 +#endif + +/* Define whether inttypes.h is available */ +#ifndef U_HAVE_INTTYPES_H +#define U_HAVE_INTTYPES_H 0 +#endif + +/* + * Define what support for C++ streams is available. + * If U_IOSTREAM_SOURCE is set to 199711, then <iostream> is available + * (1997711 is the date the ISO/IEC C++ FDIS was published), and then + * one should qualify streams using the std namespace in ICU header + * files. + * If U_IOSTREAM_SOURCE is set to 198506, then <iostream.h> is + * available instead (198506 is the date when Stroustrup published + * "An Extensible I/O Facility for C++" at the summer USENIX conference). + * If U_IOSTREAM_SOURCE is 0, then C++ streams are not available and + * support for them will be silently suppressed in ICU. + * + */ + +#ifndef U_IOSTREAM_SOURCE +#define U_IOSTREAM_SOURCE 199711 +#endif + +/* Determines whether specific types are available */ +#ifndef U_HAVE_INT8_T +#define U_HAVE_INT8_T U_HAVE_INTTYPES_H +#endif + +#ifndef U_HAVE_UINT8_T +#define U_HAVE_UINT8_T U_HAVE_INTTYPES_H +#endif + +#ifndef U_HAVE_INT16_T +#define U_HAVE_INT16_T U_HAVE_INTTYPES_H +#endif + +#ifndef U_HAVE_UINT16_T +#define U_HAVE_UINT16_T U_HAVE_INTTYPES_H +#endif + +#ifndef U_HAVE_INT32_T +#define U_HAVE_INT32_T U_HAVE_INTTYPES_H +#endif + +#ifndef U_HAVE_UINT32_T +#define U_HAVE_UINT32_T U_HAVE_INTTYPES_H +#endif + +#ifndef U_HAVE_INT64_T +#define U_HAVE_INT64_T U_HAVE_INTTYPES_H +#endif + +#ifndef U_HAVE_UINT64_T +#define U_HAVE_UINT64_T U_HAVE_INTTYPES_H +#endif + +/* Define 64 bit limits */ +#if !U_INT64_IS_LONG_LONG +# ifndef INT64_C +# define INT64_C(x) ((int64_t)x) +# endif +# ifndef UINT64_C +# define UINT64_C(x) ((uint64_t)x) +# endif +/* else use the umachine.h definition */ +#endif + +/*===========================================================================*/ +/* Generic data types */ +/*===========================================================================*/ + +/* If your platform does not have the <inttypes.h> header, you may + need to edit the typedefs below. */ +#if U_HAVE_INTTYPES_H +#include <inttypes.h> +#else /* U_HAVE_INTTYPES_H */ + +#if ! U_HAVE_INT8_T +typedef signed char int8_t; +#endif + +#if ! U_HAVE_UINT8_T +typedef unsigned char uint8_t; +#endif + +#if ! U_HAVE_INT16_T +typedef signed short int16_t; +#endif + +#if ! U_HAVE_UINT16_T +typedef unsigned short uint16_t; +#endif + +#if ! U_HAVE_INT32_T +typedef signed int int32_t; +#endif + +#if ! U_HAVE_UINT32_T +typedef unsigned int uint32_t; +#endif + +#if ! U_HAVE_INT64_T +#if U_INT64_IS_LONG_LONG + typedef signed long long int64_t; +#else + typedef signed __int64 int64_t; +#endif +#endif + +#if ! U_HAVE_UINT64_T +#if U_INT64_IS_LONG_LONG + typedef unsigned long long uint64_t; +#else + typedef unsigned __int64 uint64_t; +#endif +#endif +#endif + +/*===========================================================================*/ +/* Compiler and environment features */ +/*===========================================================================*/ + +/* Define whether namespace is supported */ +#ifndef U_HAVE_NAMESPACE +#define U_HAVE_NAMESPACE 1 +#endif + +/* Determines the endianness of the platform */ +#define U_IS_BIG_ENDIAN 0 + +/* 1 or 0 to enable or disable threads. If undefined, default is: enable threads. */ +#define ICU_USE_THREADS 1 + +/* On strong memory model CPUs (e.g. x86 CPUs), we use a safe & quick double check mutex lock. */ +/* +Microsoft can define _M_IX86, _M_AMD64 (before Visual Studio 8) or _M_X64 (starting in Visual Studio 8). +Intel can define _M_IX86 or _M_X64 +*/ +#if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) +#define UMTX_STRONG_MEMORY_MODEL 1 +#endif + +#ifndef U_DEBUG +#ifdef _DEBUG +#define U_DEBUG 1 +#else +#define U_DEBUG 0 +#endif +#endif + +#ifndef U_RELEASE +#ifdef NDEBUG +#define U_RELEASE 1 +#else +#define U_RELEASE 0 +#endif +#endif + +/* Determine whether to disable renaming or not. This overrides the + setting in umachine.h which is for all platforms. */ +#ifndef U_DISABLE_RENAMING +#define U_DISABLE_RENAMING 0 +#endif + +/* Determine whether to override new and delete. */ +#ifndef U_OVERRIDE_CXX_ALLOCATION +#define U_OVERRIDE_CXX_ALLOCATION 1 +#endif +/* Determine whether to override placement new and delete for STL. */ +#ifndef U_HAVE_PLACEMENT_NEW +#define U_HAVE_PLACEMENT_NEW 1 +#endif +/* Determine whether to override new and delete for MFC. */ +#if !defined(U_HAVE_DEBUG_LOCATION_NEW) && defined(_MSC_VER) +#define U_HAVE_DEBUG_LOCATION_NEW 1 +#endif + +/* Determine whether to enable tracing. */ +#ifndef U_ENABLE_TRACING +#define U_ENABLE_TRACING 0 +#endif + +/* Do we allow ICU users to use the draft APIs by default? */ +#ifndef U_DEFAULT_SHOW_DRAFT +#define U_DEFAULT_SHOW_DRAFT 1 +#endif + +/* Define the library suffix in a C syntax. */ +#define U_HAVE_LIB_SUFFIX 0 +#define U_LIB_SUFFIX_C_NAME +#define U_LIB_SUFFIX_C_NAME_STRING "" + +/*===========================================================================*/ +/* Information about wchar support */ +/*===========================================================================*/ + +#define U_HAVE_WCHAR_H 1 +#define U_SIZEOF_WCHAR_T 2 + +#define U_HAVE_WCSCPY 1 + +/** + * \def U_DECLARE_UTF16 + * Do not use this macro. Use the UNICODE_STRING or U_STRING_DECL macros + * instead. + * @internal + */ +#if 1 +#define U_DECLARE_UTF16(string) L ## string +#endif + +/*===========================================================================*/ +/* Information about POSIX support */ +/*===========================================================================*/ + +#if 1 +#define U_TZSET _tzset +#endif +#if 1 +#define U_TIMEZONE _timezone +#endif +#if 1 +#define U_TZNAME _tzname +#endif +#if 1 +#define U_DAYLIGHT _daylight +#endif + +#define U_HAVE_MMAP 0 +#define U_HAVE_POPEN 0 + +/*===========================================================================*/ +/* Symbol import-export control */ +/*===========================================================================*/ + +#ifdef U_STATIC_IMPLEMENTATION +#define U_EXPORT +#else +#define U_EXPORT __declspec(dllexport) +#endif +#define U_EXPORT2 __cdecl +#define U_IMPORT __declspec(dllimport) + +/*===========================================================================*/ +/* Code alignment and C function inlining */ +/*===========================================================================*/ + +#ifndef U_INLINE +# ifdef __cplusplus +# define U_INLINE inline +# else +# define U_INLINE __inline +# endif +#endif + +#if defined(_MSC_VER) && defined(_M_IX86) && !defined(_MANAGED) +#define U_ALIGN_CODE(val) __asm align val +#else +#define U_ALIGN_CODE(val) +#endif + + +/*===========================================================================*/ +/* Programs used by ICU code */ +/*===========================================================================*/ + +#ifndef U_MAKE +#define U_MAKE "nmake" +#define U_MAKE_IS_NMAKE 1 +#endif diff --git a/utils/openttd/unicode/rbbi.h b/utils/openttd/unicode/rbbi.h new file mode 100644 index 00000000000..747ea44ce1c --- /dev/null +++ b/utils/openttd/unicode/rbbi.h @@ -0,0 +1,700 @@ +/* +*************************************************************************** +* Copyright (C) 1999-2007 International Business Machines Corporation * +* and others. All rights reserved. * +*************************************************************************** + +********************************************************************** +* Date Name Description +* 10/22/99 alan Creation. +* 11/11/99 rgillam Complete port from Java. +********************************************************************** +*/ + +#ifndef RBBI_H +#define RBBI_H + +#include "unicode/utypes.h" + +/** + * \file + * \brief C++ API: Rule Based Break Iterator + */ + +#if !UCONFIG_NO_BREAK_ITERATION + +#include "unicode/brkiter.h" +#include "unicode/udata.h" +#include "unicode/parseerr.h" +#include "unicode/schriter.h" +#include "unicode/uchriter.h" + + +struct UTrie; + +U_NAMESPACE_BEGIN + +/** @internal */ +struct RBBIDataHeader; +class RuleBasedBreakIteratorTables; +class BreakIterator; +class RBBIDataWrapper; +class UStack; +class LanguageBreakEngine; +class UnhandledEngine; +struct RBBIStateTable; + + + + +/** + * + * A subclass of BreakIterator whose behavior is specified using a list of rules. + * <p>Instances of this class are most commonly created by the factory methods of + * BreakIterator::createWordInstance(), BreakIterator::createLineInstance(), etc., + * and then used via the abstract API in class BreakIterator</p> + * + * <p>See the ICU User Guide for information on Break Iterator Rules.</p> + * + * <p>This class is not intended to be subclassed. (Class DictionaryBasedBreakIterator + * is a subclass, but that relationship is effectively internal to the ICU + * implementation. The subclassing interface to RulesBasedBreakIterator is + * not part of the ICU API, and may not remain stable.</p> + * + */ +class U_COMMON_API RuleBasedBreakIterator : public BreakIterator { + +protected: + /** + * The UText through which this BreakIterator accesses the text + * @internal + */ + UText *fText; + + /** + * A character iterator that refers to the same text as the UText, above. + * Only included for compatibility with old API, which was based on CharacterIterators. + * Value may be adopted from outside, or one of fSCharIter or fDCharIter, below. + */ + CharacterIterator *fCharIter; + + /** + * When the input text is provided by a UnicodeString, this will point to + * a characterIterator that wraps that data. Needed only for the + * implementation of getText(), a backwards compatibility issue. + */ + StringCharacterIterator *fSCharIter; + + /** + * When the input text is provided by a UText, this + * dummy CharacterIterator over an empty string will + * be returned from getText() + */ + UCharCharacterIterator *fDCharIter; + + /** + * The rule data for this BreakIterator instance + * @internal + */ + RBBIDataWrapper *fData; + + /** Index of the Rule {tag} values for the most recent match. + * @internal + */ + int32_t fLastRuleStatusIndex; + + /** + * Rule tag value valid flag. + * Some iterator operations don't intrinsically set the correct tag value. + * This flag lets us lazily compute the value if we are ever asked for it. + * @internal + */ + UBool fLastStatusIndexValid; + + /** + * Counter for the number of characters encountered with the "dictionary" + * flag set. + * @internal + */ + uint32_t fDictionaryCharCount; + + /** + * When a range of characters is divided up using the dictionary, the break + * positions that are discovered are stored here, preventing us from having + * to use either the dictionary or the state table again until the iterator + * leaves this range of text. Has the most impact for line breaking. + * @internal + */ + int32_t* fCachedBreakPositions; + + /** + * The number of elements in fCachedBreakPositions + * @internal + */ + int32_t fNumCachedBreakPositions; + + /** + * if fCachedBreakPositions is not null, this indicates which item in the + * cache the current iteration position refers to + * @internal + */ + int32_t fPositionInCache; + + /** + * + * If present, UStack of LanguageBreakEngine objects that might handle + * dictionary characters. Searched from top to bottom to find an object to + * handle a given character. + * @internal + */ + UStack *fLanguageBreakEngines; + + /** + * + * If present, the special LanguageBreakEngine used for handling + * characters that are in the dictionary set, but not handled by any + * LangugageBreakEngine. + * @internal + */ + UnhandledEngine *fUnhandledBreakEngine; + + /** + * + * The type of the break iterator, or -1 if it has not been set. + * @internal + */ + int32_t fBreakType; + +protected: + //======================================================================= + // constructors + //======================================================================= + + /** + * Constructor from a flattened set of RBBI data in malloced memory. + * RulesBasedBreakIterators built from a custom set of rules + * are created via this constructor; the rules are compiled + * into memory, then the break iterator is constructed here. + * + * The break iterator adopts the memory, and will + * free it when done. + * @internal + */ + RuleBasedBreakIterator(RBBIDataHeader* data, UErrorCode &status); + + + friend class RBBIRuleBuilder; + /** @internal */ + friend class BreakIterator; + + + +public: + + /** Default constructor. Creates an empty shell of an iterator, with no + * rules or text to iterate over. Object can subsequently be assigned to. + * @stable ICU 2.2 + */ + RuleBasedBreakIterator(); + + /** + * Copy constructor. Will produce a break iterator with the same behavior, + * and which iterates over the same text, as the one passed in. + * @param that The RuleBasedBreakIterator passed to be copied + * @stable ICU 2.0 + */ + RuleBasedBreakIterator(const RuleBasedBreakIterator& that); + + /** + * Construct a RuleBasedBreakIterator from a set of rules supplied as a string. + * @param rules The break rules to be used. + * @param parseError In the event of a syntax error in the rules, provides the location + * within the rules of the problem. + * @param status Information on any errors encountered. + * @stable ICU 2.2 + */ + RuleBasedBreakIterator( const UnicodeString &rules, + UParseError &parseError, + UErrorCode &status); + + + /** + * This constructor uses the udata interface to create a BreakIterator + * whose internal tables live in a memory-mapped file. "image" is an + * ICU UDataMemory handle for the pre-compiled break iterator tables. + * @param image handle to the memory image for the break iterator data. + * Ownership of the UDataMemory handle passes to the Break Iterator, + * which will be responsible for closing it when it is no longer needed. + * @param status Information on any errors encountered. + * @see udata_open + * @see #getBinaryRules + * @stable ICU 2.8 + */ + RuleBasedBreakIterator(UDataMemory* image, UErrorCode &status); + + /** + * Destructor + * @stable ICU 2.0 + */ + virtual ~RuleBasedBreakIterator(); + + /** + * Assignment operator. Sets this iterator to have the same behavior, + * and iterate over the same text, as the one passed in. + * @param that The RuleBasedBreakItertor passed in + * @return the newly created RuleBasedBreakIterator + * @stable ICU 2.0 + */ + RuleBasedBreakIterator& operator=(const RuleBasedBreakIterator& that); + + /** + * Equality operator. Returns TRUE if both BreakIterators are of the + * same class, have the same behavior, and iterate over the same text. + * @param that The BreakIterator to be compared for equality + * @return TRUE if both BreakIterators are of the + * same class, have the same behavior, and iterate over the same text. + * @stable ICU 2.0 + */ + virtual UBool operator==(const BreakIterator& that) const; + + /** + * Not-equal operator. If operator== returns TRUE, this returns FALSE, + * and vice versa. + * @param that The BreakIterator to be compared for inequality + * @return TRUE if both BreakIterators are not same. + * @stable ICU 2.0 + */ + UBool operator!=(const BreakIterator& that) const; + + /** + * Returns a newly-constructed RuleBasedBreakIterator with the same + * behavior, and iterating over the same text, as this one. + * Differs from the copy constructor in that it is polymorphic, and + * will correctly clone (copy) a derived class. + * clone() is thread safe. Multiple threads may simultaeneously + * clone the same source break iterator. + * @return a newly-constructed RuleBasedBreakIterator + * @stable ICU 2.0 + */ + virtual BreakIterator* clone() const; + + /** + * Compute a hash code for this BreakIterator + * @return A hash code + * @stable ICU 2.0 + */ + virtual int32_t hashCode(void) const; + + /** + * Returns the description used to create this iterator + * @return the description used to create this iterator + * @stable ICU 2.0 + */ + virtual const UnicodeString& getRules(void) const; + + //======================================================================= + // BreakIterator overrides + //======================================================================= + + /** + * <p> + * Return a CharacterIterator over the text being analyzed. + * The returned character iterator is owned by the break iterator, and must + * not be deleted by the caller. Repeated calls to this function may + * return the same CharacterIterator. + * </p> + * <p> + * The returned character iterator must not be used concurrently with + * the break iterator. If concurrent operation is needed, clone the + * returned character iterator first and operate on the clone. + * </p> + * <p> + * When the break iterator is operating on text supplied via a UText, + * this function will fail. Lacking any way to signal failures, it + * returns an CharacterIterator containing no text. + * The function getUText() provides similar functionality, + * is reliable, and is more efficient. + * </p> + * + * TODO: deprecate this function? + * + * @return An iterator over the text being analyzed. + * @stable ICU 2.0 + */ + virtual CharacterIterator& getText(void) const; + + + /** + * Get a UText for the text being analyzed. + * The returned UText is a shallow clone of the UText used internally + * by the break iterator implementation. It can safely be used to + * access the text without impacting any break iterator operations, + * but the underlying text itself must not be altered. + * + * @param fillIn A UText to be filled in. If NULL, a new UText will be + * allocated to hold the result. + * @param status receives any error codes. + * @return The current UText for this break iterator. If an input + * UText was provided, it will always be returned. + * @stable ICU 3.4 + */ + virtual UText *getUText(UText *fillIn, UErrorCode &status) const; + + /** + * Set the iterator to analyze a new piece of text. This function resets + * the current iteration position to the beginning of the text. + * @param newText An iterator over the text to analyze. The BreakIterator + * takes ownership of the character iterator. The caller MUST NOT delete it! + * @stable ICU 2.0 + */ + virtual void adoptText(CharacterIterator* newText); + + /** + * Set the iterator to analyze a new piece of text. This function resets + * the current iteration position to the beginning of the text. + * @param newText The text to analyze. + * @stable ICU 2.0 + */ + virtual void setText(const UnicodeString& newText); + + /** + * Reset the break iterator to operate over the text represented by + * the UText. The iterator position is reset to the start. + * + * This function makes a shallow clone of the supplied UText. This means + * that the caller is free to immediately close or otherwise reuse the + * Utext that was passed as a parameter, but that the underlying text itself + * must not be altered while being referenced by the break iterator. + * + * @param text The UText used to change the text. + * @param status Receives any error codes. + * @stable ICU 3.4 + */ + virtual void setText(UText *text, UErrorCode &status); + + /** + * Sets the current iteration position to the beginning of the text. + * @return The offset of the beginning of the text. + * @stable ICU 2.0 + */ + virtual int32_t first(void); + + /** + * Sets the current iteration position to the end of the text. + * @return The text's past-the-end offset. + * @stable ICU 2.0 + */ + virtual int32_t last(void); + + /** + * Advances the iterator either forward or backward the specified number of steps. + * Negative values move backward, and positive values move forward. This is + * equivalent to repeatedly calling next() or previous(). + * @param n The number of steps to move. The sign indicates the direction + * (negative is backwards, and positive is forwards). + * @return The character offset of the boundary position n boundaries away from + * the current one. + * @stable ICU 2.0 + */ + virtual int32_t next(int32_t n); + + /** + * Advances the iterator to the next boundary position. + * @return The position of the first boundary after this one. + * @stable ICU 2.0 + */ + virtual int32_t next(void); + + /** + * Moves the iterator backwards, to the last boundary preceding this one. + * @return The position of the last boundary position preceding this one. + * @stable ICU 2.0 + */ + virtual int32_t previous(void); + + /** + * Sets the iterator to refer to the first boundary position following + * the specified position. + * @param offset The position from which to begin searching for a break position. + * @return The position of the first break after the current position. + * @stable ICU 2.0 + */ + virtual int32_t following(int32_t offset); + + /** + * Sets the iterator to refer to the last boundary position before the + * specified position. + * @param offset The position to begin searching for a break from. + * @return The position of the last boundary before the starting position. + * @stable ICU 2.0 + */ + virtual int32_t preceding(int32_t offset); + + /** + * Returns true if the specfied position is a boundary position. As a side + * effect, leaves the iterator pointing to the first boundary position at + * or after "offset". + * @param offset the offset to check. + * @return True if "offset" is a boundary position. + * @stable ICU 2.0 + */ + virtual UBool isBoundary(int32_t offset); + + /** + * Returns the current iteration position. + * @return The current iteration position. + * @stable ICU 2.0 + */ + virtual int32_t current(void) const; + + + /** + * Return the status tag from the break rule that determined the most recently + * returned break position. For break rules that do not specify a + * status, a default value of 0 is returned. If more than one break rule + * would cause a boundary to be located at some position in the text, + * the numerically largest of the applicable status values is returned. + * <p> + * Of the standard types of ICU break iterators, only word break and + * line break provide status values. The values are defined in + * the header file ubrk.h. For Word breaks, the status allows distinguishing between words + * that contain alphabetic letters, "words" that appear to be numbers, + * punctuation and spaces, words containing ideographic characters, and + * more. For Line Break, the status distinguishes between hard (mandatory) breaks + * and soft (potential) break positions. + * <p> + * <code>getRuleStatus()</code> can be called after obtaining a boundary + * position from <code>next()</code>, <code>previous()</code>, or + * any other break iterator functions that returns a boundary position. + * <p> + * When creating custom break rules, one is free to define whatever + * status values may be convenient for the application. + * <p> + * Note: this function is not thread safe. It should not have been + * declared const, and the const remains only for compatibility + * reasons. (The function is logically const, but not bit-wise const). + * <p> + * @return the status from the break rule that determined the most recently + * returned break position. + * + * @see UWordBreak + * @stable ICU 2.2 + */ + virtual int32_t getRuleStatus() const; + + /** + * Get the status (tag) values from the break rule(s) that determined the most + * recently returned break position. + * <p> + * The returned status value(s) are stored into an array provided by the caller. + * The values are stored in sorted (ascending) order. + * If the capacity of the output array is insufficient to hold the data, + * the output will be truncated to the available length, and a + * U_BUFFER_OVERFLOW_ERROR will be signaled. + * + * @param fillInVec an array to be filled in with the status values. + * @param capacity the length of the supplied vector. A length of zero causes + * the function to return the number of status values, in the + * normal way, without attemtping to store any values. + * @param status receives error codes. + * @return The number of rule status values from rules that determined + * the most recent boundary returned by the break iterator. + * In the event of a U_BUFFER_OVERFLOW_ERROR, the return value + * is the total number of status values that were available, + * not the reduced number that were actually returned. + * @see getRuleStatus + * @stable ICU 3.0 + */ + virtual int32_t getRuleStatusVec(int32_t *fillInVec, int32_t capacity, UErrorCode &status); + + /** + * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. + * This method is to implement a simple version of RTTI, since not all + * C++ compilers support genuine RTTI. Polymorphic operator==() and + * clone() methods call this method. + * + * @return The class ID for this object. All objects of a + * given class have the same class ID. Objects of + * other classes have different class IDs. + * @stable ICU 2.0 + */ + virtual UClassID getDynamicClassID(void) const; + + /** + * Returns the class ID for this class. This is useful only for + * comparing to a return value from getDynamicClassID(). For example: + * + * Base* polymorphic_pointer = createPolymorphicObject(); + * if (polymorphic_pointer->getDynamicClassID() == + * Derived::getStaticClassID()) ... + * + * @return The class ID for all objects of this class. + * @stable ICU 2.0 + */ + static UClassID U_EXPORT2 getStaticClassID(void); + + /* + * Create a clone (copy) of this break iterator in memory provided + * by the caller. The idea is to increase performance by avoiding + * a storage allocation. Use of this functoin is NOT RECOMMENDED. + * Performance gains are minimal, and correct buffer management is + * tricky. Use clone() instead. + * + * @param stackBuffer The pointer to the memory into which the cloned object + * should be placed. If NULL, allocate heap memory + * for the cloned object. + * @param BufferSize The size of the buffer. If zero, return the required + * buffer size, but do not clone the object. If the + * size was too small (but not zero), allocate heap + * storage for the cloned object. + * + * @param status Error status. U_SAFECLONE_ALLOCATED_WARNING will be + * returned if the the provided buffer was too small, and + * the clone was therefore put on the heap. + * + * @return Pointer to the clone object. This may differ from the stackBuffer + * address if the byte alignment of the stack buffer was not suitable + * or if the stackBuffer was too small to hold the clone. + * @stable ICU 2.0 + */ + virtual BreakIterator * createBufferClone(void *stackBuffer, + int32_t &BufferSize, + UErrorCode &status); + + + /** + * Return the binary form of compiled break rules, + * which can then be used to create a new break iterator at some + * time in the future. Creating a break iterator from pre-compiled rules + * is much faster than building one from the source form of the + * break rules. + * + * The binary data can only be used with the same version of ICU + * and on the same platform type (processor endian-ness) + * + * @param length Returns the length of the binary data. (Out paramter.) + * + * @return A pointer to the binary (compiled) rule data. The storage + * belongs to the RulesBasedBreakIterator object, not the + * caller, and must not be modified or deleted. + * @internal + */ + virtual const uint8_t *getBinaryRules(uint32_t &length); + + +protected: + //======================================================================= + // implementation + //======================================================================= + /** + * Dumps caches and performs other actions associated with a complete change + * in text or iteration position. + * @internal + */ + virtual void reset(void); + +#if 0 + /** + * Return true if the category lookup for this char + * indicates that it is in the set of dictionary lookup chars. + * This function is intended for use by dictionary based break iterators. + * @return true if the category lookup for this char + * indicates that it is in the set of dictionary lookup chars. + * @internal + */ + virtual UBool isDictionaryChar(UChar32); + + /** + * Get the type of the break iterator. + * @internal + */ + virtual int32_t getBreakType() const; +#endif + + /** + * Set the type of the break iterator. + * @internal + */ + virtual void setBreakType(int32_t type); + + /** + * Common initialization function, used by constructors and bufferClone. + * (Also used by DictionaryBasedBreakIterator::createBufferClone().) + * @internal + */ + void init(); + +private: + + /** + * This method backs the iterator back up to a "safe position" in the text. + * This is a position that we know, without any context, must be a break position. + * The various calling methods then iterate forward from this safe position to + * the appropriate position to return. (For more information, see the description + * of buildBackwardsStateTable() in RuleBasedBreakIterator.Builder.) + * @param statetable state table used of moving backwards + * @internal + */ + int32_t handlePrevious(const RBBIStateTable *statetable); + + /** + * This method is the actual implementation of the next() method. All iteration + * vectors through here. This method initializes the state machine to state 1 + * and advances through the text character by character until we reach the end + * of the text or the state machine transitions to state 0. We update our return + * value every time the state machine passes through a possible end state. + * @param statetable state table used of moving forwards + * @internal + */ + int32_t handleNext(const RBBIStateTable *statetable); + +protected: + + /** + * This is the function that actually implements dictionary-based + * breaking. Covering at least the range from startPos to endPos, + * it checks for dictionary characters, and if it finds them determines + * the appropriate object to deal with them. It may cache found breaks in + * fCachedBreakPositions as it goes. It may well also look at text outside + * the range startPos to endPos. + * If going forward, endPos is the normal Unicode break result, and + * if goind in reverse, startPos is the normal Unicode break result + * @param startPos The start position of a range of text + * @param endPos The end position of a range of text + * @param reverse The call is for the reverse direction + * @internal + */ + int32_t checkDictionary(int32_t startPos, int32_t endPos, UBool reverse); + +private: + + /** + * This function returns the appropriate LanguageBreakEngine for a + * given character c. + * @param c A character in the dictionary set + * @internal + */ + const LanguageBreakEngine *getLanguageBreakEngine(UChar32 c); + + /** + * @internal + */ + void makeRuleStatusValid(); + +}; + +//------------------------------------------------------------------------------ +// +// Inline Functions Definitions ... +// +//------------------------------------------------------------------------------ + +inline UBool RuleBasedBreakIterator::operator!=(const BreakIterator& that) const { + return !operator==(that); +} + +U_NAMESPACE_END + +#endif /* #if !UCONFIG_NO_BREAK_ITERATION */ + +#endif diff --git a/utils/openttd/unicode/rep.h b/utils/openttd/unicode/rep.h new file mode 100644 index 00000000000..3fab6fa1272 --- /dev/null +++ b/utils/openttd/unicode/rep.h @@ -0,0 +1,259 @@ +/* +************************************************************************** +* Copyright (C) 1999-2005, International Business Machines Corporation and +* others. All Rights Reserved. +************************************************************************** +* Date Name Description +* 11/17/99 aliu Creation. Ported from java. Modified to +* match current UnicodeString API. Forced +* to use name "handleReplaceBetween" because +* of existing methods in UnicodeString. +************************************************************************** +*/ + +#ifndef REP_H +#define REP_H + +#include "unicode/uobject.h" + +/** + * \file + * \brief C++ API: Replaceable String + */ + +U_NAMESPACE_BEGIN + +class UnicodeString; + +/** + * <code>Replaceable</code> is an abstract base class representing a + * string of characters that supports the replacement of a range of + * itself with a new string of characters. It is used by APIs that + * change a piece of text while retaining metadata. Metadata is data + * other than the Unicode characters returned by char32At(). One + * example of metadata is style attributes; another is an edit + * history, marking each character with an author and revision number. + * + * <p>An implicit aspect of the <code>Replaceable</code> API is that + * during a replace operation, new characters take on the metadata of + * the old characters. For example, if the string "the <b>bold</b> + * font" has range (4, 8) replaced with "strong", then it becomes "the + * <b>strong</b> font". + * + * <p><code>Replaceable</code> specifies ranges using a start + * offset and a limit offset. The range of characters thus specified + * includes the characters at offset start..limit-1. That is, the + * start offset is inclusive, and the limit offset is exclusive. + * + * <p><code>Replaceable</code> also includes API to access characters + * in the string: <code>length()</code>, <code>charAt()</code>, + * <code>char32At()</code>, and <code>extractBetween()</code>. + * + * <p>For a subclass to support metadata, typical behavior of + * <code>replace()</code> is the following: + * <ul> + * <li>Set the metadata of the new text to the metadata of the first + * character replaced</li> + * <li>If no characters are replaced, use the metadata of the + * previous character</li> + * <li>If there is no previous character (i.e. start == 0), use the + * following character</li> + * <li>If there is no following character (i.e. the replaceable was + * empty), use default metadata.<br> + * <li>If the code point U+FFFF is seen, it should be interpreted as + * a special marker having no metadata<li> + * </li> + * </ul> + * If this is not the behavior, the subclass should document any differences. + * @author Alan Liu + * @stable ICU 2.0 + */ +class U_COMMON_API Replaceable : public UObject { + +public: + /** + * Destructor. + * @stable ICU 2.0 + */ + virtual ~Replaceable(); + + /** + * Returns the number of 16-bit code units in the text. + * @return number of 16-bit code units in text + * @stable ICU 1.8 + */ + inline int32_t length() const; + + /** + * Returns the 16-bit code unit at the given offset into the text. + * @param offset an integer between 0 and <code>length()</code>-1 + * inclusive + * @return 16-bit code unit of text at given offset + * @stable ICU 1.8 + */ + inline UChar charAt(int32_t offset) const; + + /** + * Returns the 32-bit code point at the given 16-bit offset into + * the text. This assumes the text is stored as 16-bit code units + * with surrogate pairs intermixed. If the offset of a leading or + * trailing code unit of a surrogate pair is given, return the + * code point of the surrogate pair. + * + * @param offset an integer between 0 and <code>length()</code>-1 + * inclusive + * @return 32-bit code point of text at given offset + * @stable ICU 1.8 + */ + inline UChar32 char32At(int32_t offset) const; + + /** + * Copies characters in the range [<tt>start</tt>, <tt>limit</tt>) + * into the UnicodeString <tt>target</tt>. + * @param start offset of first character which will be copied + * @param limit offset immediately following the last character to + * be copied + * @param target UnicodeString into which to copy characters. + * @return A reference to <TT>target</TT> + * @stable ICU 2.1 + */ + virtual void extractBetween(int32_t start, + int32_t limit, + UnicodeString& target) const = 0; + + /** + * Replaces a substring of this object with the given text. If the + * characters being replaced have metadata, the new characters + * that replace them should be given the same metadata. + * + * <p>Subclasses must ensure that if the text between start and + * limit is equal to the replacement text, that replace has no + * effect. That is, any metadata + * should be unaffected. In addition, subclasses are encouraged to + * check for initial and trailing identical characters, and make a + * smaller replacement if possible. This will preserve as much + * metadata as possible. + * @param start the beginning index, inclusive; <code>0 <= start + * <= limit</code>. + * @param limit the ending index, exclusive; <code>start <= limit + * <= length()</code>. + * @param text the text to replace characters <code>start</code> + * to <code>limit - 1</code> + * @stable ICU 2.0 + */ + virtual void handleReplaceBetween(int32_t start, + int32_t limit, + const UnicodeString& text) = 0; + // Note: All other methods in this class take the names of + // existing UnicodeString methods. This method is the exception. + // It is named differently because all replace methods of + // UnicodeString return a UnicodeString&. The 'between' is + // required in order to conform to the UnicodeString naming + // convention; API taking start/length are named <operation>, and + // those taking start/limit are named <operationBetween>. The + // 'handle' is added because 'replaceBetween' and + // 'doReplaceBetween' are already taken. + + /** + * Copies a substring of this object, retaining metadata. + * This method is used to duplicate or reorder substrings. + * The destination index must not overlap the source range. + * + * @param start the beginning index, inclusive; <code>0 <= start <= + * limit</code>. + * @param limit the ending index, exclusive; <code>start <= limit <= + * length()</code>. + * @param dest the destination index. The characters from + * <code>start..limit-1</code> will be copied to <code>dest</code>. + * Implementations of this method may assume that <code>dest <= start || + * dest >= limit</code>. + * @stable ICU 2.0 + */ + virtual void copy(int32_t start, int32_t limit, int32_t dest) = 0; + + /** + * Returns true if this object contains metadata. If a + * Replaceable object has metadata, calls to the Replaceable API + * must be made so as to preserve metadata. If it does not, calls + * to the Replaceable API may be optimized to improve performance. + * The default implementation returns true. + * @return true if this object contains metadata + * @stable ICU 2.2 + */ + virtual UBool hasMetaData() const; + + /** + * Clone this object, an instance of a subclass of Replaceable. + * Clones can be used concurrently in multiple threads. + * If a subclass does not implement clone(), or if an error occurs, + * then NULL is returned. + * The clone functions in all subclasses return a pointer to a Replaceable + * because some compilers do not support covariant (same-as-this) + * return types; cast to the appropriate subclass if necessary. + * The caller must delete the clone. + * + * @return a clone of this object + * + * @see getDynamicClassID + * @stable ICU 2.6 + */ + virtual Replaceable *clone() const; + +protected: + + /** + * Default constructor. + * @stable ICU 2.4 + */ + Replaceable(); + + /* + * Assignment operator not declared. The compiler will provide one + * which does nothing since this class does not contain any data members. + * API/code coverage may show the assignment operator as present and + * untested - ignore. + * Subclasses need this assignment operator if they use compiler-provided + * assignment operators of their own. An alternative to not declaring one + * here would be to declare and empty-implement a protected or public one. + Replaceable &Replaceable::operator=(const Replaceable &); + */ + + /** + * Virtual version of length(). + * @stable ICU 2.4 + */ + virtual int32_t getLength() const = 0; + + /** + * Virtual version of charAt(). + * @stable ICU 2.4 + */ + virtual UChar getCharAt(int32_t offset) const = 0; + + /** + * Virtual version of char32At(). + * @stable ICU 2.4 + */ + virtual UChar32 getChar32At(int32_t offset) const = 0; +}; + +inline int32_t +Replaceable::length() const { + return getLength(); +} + +inline UChar +Replaceable::charAt(int32_t offset) const { + return getCharAt(offset); +} + +inline UChar32 +Replaceable::char32At(int32_t offset) const { + return getChar32At(offset); +} + +// There is no rep.cpp, see unistr.cpp for Replaceable function implementations. + +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/resbund.h b/utils/openttd/unicode/resbund.h new file mode 100644 index 00000000000..6d6b991361b --- /dev/null +++ b/utils/openttd/unicode/resbund.h @@ -0,0 +1,485 @@ +/* +****************************************************************************** +* +* Copyright (C) 1996-2007, International Business Machines Corporation +* and others. All Rights Reserved. +* +****************************************************************************** +* +* File resbund.h +* +* CREATED BY +* Richard Gillam +* +* Modification History: +* +* Date Name Description +* 2/5/97 aliu Added scanForLocaleInFile. Added +* constructor which attempts to read resource bundle +* from a specific file, without searching other files. +* 2/11/97 aliu Added UErrorCode return values to constructors. Fixed +* infinite loops in scanForFile and scanForLocale. +* Modified getRawResourceData to not delete storage +* in localeData and resourceData which it doesn't own. +* Added Mac compatibility #ifdefs for tellp() and +* ios::nocreate. +* 2/18/97 helena Updated with 100% documentation coverage. +* 3/13/97 aliu Rewrote to load in entire resource bundle and store +* it as a Hashtable of ResourceBundleData objects. +* Added state table to govern parsing of files. +* Modified to load locale index out of new file +* distinct from default.txt. +* 3/25/97 aliu Modified to support 2-d arrays, needed for timezone +* data. Added support for custom file suffixes. Again, +* needed to support timezone data. +* 4/7/97 aliu Cleaned up. +* 03/02/99 stephen Removed dependency on FILE*. +* 03/29/99 helena Merged Bertrand and Stephen's changes. +* 06/11/99 stephen Removed parsing of .txt files. +* Reworked to use new binary format. +* Cleaned up. +* 06/14/99 stephen Removed methods taking a filename suffix. +* 11/09/99 weiv Added getLocale(), fRealLocale, removed fRealLocaleID +****************************************************************************** +*/ + +#ifndef RESBUND_H +#define RESBUND_H + +#include "unicode/utypes.h" +#include "unicode/uobject.h" +#include "unicode/ures.h" +#include "unicode/unistr.h" +#include "unicode/locid.h" + +/** + * \file + * \brief C++ API: Resource Bundle + */ + +U_NAMESPACE_BEGIN + +/** + * A class representing a collection of resource information pertaining to a given + * locale. A resource bundle provides a way of accessing locale- specfic information in + * a data file. You create a resource bundle that manages the resources for a given + * locale and then ask it for individual resources. + * <P> + * Resource bundles in ICU4C are currently defined using text files which conform to the following + * <a href="http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt">BNF definition</a>. + * More on resource bundle concepts and syntax can be found in the + * <a href="http://icu-project.org/userguide/ResourceManagement.html">Users Guide</a>. + * <P> + * + * The ResourceBundle class is not suitable for subclassing. + * + * @stable ICU 2.0 + */ +class U_COMMON_API ResourceBundle : public UObject { +public: + /** + * Constructor + * + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by <code> udata_open( packageName, "res", locale, err) </code> + * or equivalent. Typically, packageName will refer to a (.dat) file, or to + * a package registered with udata_setAppData(). Using a full file or directory + * pathname for packageName is deprecated. + * @param locale This is the locale this resource bundle is for. To get resources + * for the French locale, for example, you would create a + * ResourceBundle passing Locale::FRENCH for the "locale" parameter, + * and all subsequent calls to that resource bundle will return + * resources that pertain to the French locale. If the caller doesn't + * pass a locale parameter, the default locale for the system (as + * returned by Locale::getDefault()) will be used. + * @param err The Error Code. + * The UErrorCode& err parameter is used to return status information to the user. To + * check whether the construction succeeded or not, you should check the value of + * U_SUCCESS(err). If you wish more detailed information, you can check for + * informational error results which still indicate success. U_USING_FALLBACK_WARNING + * indicates that a fall back locale was used. For example, 'de_CH' was requested, + * but nothing was found there, so 'de' was used. U_USING_DEFAULT_WARNING indicates that + * the default locale data was used; neither the requested locale nor any of its + * fall back locales could be found. + * @stable ICU 2.0 + */ + ResourceBundle(const UnicodeString& packageName, + const Locale& locale, + UErrorCode& err); + + /** + * Construct a resource bundle for the default bundle in the specified package. + * + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by <code> udata_open( packageName, "res", locale, err) </code> + * or equivalent. Typically, packageName will refer to a (.dat) file, or to + * a package registered with udata_setAppData(). Using a full file or directory + * pathname for packageName is deprecated. + * @param err A UErrorCode value + * @stable ICU 2.0 + */ + ResourceBundle(const UnicodeString& packageName, + UErrorCode& err); + + /** + * Construct a resource bundle for the ICU default bundle. + * + * @param err A UErrorCode value + * @stable ICU 2.0 + */ + ResourceBundle(UErrorCode &err); + + /** + * Standard constructor, onstructs a resource bundle for the locale-specific + * bundle in the specified package. + * + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by <code> udata_open( packageName, "res", locale, err) </code> + * or equivalent. Typically, packageName will refer to a (.dat) file, or to + * a package registered with udata_setAppData(). Using a full file or directory + * pathname for packageName is deprecated. + * NULL is used to refer to ICU data. + * @param locale The locale for which to open a resource bundle. + * @param err A UErrorCode value + * @stable ICU 2.0 + */ + ResourceBundle(const char* packageName, + const Locale& locale, + UErrorCode& err); + + /** + * Copy constructor. + * + * @param original The resource bundle to copy. + * @stable ICU 2.0 + */ + ResourceBundle(const ResourceBundle &original); + + /** + * Constructor from a C UResourceBundle. The resource bundle is + * copied and not adopted. ures_close will still need to be used on the + * original resource bundle. + * + * @param res A pointer to the C resource bundle. + * @param status A UErrorCode value. + * @stable ICU 2.0 + */ + ResourceBundle(UResourceBundle *res, + UErrorCode &status); + + /** + * Assignment operator. + * + * @param other The resource bundle to copy. + * @stable ICU 2.0 + */ + ResourceBundle& + operator=(const ResourceBundle& other); + + /** Destructor. + * @stable ICU 2.0 + */ + virtual ~ResourceBundle(); + + /** + * Clone this object. + * Clones can be used concurrently in multiple threads. + * If an error occurs, then NULL is returned. + * The caller must delete the clone. + * + * @return a clone of this object + * + * @see getDynamicClassID + * @stable ICU 2.8 + */ + ResourceBundle *clone() const; + + /** + * Returns the size of a resource. Size for scalar types is always 1, and for vector/table types is + * the number of child resources. + * @warning Integer array is treated as a scalar type. There are no + * APIs to access individual members of an integer array. It + * is always returned as a whole. + * + * @return number of resources in a given resource. + * @stable ICU 2.0 + */ + int32_t + getSize(void) const; + + /** + * returns a string from a string resource type + * + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * could be a warning + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. + * @stable ICU 2.0 + */ + UnicodeString + getString(UErrorCode& status) const; + + /** + * returns a binary data from a resource. Can be used at most primitive resource types (binaries, + * strings, ints) + * + * @param len fills in the length of resulting byte chunk + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * could be a warning + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file. + * @stable ICU 2.0 + */ + const uint8_t* + getBinary(int32_t& len, UErrorCode& status) const; + + + /** + * returns an integer vector from a resource. + * + * @param len fills in the length of resulting integer vector + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * could be a warning + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return a pointer to a vector of integers that lives in a memory mapped/DLL file. + * @stable ICU 2.0 + */ + const int32_t* + getIntVector(int32_t& len, UErrorCode& status) const; + + /** + * returns an unsigned integer from a resource. + * This integer is originally 28 bits. + * + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * could be a warning + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return an unsigned integer value + * @stable ICU 2.0 + */ + uint32_t + getUInt(UErrorCode& status) const; + + /** + * returns a signed integer from a resource. + * This integer is originally 28 bit and the sign gets propagated. + * + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * could be a warning + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return a signed integer value + * @stable ICU 2.0 + */ + int32_t + getInt(UErrorCode& status) const; + + /** + * Checks whether the resource has another element to iterate over. + * + * @return TRUE if there are more elements, FALSE if there is no more elements + * @stable ICU 2.0 + */ + UBool + hasNext(void) const; + + /** + * Resets the internal context of a resource so that iteration starts from the first element. + * + * @stable ICU 2.0 + */ + void + resetIterator(void); + + /** + * Returns the key associated with this resource. Not all the resources have a key - only + * those that are members of a table. + * + * @return a key associated to this resource, or NULL if it doesn't have a key + * @stable ICU 2.0 + */ + const char* + getKey(void) const; + + /** + * Gets the locale ID of the resource bundle as a string. + * Same as getLocale().getName() . + * + * @return the locale ID of the resource bundle as a string + * @stable ICU 2.0 + */ + const char* + getName(void) const; + + + /** + * Returns the type of a resource. Available types are defined in enum UResType + * + * @return type of the given resource. + * @stable ICU 2.0 + */ + UResType + getType(void) const; + + /** + * Returns the next resource in a given resource or NULL if there are no more resources + * + * @param status fills in the outgoing error code + * @return ResourceBundle object. + * @stable ICU 2.0 + */ + ResourceBundle + getNext(UErrorCode& status); + + /** + * Returns the next string in a resource or NULL if there are no more resources + * to iterate over. + * + * @param status fills in the outgoing error code + * @return an UnicodeString object. + * @stable ICU 2.0 + */ + UnicodeString + getNextString(UErrorCode& status); + + /** + * Returns the next string in a resource or NULL if there are no more resources + * to iterate over. + * + * @param key fill in for key associated with this string + * @param status fills in the outgoing error code + * @return an UnicodeString object. + * @stable ICU 2.0 + */ + UnicodeString + getNextString(const char ** key, + UErrorCode& status); + + /** + * Returns the resource in a resource at the specified index. + * + * @param index an index to the wanted resource. + * @param status fills in the outgoing error code + * @return ResourceBundle object. If there is an error, resource is invalid. + * @stable ICU 2.0 + */ + ResourceBundle + get(int32_t index, + UErrorCode& status) const; + + /** + * Returns the string in a given resource at the specified index. + * + * @param index an index to the wanted string. + * @param status fills in the outgoing error code + * @return an UnicodeString object. If there is an error, string is bogus + * @stable ICU 2.0 + */ + UnicodeString + getStringEx(int32_t index, + UErrorCode& status) const; + + /** + * Returns a resource in a resource that has a given key. This procedure works only with table + * resources. + * + * @param key a key associated with the wanted resource + * @param status fills in the outgoing error code. + * @return ResourceBundle object. If there is an error, resource is invalid. + * @stable ICU 2.0 + */ + ResourceBundle + get(const char* key, + UErrorCode& status) const; + + /** + * Returns a string in a resource that has a given key. This procedure works only with table + * resources. + * + * @param key a key associated with the wanted string + * @param status fills in the outgoing error code + * @return an UnicodeString object. If there is an error, string is bogus + * @stable ICU 2.0 + */ + UnicodeString + getStringEx(const char* key, + UErrorCode& status) const; + + /** + * Return the version number associated with this ResourceBundle as a string. Please + * use getVersion, as this method is going to be deprecated. + * + * @return A version number string as specified in the resource bundle or its parent. + * The caller does not own this string. + * @see getVersion + * @deprecated ICU 2.8 Use getVersion instead. + */ + const char* + getVersionNumber(void) const; + + /** + * Return the version number associated with this ResourceBundle as a UVersionInfo array. + * + * @param versionInfo A UVersionInfo array that is filled with the version number + * as specified in the resource bundle or its parent. + * @stable ICU 2.0 + */ + void + getVersion(UVersionInfo versionInfo) const; + + /** + * Return the Locale associated with this ResourceBundle. + * + * @return a Locale object + * @deprecated ICU 2.8 Use getLocale(ULocDataLocaleType type, UErrorCode &status) overload instead. + */ + const Locale& + getLocale(void) const; + + /** + * Return the Locale associated with this ResourceBundle. + * @param type You can choose between requested, valid and actual + * locale. For description see the definition of + * ULocDataLocaleType in uloc.h + * @param status just for catching illegal arguments + * + * @return a Locale object + * @stable ICU 2.8 + */ + const Locale + getLocale(ULocDataLocaleType type, UErrorCode &status) const; + /** + * This API implements multilevel fallback + * @internal + */ + ResourceBundle + getWithFallback(const char* key, UErrorCode& status); + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.2 + */ + virtual UClassID getDynamicClassID() const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.2 + */ + static UClassID U_EXPORT2 getStaticClassID(); + +private: + ResourceBundle(); // default constructor not implemented + + UResourceBundle *fResource; + void constructForLocale(const UnicodeString& path, const Locale& locale, UErrorCode& error); + Locale *fLocale; + +}; + +U_NAMESPACE_END +#endif diff --git a/utils/openttd/unicode/schriter.h b/utils/openttd/unicode/schriter.h new file mode 100644 index 00000000000..d0b5e22503c --- /dev/null +++ b/utils/openttd/unicode/schriter.h @@ -0,0 +1,187 @@ +/* +****************************************************************************** +* +* Copyright (C) 1998-2005, International Business Machines +* Corporation and others. All Rights Reserved. +* +****************************************************************************** +* +* File schriter.h +* +* Modification History: +* +* Date Name Description +* 05/05/99 stephen Cleaned up. +****************************************************************************** +*/ + +#ifndef SCHRITER_H +#define SCHRITER_H + +#include "unicode/utypes.h" +#include "unicode/chariter.h" +#include "unicode/uchriter.h" + +/** + * \file + * \brief C++ API: String Character Iterator + */ + +U_NAMESPACE_BEGIN +/** + * A concrete subclass of CharacterIterator that iterates over the + * characters (code units or code points) in a UnicodeString. + * It's possible not only to create an + * iterator that iterates over an entire UnicodeString, but also to + * create one that iterates over only a subrange of a UnicodeString + * (iterators over different subranges of the same UnicodeString don't + * compare equal). + * @see CharacterIterator + * @see ForwardCharacterIterator + * @stable ICU 2.0 + */ +class U_COMMON_API StringCharacterIterator : public UCharCharacterIterator { +public: + /** + * Create an iterator over the UnicodeString referred to by "textStr". + * The UnicodeString object is copied. + * The iteration range is the whole string, and the starting position is 0. + * @param textStr The unicode string used to create an iterator + * @stable ICU 2.0 + */ + StringCharacterIterator(const UnicodeString& textStr); + + /** + * Create an iterator over the UnicodeString referred to by "textStr". + * The iteration range is the whole string, and the starting + * position is specified by "textPos". If "textPos" is outside the valid + * iteration range, the behavior of this object is undefined. + * @param textStr The unicode string used to create an iterator + * @param textPos The starting position of the iteration + * @stable ICU 2.0 + */ + StringCharacterIterator(const UnicodeString& textStr, + int32_t textPos); + + /** + * Create an iterator over the UnicodeString referred to by "textStr". + * The UnicodeString object is copied. + * The iteration range begins with the code unit specified by + * "textBegin" and ends with the code unit BEFORE the code unit specfied + * by "textEnd". The starting position is specified by "textPos". If + * "textBegin" and "textEnd" don't form a valid range on "text" (i.e., + * textBegin >= textEnd or either is negative or greater than text.size()), + * or "textPos" is outside the range defined by "textBegin" and "textEnd", + * the behavior of this iterator is undefined. + * @param textStr The unicode string used to create the StringCharacterIterator + * @param textBegin The begin position of the iteration range + * @param textEnd The end position of the iteration range + * @param textPos The starting position of the iteration + * @stable ICU 2.0 + */ + StringCharacterIterator(const UnicodeString& textStr, + int32_t textBegin, + int32_t textEnd, + int32_t textPos); + + /** + * Copy constructor. The new iterator iterates over the same range + * of the same string as "that", and its initial position is the + * same as "that"'s current position. + * The UnicodeString object in "that" is copied. + * @param that The StringCharacterIterator to be copied + * @stable ICU 2.0 + */ + StringCharacterIterator(const StringCharacterIterator& that); + + /** + * Destructor. + * @stable ICU 2.0 + */ + virtual ~StringCharacterIterator(); + + /** + * Assignment operator. *this is altered to iterate over the same + * range of the same string as "that", and refers to the same + * character within that string as "that" does. + * @param that The object to be copied. + * @return the newly created object. + * @stable ICU 2.0 + */ + StringCharacterIterator& + operator=(const StringCharacterIterator& that); + + /** + * Returns true if the iterators iterate over the same range of the + * same string and are pointing at the same character. + * @param that The ForwardCharacterIterator to be compared for equality + * @return true if the iterators iterate over the same range of the + * same string and are pointing at the same character. + * @stable ICU 2.0 + */ + virtual UBool operator==(const ForwardCharacterIterator& that) const; + + /** + * Returns a new StringCharacterIterator referring to the same + * character in the same range of the same string as this one. The + * caller must delete the new iterator. + * @return the newly cloned object. + * @stable ICU 2.0 + */ + virtual CharacterIterator* clone(void) const; + + /** + * Sets the iterator to iterate over the provided string. + * @param newText The string to be iterated over + * @stable ICU 2.0 + */ + void setText(const UnicodeString& newText); + + /** + * Copies the UnicodeString under iteration into the UnicodeString + * referred to by "result". Even if this iterator iterates across + * only a part of this string, the whole string is copied. + * @param result Receives a copy of the text under iteration. + * @stable ICU 2.0 + */ + virtual void getText(UnicodeString& result); + + /** + * Return a class ID for this object (not really public) + * @return a class ID for this object. + * @stable ICU 2.0 + */ + virtual UClassID getDynamicClassID(void) const; + + /** + * Return a class ID for this class (not really public) + * @return a class ID for this class + * @stable ICU 2.0 + */ + static UClassID U_EXPORT2 getStaticClassID(void); + +protected: + /** + * Default constructor, iteration over empty string. + * @stable ICU 2.0 + */ + StringCharacterIterator(); + + /** + * Sets the iterator to iterate over the provided string. + * @param newText The string to be iterated over + * @param newTextLength The length of the String + * @stable ICU 2.0 + */ + void setText(const UChar* newText, int32_t newTextLength); + + /** + * Copy of the iterated string object. + * @stable ICU 2.0 + */ + UnicodeString text; + +}; + +U_NAMESPACE_END +#endif diff --git a/utils/openttd/unicode/strenum.h b/utils/openttd/unicode/strenum.h new file mode 100644 index 00000000000..ce42195a4f2 --- /dev/null +++ b/utils/openttd/unicode/strenum.h @@ -0,0 +1,271 @@ +/* +******************************************************************************* +* +* Copyright (C) 2002-2007, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +*/ + +#ifndef STRENUM_H +#define STRENUM_H + +#include "unicode/uobject.h" +#include "unicode/unistr.h" + +/** + * \file + * \brief C++ API: String Enumeration + */ + +U_NAMESPACE_BEGIN + +/** + * Base class for 'pure' C++ implementations of uenum api. Adds a + * method that returns the next UnicodeString since in C++ this can + * be a common storage format for strings. + * + * <p>The model is that the enumeration is over strings maintained by + * a 'service.' At any point, the service might change, invalidating + * the enumerator (though this is expected to be rare). The iterator + * returns an error if this has occurred. Lack of the error is no + * guarantee that the service didn't change immediately after the + * call, so the returned string still might not be 'valid' on + * subsequent use.</p> + * + * <p>Strings may take the form of const char*, const UChar*, or const + * UnicodeString*. The type you get is determine by the variant of + * 'next' that you call. In general the StringEnumeration is + * optimized for one of these types, but all StringEnumerations can + * return all types. Returned strings are each terminated with a NUL. + * Depending on the service data, they might also include embedded NUL + * characters, so API is provided to optionally return the true + * length, counting the embedded NULs but not counting the terminating + * NUL.</p> + * + * <p>The pointers returned by next, unext, and snext become invalid + * upon any subsequent call to the enumeration's destructor, next, + * unext, snext, or reset.</p> + * + * ICU 2.8 adds some default implementations and helper functions + * for subclasses. + * + * @stable ICU 2.4 + */ +class U_COMMON_API StringEnumeration : public UObject { +public: + /** + * Destructor. + * @stable ICU 2.4 + */ + virtual ~StringEnumeration(); + + /** + * Clone this object, an instance of a subclass of StringEnumeration. + * Clones can be used concurrently in multiple threads. + * If a subclass does not implement clone(), or if an error occurs, + * then NULL is returned. + * The clone functions in all subclasses return a base class pointer + * because some compilers do not support covariant (same-as-this) + * return types; cast to the appropriate subclass if necessary. + * The caller must delete the clone. + * + * @return a clone of this object + * + * @see getDynamicClassID + * @stable ICU 2.8 + */ + virtual StringEnumeration *clone() const; + + /** + * <p>Return the number of elements that the iterator traverses. If + * the iterator is out of sync with its service, status is set to + * U_ENUM_OUT_OF_SYNC_ERROR, and the return value is zero.</p> + * + * <p>The return value will not change except possibly as a result of + * a subsequent call to reset, or if the iterator becomes out of sync.</p> + * + * <p>This is a convenience function. It can end up being very + * expensive as all the items might have to be pre-fetched + * (depending on the storage format of the data being + * traversed).</p> + * + * @param status the error code. + * @return number of elements in the iterator. + * + * @stable ICU 2.4 */ + virtual int32_t count(UErrorCode& status) const = 0; + + /** + * <p>Returns the next element as a NUL-terminated char*. If there + * are no more elements, returns NULL. If the resultLength pointer + * is not NULL, the length of the string (not counting the + * terminating NUL) is returned at that address. If an error + * status is returned, the value at resultLength is undefined.</p> + * + * <p>The returned pointer is owned by this iterator and must not be + * deleted by the caller. The pointer is valid until the next call + * to next, unext, snext, reset, or the enumerator's destructor.</p> + * + * <p>If the iterator is out of sync with its service, status is set + * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p> + * + * <p>If the native service string is a UChar* string, it is + * converted to char* with the invariant converter. If the + * conversion fails (because a character cannot be converted) then + * status is set to U_INVARIANT_CONVERSION_ERROR and the return + * value is undefined (though not NULL).</p> + * + * Starting with ICU 2.8, the default implementation calls snext() + * and handles the conversion. + * + * @param status the error code. + * @param resultLength a pointer to receive the length, can be NULL. + * @return a pointer to the string, or NULL. + * + * @stable ICU 2.4 + */ + virtual const char* next(int32_t *resultLength, UErrorCode& status); + + /** + * <p>Returns the next element as a NUL-terminated UChar*. If there + * are no more elements, returns NULL. If the resultLength pointer + * is not NULL, the length of the string (not counting the + * terminating NUL) is returned at that address. If an error + * status is returned, the value at resultLength is undefined.</p> + * + * <p>The returned pointer is owned by this iterator and must not be + * deleted by the caller. The pointer is valid until the next call + * to next, unext, snext, reset, or the enumerator's destructor.</p> + * + * <p>If the iterator is out of sync with its service, status is set + * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p> + * + * Starting with ICU 2.8, the default implementation calls snext() + * and handles the conversion. + * + * @param status the error code. + * @param resultLength a ponter to receive the length, can be NULL. + * @return a pointer to the string, or NULL. + * + * @stable ICU 2.4 + */ + virtual const UChar* unext(int32_t *resultLength, UErrorCode& status); + + /** + * <p>Returns the next element a UnicodeString*. If there are no + * more elements, returns NULL.</p> + * + * <p>The returned pointer is owned by this iterator and must not be + * deleted by the caller. The pointer is valid until the next call + * to next, unext, snext, reset, or the enumerator's destructor.</p> + * + * <p>If the iterator is out of sync with its service, status is set + * to U_ENUM_OUT_OF_SYNC_ERROR and NULL is returned.</p> + * + * @param status the error code. + * @return a pointer to the string, or NULL. + * + * @stable ICU 2.4 + */ + virtual const UnicodeString* snext(UErrorCode& status) = 0; + + /** + * <p>Resets the iterator. This re-establishes sync with the + * service and rewinds the iterator to start at the first + * element.</p> + * + * <p>Previous pointers returned by next, unext, or snext become + * invalid, and the value returned by count might change.</p> + * + * @param status the error code. + * + * @stable ICU 2.4 + */ + virtual void reset(UErrorCode& status) = 0; + + /** + * Compares this enumeration to other to check if both are equal + * + * @param that The other string enumeration to compare this object to + * @return TRUE if the enumerations are equal. FALSE if not. + * @stable ICU 3.6 + */ + virtual UBool operator==(const StringEnumeration& that)const; + /** + * Compares this enumeration to other to check if both are not equal + * + * @param that The other string enumeration to compare this object to + * @return TRUE if the enumerations are equal. FALSE if not. + * @stable ICU 3.6 + */ + virtual UBool operator!=(const StringEnumeration& that)const; + +protected: + /** + * UnicodeString field for use with default implementations and subclasses. + * @stable ICU 2.8 + */ + UnicodeString unistr; + /** + * char * default buffer for use with default implementations and subclasses. + * @stable ICU 2.8 + */ + char charsBuffer[32]; + /** + * char * buffer for use with default implementations and subclasses. + * Allocated in constructor and in ensureCharsCapacity(). + * @stable ICU 2.8 + */ + char *chars; + /** + * Capacity of chars, for use with default implementations and subclasses. + * @stable ICU 2.8 + */ + int32_t charsCapacity; + + /** + * Default constructor for use with default implementations and subclasses. + * @stable ICU 2.8 + */ + StringEnumeration(); + + /** + * Ensures that chars is at least as large as the requested capacity. + * For use with default implementations and subclasses. + * + * @param capacity Requested capacity. + * @param status ICU in/out error code. + * @stable ICU 2.8 + */ + void ensureCharsCapacity(int32_t capacity, UErrorCode &status); + + /** + * Converts s to Unicode and sets unistr to the result. + * For use with default implementations and subclasses, + * especially for implementations of snext() in terms of next(). + * This is provided with a helper function instead of a default implementation + * of snext() to avoid potential infinite loops between next() and snext(). + * + * For example: + * \code + * const UnicodeString* snext(UErrorCode& status) { + * int32_t resultLength=0; + * const char *s=next(&resultLength, status); + * return setChars(s, resultLength, status); + * } + * \endcode + * + * @param s String to be converted to Unicode. + * @param length Length of the string. + * @param status ICU in/out error code. + * @return A pointer to unistr. + * @stable ICU 2.8 + */ + UnicodeString *setChars(const char *s, int32_t length, UErrorCode &status); +}; + +U_NAMESPACE_END + +/* STRENUM_H */ +#endif diff --git a/utils/openttd/unicode/symtable.h b/utils/openttd/unicode/symtable.h new file mode 100644 index 00000000000..428f8bff23e --- /dev/null +++ b/utils/openttd/unicode/symtable.h @@ -0,0 +1,112 @@ +/* +********************************************************************** +* Copyright (c) 2000-2005, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* Date Name Description +* 02/04/00 aliu Creation. +********************************************************************** +*/ +#ifndef SYMTABLE_H +#define SYMTABLE_H + +#include "unicode/utypes.h" +#include "unicode/uobject.h" + +/** + * \file + * \brief C++ API: An interface that defines both lookup protocol and parsing of + * symbolic names. + */ + +U_NAMESPACE_BEGIN + +class ParsePosition; +class UnicodeFunctor; +class UnicodeSet; +class UnicodeString; + +/** + * An interface that defines both lookup protocol and parsing of + * symbolic names. + * + * <p>A symbol table maintains two kinds of mappings. The first is + * between symbolic names and their values. For example, if the + * variable with the name "start" is set to the value "alpha" + * (perhaps, though not necessarily, through an expression such as + * "$start=alpha"), then the call lookup("start") will return the + * char[] array ['a', 'l', 'p', 'h', 'a']. + * + * <p>The second kind of mapping is between character values and + * UnicodeMatcher objects. This is used by RuleBasedTransliterator, + * which uses characters in the private use area to represent objects + * such as UnicodeSets. If U+E015 is mapped to the UnicodeSet [a-z], + * then lookupMatcher(0xE015) will return the UnicodeSet [a-z]. + * + * <p>Finally, a symbol table defines parsing behavior for symbolic + * names. All symbolic names start with the SYMBOL_REF character. + * When a parser encounters this character, it calls parseReference() + * with the position immediately following the SYMBOL_REF. The symbol + * table parses the name, if there is one, and returns it. + * + * @stable ICU 2.8 + */ +class U_COMMON_API SymbolTable /* not : public UObject because this is an interface/mixin class */ { +public: + + /** + * The character preceding a symbol reference name. + * @stable ICU 2.8 + */ + enum { SYMBOL_REF = 0x0024 /*$*/ }; + + /** + * Destructor. + * @stable ICU 2.8 + */ + virtual ~SymbolTable(); + + /** + * Lookup the characters associated with this string and return it. + * Return <tt>NULL</tt> if no such name exists. The resultant + * string may have length zero. + * @param s the symbolic name to lookup + * @return a string containing the name's value, or <tt>NULL</tt> if + * there is no mapping for s. + * @stable ICU 2.8 + */ + virtual const UnicodeString* lookup(const UnicodeString& s) const = 0; + + /** + * Lookup the UnicodeMatcher associated with the given character, and + * return it. Return <tt>NULL</tt> if not found. + * @param ch a 32-bit code point from 0 to 0x10FFFF inclusive. + * @return the UnicodeMatcher object represented by the given + * character, or NULL if there is no mapping for ch. + * @stable ICU 2.8 + */ + virtual const UnicodeFunctor* lookupMatcher(UChar32 ch) const = 0; + + /** + * Parse a symbol reference name from the given string, starting + * at the given position. If no valid symbol reference name is + * found, return the empty string and leave pos unchanged. That is, if the + * character at pos cannot start a name, or if pos is at or after + * text.length(), then return an empty string. This indicates an + * isolated SYMBOL_REF character. + * @param text the text to parse for the name + * @param pos on entry, the index of the first character to parse. + * This is the character following the SYMBOL_REF character. On + * exit, the index after the last parsed character. If the parse + * failed, pos is unchanged on exit. + * @param limit the index after the last character to be parsed. + * @return the parsed name, or an empty string if there is no + * valid symbolic name at the given position. + * @stable ICU 2.8 + */ + virtual UnicodeString parseReference(const UnicodeString& text, + ParsePosition& pos, int32_t limit) const = 0; +}; +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/ubidi.h b/utils/openttd/unicode/ubidi.h new file mode 100644 index 00000000000..25f22b93ef2 --- /dev/null +++ b/utils/openttd/unicode/ubidi.h @@ -0,0 +1,2013 @@ +/* +****************************************************************************** +* +* Copyright (C) 1999-2008, International Business Machines +* Corporation and others. All Rights Reserved. +* +****************************************************************************** +* file name: ubidi.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 1999jul27 +* created by: Markus W. Scherer, updated by Matitiahu Allouche +*/ + +#ifndef UBIDI_H +#define UBIDI_H + +#include "unicode/utypes.h" +#include "unicode/uchar.h" + +/** + *\file + * \brief C API: Bidi algorithm + * + * <h2>Bidi algorithm for ICU</h2> + * + * This is an implementation of the Unicode Bidirectional algorithm. + * The algorithm is defined in the + * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Annex #9</a>, + * version 13, also described in The Unicode Standard, Version 4.0 .<p> + * + * Note: Libraries that perform a bidirectional algorithm and + * reorder strings accordingly are sometimes called "Storage Layout Engines". + * ICU's Bidi and shaping (u_shapeArabic()) APIs can be used at the core of such + * "Storage Layout Engines". + * + * <h3>General remarks about the API:</h3> + * + * In functions with an error code parameter, + * the <code>pErrorCode</code> pointer must be valid + * and the value that it points to must not indicate a failure before + * the function call. Otherwise, the function returns immediately. + * After the function call, the value indicates success or failure.<p> + * + * The "limit" of a sequence of characters is the position just after their + * last character, i.e., one more than that position.<p> + * + * Some of the API functions provide access to "runs". + * Such a "run" is defined as a sequence of characters + * that are at the same embedding level + * after performing the Bidi algorithm.<p> + * + * @author Markus W. Scherer + * @version 1.0 + * + * + * <h4> Sample code for the ICU Bidi API </h4> + * + * <h5>Rendering a paragraph with the ICU Bidi API</h5> + * + * This is (hypothetical) sample code that illustrates + * how the ICU Bidi API could be used to render a paragraph of text. + * Rendering code depends highly on the graphics system, + * therefore this sample code must make a lot of assumptions, + * which may or may not match any existing graphics system's properties. + * + * <p>The basic assumptions are:</p> + * <ul> + * <li>Rendering is done from left to right on a horizontal line.</li> + * <li>A run of single-style, unidirectional text can be rendered at once.</li> + * <li>Such a run of text is passed to the graphics system with + * characters (code units) in logical order.</li> + * <li>The line-breaking algorithm is very complicated + * and Locale-dependent - + * and therefore its implementation omitted from this sample code.</li> + * </ul> + * + * <pre> + * \code + *#include "unicode/ubidi.h" + * + *typedef enum { + * styleNormal=0, styleSelected=1, + * styleBold=2, styleItalics=4, + * styleSuper=8, styleSub=16 + *} Style; + * + *typedef struct { int32_t limit; Style style; } StyleRun; + * + *int getTextWidth(const UChar *text, int32_t start, int32_t limit, + * const StyleRun *styleRuns, int styleRunCount); + * + * // set *pLimit and *pStyleRunLimit for a line + * // from text[start] and from styleRuns[styleRunStart] + * // using ubidi_getLogicalRun(para, ...) + *void getLineBreak(const UChar *text, int32_t start, int32_t *pLimit, + * UBiDi *para, + * const StyleRun *styleRuns, int styleRunStart, int *pStyleRunLimit, + * int *pLineWidth); + * + * // render runs on a line sequentially, always from left to right + * + * // prepare rendering a new line + * void startLine(UBiDiDirection textDirection, int lineWidth); + * + * // render a run of text and advance to the right by the run width + * // the text[start..limit-1] is always in logical order + * void renderRun(const UChar *text, int32_t start, int32_t limit, + * UBiDiDirection textDirection, Style style); + * + * // We could compute a cross-product + * // from the style runs with the directional runs + * // and then reorder it. + * // Instead, here we iterate over each run type + * // and render the intersections - + * // with shortcuts in simple (and common) cases. + * // renderParagraph() is the main function. + * + * // render a directional run with + * // (possibly) multiple style runs intersecting with it + * void renderDirectionalRun(const UChar *text, + * int32_t start, int32_t limit, + * UBiDiDirection direction, + * const StyleRun *styleRuns, int styleRunCount) { + * int i; + * + * // iterate over style runs + * if(direction==UBIDI_LTR) { + * int styleLimit; + * + * for(i=0; i<styleRunCount; ++i) { + * styleLimit=styleRun[i].limit; + * if(start<styleLimit) { + * if(styleLimit>limit) { styleLimit=limit; } + * renderRun(text, start, styleLimit, + * direction, styleRun[i].style); + * if(styleLimit==limit) { break; } + * start=styleLimit; + * } + * } + * } else { + * int styleStart; + * + * for(i=styleRunCount-1; i>=0; --i) { + * if(i>0) { + * styleStart=styleRun[i-1].limit; + * } else { + * styleStart=0; + * } + * if(limit>=styleStart) { + * if(styleStart<start) { styleStart=start; } + * renderRun(text, styleStart, limit, + * direction, styleRun[i].style); + * if(styleStart==start) { break; } + * limit=styleStart; + * } + * } + * } + * } + * + * // the line object represents text[start..limit-1] + * void renderLine(UBiDi *line, const UChar *text, + * int32_t start, int32_t limit, + * const StyleRun *styleRuns, int styleRunCount) { + * UBiDiDirection direction=ubidi_getDirection(line); + * if(direction!=UBIDI_MIXED) { + * // unidirectional + * if(styleRunCount<=1) { + * renderRun(text, start, limit, direction, styleRuns[0].style); + * } else { + * renderDirectionalRun(text, start, limit, + * direction, styleRuns, styleRunCount); + * } + * } else { + * // mixed-directional + * int32_t count, i, length; + * UBiDiLevel level; + * + * count=ubidi_countRuns(para, pErrorCode); + * if(U_SUCCESS(*pErrorCode)) { + * if(styleRunCount<=1) { + * Style style=styleRuns[0].style; + * + * // iterate over directional runs + * for(i=0; i<count; ++i) { + * direction=ubidi_getVisualRun(para, i, &start, &length); + * renderRun(text, start, start+length, direction, style); + * } + * } else { + * int32_t j; + * + * // iterate over both directional and style runs + * for(i=0; i<count; ++i) { + * direction=ubidi_getVisualRun(line, i, &start, &length); + * renderDirectionalRun(text, start, start+length, + * direction, styleRuns, styleRunCount); + * } + * } + * } + * } + * } + * + *void renderParagraph(const UChar *text, int32_t length, + * UBiDiDirection textDirection, + * const StyleRun *styleRuns, int styleRunCount, + * int lineWidth, + * UErrorCode *pErrorCode) { + * UBiDi *para; + * + * if(pErrorCode==NULL || U_FAILURE(*pErrorCode) || length<=0) { + * return; + * } + * + * para=ubidi_openSized(length, 0, pErrorCode); + * if(para==NULL) { return; } + * + * ubidi_setPara(para, text, length, + * textDirection ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, + * NULL, pErrorCode); + * if(U_SUCCESS(*pErrorCode)) { + * UBiDiLevel paraLevel=1&ubidi_getParaLevel(para); + * StyleRun styleRun={ length, styleNormal }; + * int width; + * + * if(styleRuns==NULL || styleRunCount<=0) { + * styleRunCount=1; + * styleRuns=&styleRun; + * } + * + * // assume styleRuns[styleRunCount-1].limit>=length + * + * width=getTextWidth(text, 0, length, styleRuns, styleRunCount); + * if(width<=lineWidth) { + * // everything fits onto one line + * + * // prepare rendering a new line from either left or right + * startLine(paraLevel, width); + * + * renderLine(para, text, 0, length, + * styleRuns, styleRunCount); + * } else { + * UBiDi *line; + * + * // we need to render several lines + * line=ubidi_openSized(length, 0, pErrorCode); + * if(line!=NULL) { + * int32_t start=0, limit; + * int styleRunStart=0, styleRunLimit; + * + * for(;;) { + * limit=length; + * styleRunLimit=styleRunCount; + * getLineBreak(text, start, &limit, para, + * styleRuns, styleRunStart, &styleRunLimit, + * &width); + * ubidi_setLine(para, start, limit, line, pErrorCode); + * if(U_SUCCESS(*pErrorCode)) { + * // prepare rendering a new line + * // from either left or right + * startLine(paraLevel, width); + * + * renderLine(line, text, start, limit, + * styleRuns+styleRunStart, + * styleRunLimit-styleRunStart); + * } + * if(limit==length) { break; } + * start=limit; + * styleRunStart=styleRunLimit-1; + * if(start>=styleRuns[styleRunStart].limit) { + * ++styleRunStart; + * } + * } + * + * ubidi_close(line); + * } + * } + * } + * + * ubidi_close(para); + *} + *\endcode + * </pre> + */ + +/*DOCXX_TAG*/ +/*@{*/ + +/** + * UBiDiLevel is the type of the level values in this + * Bidi implementation. + * It holds an embedding level and indicates the visual direction + * by its bit 0 (even/odd value).<p> + * + * It can also hold non-level values for the + * <code>paraLevel</code> and <code>embeddingLevels</code> + * arguments of <code>ubidi_setPara()</code>; there: + * <ul> + * <li>bit 7 of an <code>embeddingLevels[]</code> + * value indicates whether the using application is + * specifying the level of a character to <i>override</i> whatever the + * Bidi implementation would resolve it to.</li> + * <li><code>paraLevel</code> can be set to the + * pseudo-level values <code>UBIDI_DEFAULT_LTR</code> + * and <code>UBIDI_DEFAULT_RTL</code>.</li> + * </ul> + * + * @see ubidi_setPara + * + * <p>The related constants are not real, valid level values. + * <code>UBIDI_DEFAULT_XXX</code> can be used to specify + * a default for the paragraph level for + * when the <code>ubidi_setPara()</code> function + * shall determine it but there is no + * strongly typed character in the input.<p> + * + * Note that the value for <code>UBIDI_DEFAULT_LTR</code> is even + * and the one for <code>UBIDI_DEFAULT_RTL</code> is odd, + * just like with normal LTR and RTL level values - + * these special values are designed that way. Also, the implementation + * assumes that UBIDI_MAX_EXPLICIT_LEVEL is odd. + * + * @see UBIDI_DEFAULT_LTR + * @see UBIDI_DEFAULT_RTL + * @see UBIDI_LEVEL_OVERRIDE + * @see UBIDI_MAX_EXPLICIT_LEVEL + * @stable ICU 2.0 + */ +typedef uint8_t UBiDiLevel; + +/** Paragraph level setting.<p> + * + * Constant indicating that the base direction depends on the first strong + * directional character in the text according to the Unicode Bidirectional + * Algorithm. If no strong directional character is present, + * then set the paragraph level to 0 (left-to-right).<p> + * + * If this value is used in conjunction with reordering modes + * <code>UBIDI_REORDER_INVERSE_LIKE_DIRECT</code> or + * <code>UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code>, the text to reorder + * is assumed to be visual LTR, and the text after reordering is required + * to be the corresponding logical string with appropriate contextual + * direction. The direction of the result string will be RTL if either + * the righmost or leftmost strong character of the source text is RTL + * or Arabic Letter, the direction will be LTR otherwise.<p> + * + * If reordering option <code>UBIDI_OPTION_INSERT_MARKS</code> is set, an RLM may + * be added at the beginning of the result string to ensure round trip + * (that the result string, when reordered back to visual, will produce + * the original source text). + * @see UBIDI_REORDER_INVERSE_LIKE_DIRECT + * @see UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL + * @stable ICU 2.0 + */ +#define UBIDI_DEFAULT_LTR 0xfe + +/** Paragraph level setting.<p> + * + * Constant indicating that the base direction depends on the first strong + * directional character in the text according to the Unicode Bidirectional + * Algorithm. If no strong directional character is present, + * then set the paragraph level to 1 (right-to-left).<p> + * + * If this value is used in conjunction with reordering modes + * <code>UBIDI_REORDER_INVERSE_LIKE_DIRECT</code> or + * <code>UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code>, the text to reorder + * is assumed to be visual LTR, and the text after reordering is required + * to be the corresponding logical string with appropriate contextual + * direction. The direction of the result string will be RTL if either + * the righmost or leftmost strong character of the source text is RTL + * or Arabic Letter, or if the text contains no strong character; + * the direction will be LTR otherwise.<p> + * + * If reordering option <code>UBIDI_OPTION_INSERT_MARKS</code> is set, an RLM may + * be added at the beginning of the result string to ensure round trip + * (that the result string, when reordered back to visual, will produce + * the original source text). + * @see UBIDI_REORDER_INVERSE_LIKE_DIRECT + * @see UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL + * @stable ICU 2.0 + */ +#define UBIDI_DEFAULT_RTL 0xff + +/** + * Maximum explicit embedding level. + * (The maximum resolved level can be up to <code>UBIDI_MAX_EXPLICIT_LEVEL+1</code>). + * @stable ICU 2.0 + */ +#define UBIDI_MAX_EXPLICIT_LEVEL 61 + +/** Bit flag for level input. + * Overrides directional properties. + * @stable ICU 2.0 + */ +#define UBIDI_LEVEL_OVERRIDE 0x80 + +/** + * Special value which can be returned by the mapping functions when a logical + * index has no corresponding visual index or vice-versa. This may happen + * for the logical-to-visual mapping of a Bidi control when option + * <code>#UBIDI_OPTION_REMOVE_CONTROLS</code> is specified. This can also happen + * for the visual-to-logical mapping of a Bidi mark (LRM or RLM) inserted + * by option <code>#UBIDI_OPTION_INSERT_MARKS</code>. + * @see ubidi_getVisualIndex + * @see ubidi_getVisualMap + * @see ubidi_getLogicalIndex + * @see ubidi_getLogicalMap + * @stable ICU 3.6 + */ +#define UBIDI_MAP_NOWHERE (-1) + +/** + * <code>UBiDiDirection</code> values indicate the text direction. + * @stable ICU 2.0 + */ +enum UBiDiDirection { + /** All left-to-right text. This is a 0 value. @stable ICU 2.0 */ + UBIDI_LTR, + /** All right-to-left text. This is a 1 value. @stable ICU 2.0 */ + UBIDI_RTL, + /** Mixed-directional text. @stable ICU 2.0 */ + UBIDI_MIXED +}; + +/** @stable ICU 2.0 */ +typedef enum UBiDiDirection UBiDiDirection; + +/** + * Forward declaration of the <code>UBiDi</code> structure for the declaration of + * the API functions. Its fields are implementation-specific.<p> + * This structure holds information about a paragraph (or multiple paragraphs) + * of text with Bidi-algorithm-related details, or about one line of + * such a paragraph.<p> + * Reordering can be done on a line, or on one or more paragraphs which are + * then interpreted each as one single line. + * @stable ICU 2.0 + */ +struct UBiDi; + +/** @stable ICU 2.0 */ +typedef struct UBiDi UBiDi; + +/** + * Allocate a <code>UBiDi</code> structure. + * Such an object is initially empty. It is assigned + * the Bidi properties of a piece of text containing one or more paragraphs + * by <code>ubidi_setPara()</code> + * or the Bidi properties of a line within a paragraph by + * <code>ubidi_setLine()</code>.<p> + * This object can be reused for as long as it is not deallocated + * by calling <code>ubidi_close()</code>.<p> + * <code>ubidi_setPara()</code> and <code>ubidi_setLine()</code> will allocate + * additional memory for internal structures as necessary. + * + * @return An empty <code>UBiDi</code> object. + * @stable ICU 2.0 + */ +U_STABLE UBiDi * U_EXPORT2 +ubidi_open(void); + +/** + * Allocate a <code>UBiDi</code> structure with preallocated memory + * for internal structures. + * This function provides a <code>UBiDi</code> object like <code>ubidi_open()</code> + * with no arguments, but it also preallocates memory for internal structures + * according to the sizings supplied by the caller.<p> + * Subsequent functions will not allocate any more memory, and are thus + * guaranteed not to fail because of lack of memory.<p> + * The preallocation can be limited to some of the internal memory + * by setting some values to 0 here. That means that if, e.g., + * <code>maxRunCount</code> cannot be reasonably predetermined and should not + * be set to <code>maxLength</code> (the only failproof value) to avoid + * wasting memory, then <code>maxRunCount</code> could be set to 0 here + * and the internal structures that are associated with it will be allocated + * on demand, just like with <code>ubidi_open()</code>. + * + * @param maxLength is the maximum text or line length that internal memory + * will be preallocated for. An attempt to associate this object with a + * longer text will fail, unless this value is 0, which leaves the allocation + * up to the implementation. + * + * @param maxRunCount is the maximum anticipated number of same-level runs + * that internal memory will be preallocated for. An attempt to access + * visual runs on an object that was not preallocated for as many runs + * as the text was actually resolved to will fail, + * unless this value is 0, which leaves the allocation up to the implementation.<br><br> + * The number of runs depends on the actual text and maybe anywhere between + * 1 and <code>maxLength</code>. It is typically small. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @return An empty <code>UBiDi</code> object with preallocated memory. + * @stable ICU 2.0 + */ +U_STABLE UBiDi * U_EXPORT2 +ubidi_openSized(int32_t maxLength, int32_t maxRunCount, UErrorCode *pErrorCode); + +/** + * <code>ubidi_close()</code> must be called to free the memory + * associated with a UBiDi object.<p> + * + * <strong>Important: </strong> + * A parent <code>UBiDi</code> object must not be destroyed or reused if + * it still has children. + * If a <code>UBiDi</code> object has become the <i>child</i> + * of another one (its <i>parent</i>) by calling + * <code>ubidi_setLine()</code>, then the child object must + * be destroyed (closed) or reused (by calling + * <code>ubidi_setPara()</code> or <code>ubidi_setLine()</code>) + * before the parent object. + * + * @param pBiDi is a <code>UBiDi</code> object. + * + * @see ubidi_setPara + * @see ubidi_setLine + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_close(UBiDi *pBiDi); + +/** + * Modify the operation of the Bidi algorithm such that it + * approximates an "inverse Bidi" algorithm. This function + * must be called before <code>ubidi_setPara()</code>. + * + * <p>The normal operation of the Bidi algorithm as described + * in the Unicode Technical Report is to take text stored in logical + * (keyboard, typing) order and to determine the reordering of it for visual + * rendering. + * Some legacy systems store text in visual order, and for operations + * with standard, Unicode-based algorithms, the text needs to be transformed + * to logical order. This is effectively the inverse algorithm of the + * described Bidi algorithm. Note that there is no standard algorithm for + * this "inverse Bidi" and that the current implementation provides only an + * approximation of "inverse Bidi".</p> + * + * <p>With <code>isInverse</code> set to <code>TRUE</code>, + * this function changes the behavior of some of the subsequent functions + * in a way that they can be used for the inverse Bidi algorithm. + * Specifically, runs of text with numeric characters will be treated in a + * special way and may need to be surrounded with LRM characters when they are + * written in reordered sequence.</p> + * + * <p>Output runs should be retrieved using <code>ubidi_getVisualRun()</code>. + * Since the actual input for "inverse Bidi" is visually ordered text and + * <code>ubidi_getVisualRun()</code> gets the reordered runs, these are actually + * the runs of the logically ordered output.</p> + * + * <p>Calling this function with argument <code>isInverse</code> set to + * <code>TRUE</code> is equivalent to calling + * <code>ubidi_setReorderingMode</code> with argument + * <code>reorderingMode</code> + * set to <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>.<br> + * Calling this function with argument <code>isInverse</code> set to + * <code>FALSE</code> is equivalent to calling + * <code>ubidi_setReorderingMode</code> with argument + * <code>reorderingMode</code> + * set to <code>#UBIDI_REORDER_DEFAULT</code>. + * + * @param pBiDi is a <code>UBiDi</code> object. + * + * @param isInverse specifies "forward" or "inverse" Bidi operation. + * + * @see ubidi_setPara + * @see ubidi_writeReordered + * @see ubidi_setReorderingMode + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_setInverse(UBiDi *pBiDi, UBool isInverse); + +/** + * Is this Bidi object set to perform the inverse Bidi algorithm? + * <p>Note: calling this function after setting the reordering mode with + * <code>ubidi_setReorderingMode</code> will return <code>TRUE</code> if the + * reordering mode was set to <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>, + * <code>FALSE</code> for all other values.</p> + * + * @param pBiDi is a <code>UBiDi</code> object. + * @return TRUE if the Bidi object is set to perform the inverse Bidi algorithm + * by handling numbers as L. + * + * @see ubidi_setInverse + * @see ubidi_setReorderingMode + * @stable ICU 2.0 + */ + +U_STABLE UBool U_EXPORT2 +ubidi_isInverse(UBiDi *pBiDi); + +/** + * Specify whether block separators must be allocated level zero, + * so that successive paragraphs will progress from left to right. + * This function must be called before <code>ubidi_setPara()</code>. + * Paragraph separators (B) may appear in the text. Setting them to level zero + * means that all paragraph separators (including one possibly appearing + * in the last text position) are kept in the reordered text after the text + * that they follow in the source text. + * When this feature is not enabled, a paragraph separator at the last + * position of the text before reordering will go to the first position + * of the reordered text when the paragraph level is odd. + * + * @param pBiDi is a <code>UBiDi</code> object. + * + * @param orderParagraphsLTR specifies whether paragraph separators (B) must + * receive level 0, so that successive paragraphs progress from left to right. + * + * @see ubidi_setPara + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +ubidi_orderParagraphsLTR(UBiDi *pBiDi, UBool orderParagraphsLTR); + +/** + * Is this Bidi object set to allocate level 0 to block separators so that + * successive paragraphs progress from left to right? + * + * @param pBiDi is a <code>UBiDi</code> object. + * @return TRUE if the Bidi object is set to allocate level 0 to block + * separators. + * + * @see ubidi_orderParagraphsLTR + * @stable ICU 3.4 + */ +U_STABLE UBool U_EXPORT2 +ubidi_isOrderParagraphsLTR(UBiDi *pBiDi); + +/** + * <code>UBiDiReorderingMode</code> values indicate which variant of the Bidi + * algorithm to use. + * + * @see ubidi_setReorderingMode + * @stable ICU 3.6 + */ +typedef enum UBiDiReorderingMode { + /** Regular Logical to Visual Bidi algorithm according to Unicode. + * This is a 0 value. + * @stable ICU 3.6 */ + UBIDI_REORDER_DEFAULT = 0, + /** Logical to Visual algorithm which handles numbers in a way which + * mimicks the behavior of Windows XP. + * @stable ICU 3.6 */ + UBIDI_REORDER_NUMBERS_SPECIAL, + /** Logical to Visual algorithm grouping numbers with adjacent R characters + * (reversible algorithm). + * @stable ICU 3.6 */ + UBIDI_REORDER_GROUP_NUMBERS_WITH_R, + /** Reorder runs only to transform a Logical LTR string to the Logical RTL + * string with the same display, or vice-versa.<br> + * If this mode is set together with option + * <code>#UBIDI_OPTION_INSERT_MARKS</code>, some Bidi controls in the source + * text may be removed and other controls may be added to produce the + * minimum combination which has the required display. + * @stable ICU 3.6 */ + UBIDI_REORDER_RUNS_ONLY, + /** Visual to Logical algorithm which handles numbers like L + * (same algorithm as selected by <code>ubidi_setInverse(TRUE)</code>. + * @see ubidi_setInverse + * @stable ICU 3.6 */ + UBIDI_REORDER_INVERSE_NUMBERS_AS_L, + /** Visual to Logical algorithm equivalent to the regular Logical to Visual + * algorithm. + * @stable ICU 3.6 */ + UBIDI_REORDER_INVERSE_LIKE_DIRECT, + /** Inverse Bidi (Visual to Logical) algorithm for the + * <code>UBIDI_REORDER_NUMBERS_SPECIAL</code> Bidi algorithm. + * @stable ICU 3.6 */ + UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL, + /** Number of values for reordering mode. + * @stable ICU 3.6 */ + UBIDI_REORDER_COUNT +} UBiDiReorderingMode; + +/** + * Modify the operation of the Bidi algorithm such that it implements some + * variant to the basic Bidi algorithm or approximates an "inverse Bidi" + * algorithm, depending on different values of the "reordering mode". + * This function must be called before <code>ubidi_setPara()</code>, and stays + * in effect until called again with a different argument. + * + * <p>The normal operation of the Bidi algorithm as described + * in the Unicode Standard Annex #9 is to take text stored in logical + * (keyboard, typing) order and to determine how to reorder it for visual + * rendering.</p> + * + * <p>With the reordering mode set to a value other than + * <code>#UBIDI_REORDER_DEFAULT</code>, this function changes the behavior of + * some of the subsequent functions in a way such that they implement an + * inverse Bidi algorithm or some other algorithm variants.</p> + * + * <p>Some legacy systems store text in visual order, and for operations + * with standard, Unicode-based algorithms, the text needs to be transformed + * into logical order. This is effectively the inverse algorithm of the + * described Bidi algorithm. Note that there is no standard algorithm for + * this "inverse Bidi", so a number of variants are implemented here.</p> + * + * <p>In other cases, it may be desirable to emulate some variant of the + * Logical to Visual algorithm (e.g. one used in MS Windows), or perform a + * Logical to Logical transformation.</p> + * + * <ul> + * <li>When the reordering mode is set to <code>#UBIDI_REORDER_DEFAULT</code>, + * the standard Bidi Logical to Visual algorithm is applied.</li> + * + * <li>When the reordering mode is set to + * <code>#UBIDI_REORDER_NUMBERS_SPECIAL</code>, + * the algorithm used to perform Bidi transformations when calling + * <code>ubidi_setPara</code> should approximate the algorithm used in + * Microsoft Windows XP rather than strictly conform to the Unicode Bidi + * algorithm. + * <br> + * The differences between the basic algorithm and the algorithm addressed + * by this option are as follows: + * <ul> + * <li>Within text at an even embedding level, the sequence "123AB" + * (where AB represent R or AL letters) is transformed to "123BA" by the + * Unicode algorithm and to "BA123" by the Windows algorithm.</li> + * <li>Arabic-Indic numbers (AN) are handled by the Windows algorithm just + * like regular numbers (EN).</li> + * </ul></li> + * + * <li>When the reordering mode is set to + * <code>#UBIDI_REORDER_GROUP_NUMBERS_WITH_R</code>, + * numbers located between LTR text and RTL text are associated with the RTL + * text. For instance, an LTR paragraph with content "abc 123 DEF" (where + * upper case letters represent RTL characters) will be transformed to + * "abc FED 123" (and not "abc 123 FED"), "DEF 123 abc" will be transformed + * to "123 FED abc" and "123 FED abc" will be transformed to "DEF 123 abc". + * This makes the algorithm reversible and makes it useful when round trip + * (from visual to logical and back to visual) must be achieved without + * adding LRM characters. However, this is a variation from the standard + * Unicode Bidi algorithm.<br> + * The source text should not contain Bidi control characters other than LRM + * or RLM.</li> + * + * <li>When the reordering mode is set to + * <code>#UBIDI_REORDER_RUNS_ONLY</code>, + * a "Logical to Logical" transformation must be performed: + * <ul> + * <li>If the default text level of the source text (argument <code>paraLevel</code> + * in <code>ubidi_setPara</code>) is even, the source text will be handled as + * LTR logical text and will be transformed to the RTL logical text which has + * the same LTR visual display.</li> + * <li>If the default level of the source text is odd, the source text + * will be handled as RTL logical text and will be transformed to the + * LTR logical text which has the same LTR visual display.</li> + * </ul> + * This mode may be needed when logical text which is basically Arabic or + * Hebrew, with possible included numbers or phrases in English, has to be + * displayed as if it had an even embedding level (this can happen if the + * displaying application treats all text as if it was basically LTR). + * <br> + * This mode may also be needed in the reverse case, when logical text which is + * basically English, with possible included phrases in Arabic or Hebrew, has to + * be displayed as if it had an odd embedding level. + * <br> + * Both cases could be handled by adding LRE or RLE at the head of the text, + * if the display subsystem supports these formatting controls. If it does not, + * the problem may be handled by transforming the source text in this mode + * before displaying it, so that it will be displayed properly.<br> + * The source text should not contain Bidi control characters other than LRM + * or RLM.</li> + * + * <li>When the reordering mode is set to + * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>, an "inverse Bidi" algorithm + * is applied. + * Runs of text with numeric characters will be treated like LTR letters and + * may need to be surrounded with LRM characters when they are written in + * reordered sequence (the option <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> can + * be used with function <code>ubidi_writeReordered</code> to this end. This + * mode is equivalent to calling <code>ubidi_setInverse()</code> with + * argument <code>isInverse</code> set to <code>TRUE</code>.</li> + * + * <li>When the reordering mode is set to + * <code>#UBIDI_REORDER_INVERSE_LIKE_DIRECT</code>, the "direct" Logical to Visual + * Bidi algorithm is used as an approximation of an "inverse Bidi" algorithm. + * This mode is similar to mode <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code> + * but is closer to the regular Bidi algorithm. + * <br> + * For example, an LTR paragraph with the content "FED 123 456 CBA" (where + * upper case represents RTL characters) will be transformed to + * "ABC 456 123 DEF", as opposed to "DEF 123 456 ABC" + * with mode <code>UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>.<br> + * When used in conjunction with option + * <code>#UBIDI_OPTION_INSERT_MARKS</code>, this mode generally + * adds Bidi marks to the output significantly more sparingly than mode + * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code> with option + * <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> in calls to + * <code>ubidi_writeReordered</code>.</li> + * + * <li>When the reordering mode is set to + * <code>#UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code>, the Logical to Visual + * Bidi algorithm used in Windows XP is used as an approximation of an + * "inverse Bidi" algorithm. + * <br> + * For example, an LTR paragraph with the content "abc FED123" (where + * upper case represents RTL characters) will be transformed to + * "abc 123DEF.</li> + * </ul> + * + * <p>In all the reordering modes specifying an "inverse Bidi" algorithm + * (i.e. those with a name starting with <code>UBIDI_REORDER_INVERSE</code>), + * output runs should be retrieved using + * <code>ubidi_getVisualRun()</code>, and the output text with + * <code>ubidi_writeReordered()</code>. The caller should keep in mind that in + * "inverse Bidi" modes the input is actually visually ordered text and + * reordered output returned by <code>ubidi_getVisualRun()</code> or + * <code>ubidi_writeReordered()</code> are actually runs or character string + * of logically ordered output.<br> + * For all the "inverse Bidi" modes, the source text should not contain + * Bidi control characters other than LRM or RLM.</p> + * + * <p>Note that option <code>#UBIDI_OUTPUT_REVERSE</code> of + * <code>ubidi_writeReordered</code> has no useful meaning and should not be + * used in conjunction with any value of the reordering mode specifying + * "inverse Bidi" or with value <code>UBIDI_REORDER_RUNS_ONLY</code>. + * + * @param pBiDi is a <code>UBiDi</code> object. + * @param reorderingMode specifies the required variant of the Bidi algorithm. + * + * @see UBiDiReorderingMode + * @see ubidi_setInverse + * @see ubidi_setPara + * @see ubidi_writeReordered + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +ubidi_setReorderingMode(UBiDi *pBiDi, UBiDiReorderingMode reorderingMode); + +/** + * What is the requested reordering mode for a given Bidi object? + * + * @param pBiDi is a <code>UBiDi</code> object. + * @return the current reordering mode of the Bidi object + * @see ubidi_setReorderingMode + * @stable ICU 3.6 + */ +U_STABLE UBiDiReorderingMode U_EXPORT2 +ubidi_getReorderingMode(UBiDi *pBiDi); + +/** + * <code>UBiDiReorderingOption</code> values indicate which options are + * specified to affect the Bidi algorithm. + * + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ +typedef enum UBiDiReorderingOption { + /** + * option value for <code>ubidi_setReorderingOptions</code>: + * disable all the options which can be set with this function + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ + UBIDI_OPTION_DEFAULT = 0, + + /** + * option bit for <code>ubidi_setReorderingOptions</code>: + * insert Bidi marks (LRM or RLM) when needed to ensure correct result of + * a reordering to a Logical order + * + * <p>This option must be set or reset before calling + * <code>ubidi_setPara</code>.</p> + * + * <p>This option is significant only with reordering modes which generate + * a result with Logical order, specifically:</p> + * <ul> + * <li><code>#UBIDI_REORDER_RUNS_ONLY</code></li> + * <li><code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code></li> + * <li><code>#UBIDI_REORDER_INVERSE_LIKE_DIRECT</code></li> + * <li><code>#UBIDI_REORDER_INVERSE_FOR_NUMBERS_SPECIAL</code></li> + * </ul> + * + * <p>If this option is set in conjunction with reordering mode + * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code> or with calling + * <code>ubidi_setInverse(TRUE)</code>, it implies + * option <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> + * in calls to function <code>ubidi_writeReordered()</code>.</p> + * + * <p>For other reordering modes, a minimum number of LRM or RLM characters + * will be added to the source text after reordering it so as to ensure + * round trip, i.e. when applying the inverse reordering mode on the + * resulting logical text with removal of Bidi marks + * (option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code> set before calling + * <code>ubidi_setPara()</code> or option <code>#UBIDI_REMOVE_BIDI_CONTROLS</code> + * in <code>ubidi_writeReordered</code>), the result will be identical to the + * source text in the first transformation. + * + * <p>This option will be ignored if specified together with option + * <code>#UBIDI_OPTION_REMOVE_CONTROLS</code>. It inhibits option + * <code>UBIDI_REMOVE_BIDI_CONTROLS</code> in calls to function + * <code>ubidi_writeReordered()</code> and it implies option + * <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> in calls to function + * <code>ubidi_writeReordered()</code> if the reordering mode is + * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code>.</p> + * + * @see ubidi_setReorderingMode + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ + UBIDI_OPTION_INSERT_MARKS = 1, + + /** + * option bit for <code>ubidi_setReorderingOptions</code>: + * remove Bidi control characters + * + * <p>This option must be set or reset before calling + * <code>ubidi_setPara</code>.</p> + * + * <p>This option nullifies option <code>#UBIDI_OPTION_INSERT_MARKS</code>. + * It inhibits option <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code> in calls + * to function <code>ubidi_writeReordered()</code> and it implies option + * <code>#UBIDI_REMOVE_BIDI_CONTROLS</code> in calls to that function.</p> + * + * @see ubidi_setReorderingMode + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ + UBIDI_OPTION_REMOVE_CONTROLS = 2, + + /** + * option bit for <code>ubidi_setReorderingOptions</code>: + * process the output as part of a stream to be continued + * + * <p>This option must be set or reset before calling + * <code>ubidi_setPara</code>.</p> + * + * <p>This option specifies that the caller is interested in processing large + * text object in parts. + * The results of the successive calls are expected to be concatenated by the + * caller. Only the call for the last part will have this option bit off.</p> + * + * <p>When this option bit is on, <code>ubidi_setPara()</code> may process + * less than the full source text in order to truncate the text at a meaningful + * boundary. The caller should call <code>ubidi_getProcessedLength()</code> + * immediately after calling <code>ubidi_setPara()</code> in order to + * determine how much of the source text has been processed. + * Source text beyond that length should be resubmitted in following calls to + * <code>ubidi_setPara</code>. The processed length may be less than + * the length of the source text if a character preceding the last character of + * the source text constitutes a reasonable boundary (like a block separator) + * for text to be continued.<br> + * If the last character of the source text constitutes a reasonable + * boundary, the whole text will be processed at once.<br> + * If nowhere in the source text there exists + * such a reasonable boundary, the processed length will be zero.<br> + * The caller should check for such an occurrence and do one of the following: + * <ul><li>submit a larger amount of text with a better chance to include + * a reasonable boundary.</li> + * <li>resubmit the same text after turning off option + * <code>UBIDI_OPTION_STREAMING</code>.</li></ul> + * In all cases, this option should be turned off before processing the last + * part of the text.</p> + * + * <p>When the <code>UBIDI_OPTION_STREAMING</code> option is used, + * it is recommended to call <code>ubidi_orderParagraphsLTR()</code> with + * argument <code>orderParagraphsLTR</code> set to <code>TRUE</code> before + * calling <code>ubidi_setPara</code> so that later paragraphs may be + * concatenated to previous paragraphs on the right.</p> + * + * @see ubidi_setReorderingMode + * @see ubidi_setReorderingOptions + * @see ubidi_getProcessedLength + * @see ubidi_orderParagraphsLTR + * @stable ICU 3.6 + */ + UBIDI_OPTION_STREAMING = 4 +} UBiDiReorderingOption; + +/** + * Specify which of the reordering options + * should be applied during Bidi transformations. + * + * @param pBiDi is a <code>UBiDi</code> object. + * @param reorderingOptions is a combination of zero or more of the following + * options: + * <code>#UBIDI_OPTION_DEFAULT</code>, <code>#UBIDI_OPTION_INSERT_MARKS</code>, + * <code>#UBIDI_OPTION_REMOVE_CONTROLS</code>, <code>#UBIDI_OPTION_STREAMING</code>. + * + * @see ubidi_getReorderingOptions + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +ubidi_setReorderingOptions(UBiDi *pBiDi, uint32_t reorderingOptions); + +/** + * What are the reordering options applied to a given Bidi object? + * + * @param pBiDi is a <code>UBiDi</code> object. + * @return the current reordering options of the Bidi object + * @see ubidi_setReorderingOptions + * @stable ICU 3.6 + */ +U_STABLE uint32_t U_EXPORT2 +ubidi_getReorderingOptions(UBiDi *pBiDi); + +/** + * Perform the Unicode Bidi algorithm. It is defined in the + * <a href="http://www.unicode.org/unicode/reports/tr9/">Unicode Standard Anned #9</a>, + * version 13, + * also described in The Unicode Standard, Version 4.0 .<p> + * + * This function takes a piece of plain text containing one or more paragraphs, + * with or without externally specified embedding levels from <i>styled</i> + * text and computes the left-right-directionality of each character.<p> + * + * If the entire text is all of the same directionality, then + * the function may not perform all the steps described by the algorithm, + * i.e., some levels may not be the same as if all steps were performed. + * This is not relevant for unidirectional text.<br> + * For example, in pure LTR text with numbers the numbers would get + * a resolved level of 2 higher than the surrounding text according to + * the algorithm. This implementation may set all resolved levels to + * the same value in such a case.<p> + * + * The text can be composed of multiple paragraphs. Occurrence of a block + * separator in the text terminates a paragraph, and whatever comes next starts + * a new paragraph. The exception to this rule is when a Carriage Return (CR) + * is followed by a Line Feed (LF). Both CR and LF are block separators, but + * in that case, the pair of characters is considered as terminating the + * preceding paragraph, and a new paragraph will be started by a character + * coming after the LF. + * + * @param pBiDi A <code>UBiDi</code> object allocated with <code>ubidi_open()</code> + * which will be set to contain the reordering information, + * especially the resolved levels for all the characters in <code>text</code>. + * + * @param text is a pointer to the text that the Bidi algorithm will be performed on. + * This pointer is stored in the UBiDi object and can be retrieved + * with <code>ubidi_getText()</code>.<br> + * <strong>Note:</strong> the text must be (at least) <code>length</code> long. + * + * @param length is the length of the text; if <code>length==-1</code> then + * the text must be zero-terminated. + * + * @param paraLevel specifies the default level for the text; + * it is typically 0 (LTR) or 1 (RTL). + * If the function shall determine the paragraph level from the text, + * then <code>paraLevel</code> can be set to + * either <code>#UBIDI_DEFAULT_LTR</code> + * or <code>#UBIDI_DEFAULT_RTL</code>; if the text contains multiple + * paragraphs, the paragraph level shall be determined separately for + * each paragraph; if a paragraph does not include any strongly typed + * character, then the desired default is used (0 for LTR or 1 for RTL). + * Any other value between 0 and <code>#UBIDI_MAX_EXPLICIT_LEVEL</code> + * is also valid, with odd levels indicating RTL. + * + * @param embeddingLevels (in) may be used to preset the embedding and override levels, + * ignoring characters like LRE and PDF in the text. + * A level overrides the directional property of its corresponding + * (same index) character if the level has the + * <code>#UBIDI_LEVEL_OVERRIDE</code> bit set.<br><br> + * Except for that bit, it must be + * <code>paraLevel<=embeddingLevels[]<=UBIDI_MAX_EXPLICIT_LEVEL</code>, + * with one exception: a level of zero may be specified for a paragraph + * separator even if <code>paraLevel>0</code> when multiple paragraphs + * are submitted in the same call to <code>ubidi_setPara()</code>.<br><br> + * <strong>Caution: </strong>A copy of this pointer, not of the levels, + * will be stored in the <code>UBiDi</code> object; + * the <code>embeddingLevels</code> array must not be + * deallocated before the <code>UBiDi</code> structure is destroyed or reused, + * and the <code>embeddingLevels</code> + * should not be modified to avoid unexpected results on subsequent Bidi operations. + * However, the <code>ubidi_setPara()</code> and + * <code>ubidi_setLine()</code> functions may modify some or all of the levels.<br><br> + * After the <code>UBiDi</code> object is reused or destroyed, the caller + * must take care of the deallocation of the <code>embeddingLevels</code> array.<br><br> + * <strong>Note:</strong> the <code>embeddingLevels</code> array must be + * at least <code>length</code> long. + * + * @param pErrorCode must be a valid pointer to an error code value. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_setPara(UBiDi *pBiDi, const UChar *text, int32_t length, + UBiDiLevel paraLevel, UBiDiLevel *embeddingLevels, + UErrorCode *pErrorCode); + +/** + * <code>ubidi_setLine()</code> sets a <code>UBiDi</code> to + * contain the reordering information, especially the resolved levels, + * for all the characters in a line of text. This line of text is + * specified by referring to a <code>UBiDi</code> object representing + * this information for a piece of text containing one or more paragraphs, + * and by specifying a range of indexes in this text.<p> + * In the new line object, the indexes will range from 0 to <code>limit-start-1</code>.<p> + * + * This is used after calling <code>ubidi_setPara()</code> + * for a piece of text, and after line-breaking on that text. + * It is not necessary if each paragraph is treated as a single line.<p> + * + * After line-breaking, rules (L1) and (L2) for the treatment of + * trailing WS and for reordering are performed on + * a <code>UBiDi</code> object that represents a line.<p> + * + * <strong>Important: </strong><code>pLineBiDi</code> shares data with + * <code>pParaBiDi</code>. + * You must destroy or reuse <code>pLineBiDi</code> before <code>pParaBiDi</code>. + * In other words, you must destroy or reuse the <code>UBiDi</code> object for a line + * before the object for its parent paragraph.<p> + * + * The text pointer that was stored in <code>pParaBiDi</code> is also copied, + * and <code>start</code> is added to it so that it points to the beginning of the + * line for this object. + * + * @param pParaBiDi is the parent paragraph object. It must have been set + * by a successful call to ubidi_setPara. + * + * @param start is the line's first index into the text. + * + * @param limit is just behind the line's last index into the text + * (its last index +1).<br> + * It must be <code>0<=start<limit<=</code>containing paragraph limit. + * If the specified line crosses a paragraph boundary, the function + * will terminate with error code U_ILLEGAL_ARGUMENT_ERROR. + * + * @param pLineBiDi is the object that will now represent a line of the text. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @see ubidi_setPara + * @see ubidi_getProcessedLength + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_setLine(const UBiDi *pParaBiDi, + int32_t start, int32_t limit, + UBiDi *pLineBiDi, + UErrorCode *pErrorCode); + +/** + * Get the directionality of the text. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @return a value of <code>UBIDI_LTR</code>, <code>UBIDI_RTL</code> + * or <code>UBIDI_MIXED</code> + * that indicates if the entire text + * represented by this object is unidirectional, + * and which direction, or if it is mixed-directional. + * + * @see UBiDiDirection + * @stable ICU 2.0 + */ +U_STABLE UBiDiDirection U_EXPORT2 +ubidi_getDirection(const UBiDi *pBiDi); + +/** + * Get the pointer to the text. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @return The pointer to the text that the UBiDi object was created for. + * + * @see ubidi_setPara + * @see ubidi_setLine + * @stable ICU 2.0 + */ +U_STABLE const UChar * U_EXPORT2 +ubidi_getText(const UBiDi *pBiDi); + +/** + * Get the length of the text. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @return The length of the text that the UBiDi object was created for. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_getLength(const UBiDi *pBiDi); + +/** + * Get the paragraph level of the text. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @return The paragraph level. If there are multiple paragraphs, their + * level may vary if the required paraLevel is UBIDI_DEFAULT_LTR or + * UBIDI_DEFAULT_RTL. In that case, the level of the first paragraph + * is returned. + * + * @see UBiDiLevel + * @see ubidi_getParagraph + * @see ubidi_getParagraphByIndex + * @stable ICU 2.0 + */ +U_STABLE UBiDiLevel U_EXPORT2 +ubidi_getParaLevel(const UBiDi *pBiDi); + +/** + * Get the number of paragraphs. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @return The number of paragraphs. + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_countParagraphs(UBiDi *pBiDi); + +/** + * Get a paragraph, given a position within the text. + * This function returns information about a paragraph.<br> + * Note: if the paragraph index is known, it is more efficient to + * retrieve the paragraph information using ubidi_getParagraphByIndex().<p> + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @param charIndex is the index of a character within the text, in the + * range <code>[0..ubidi_getProcessedLength(pBiDi)-1]</code>. + * + * @param pParaStart will receive the index of the first character of the + * paragraph in the text. + * This pointer can be <code>NULL</code> if this + * value is not necessary. + * + * @param pParaLimit will receive the limit of the paragraph. + * The l-value that you point to here may be the + * same expression (variable) as the one for + * <code>charIndex</code>. + * This pointer can be <code>NULL</code> if this + * value is not necessary. + * + * @param pParaLevel will receive the level of the paragraph. + * This pointer can be <code>NULL</code> if this + * value is not necessary. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @return The index of the paragraph containing the specified position. + * + * @see ubidi_getProcessedLength + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_getParagraph(const UBiDi *pBiDi, int32_t charIndex, int32_t *pParaStart, + int32_t *pParaLimit, UBiDiLevel *pParaLevel, + UErrorCode *pErrorCode); + +/** + * Get a paragraph, given the index of this paragraph. + * + * This function returns information about a paragraph.<p> + * + * @param pBiDi is the paragraph <code>UBiDi</code> object. + * + * @param paraIndex is the number of the paragraph, in the + * range <code>[0..ubidi_countParagraphs(pBiDi)-1]</code>. + * + * @param pParaStart will receive the index of the first character of the + * paragraph in the text. + * This pointer can be <code>NULL</code> if this + * value is not necessary. + * + * @param pParaLimit will receive the limit of the paragraph. + * This pointer can be <code>NULL</code> if this + * value is not necessary. + * + * @param pParaLevel will receive the level of the paragraph. + * This pointer can be <code>NULL</code> if this + * value is not necessary. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +ubidi_getParagraphByIndex(const UBiDi *pBiDi, int32_t paraIndex, + int32_t *pParaStart, int32_t *pParaLimit, + UBiDiLevel *pParaLevel, UErrorCode *pErrorCode); + +/** + * Get the level for one character. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @param charIndex the index of a character. It must be in the range + * [0..ubidi_getProcessedLength(pBiDi)]. + * + * @return The level for the character at charIndex (0 if charIndex is not + * in the valid range). + * + * @see UBiDiLevel + * @see ubidi_getProcessedLength + * @stable ICU 2.0 + */ +U_STABLE UBiDiLevel U_EXPORT2 +ubidi_getLevelAt(const UBiDi *pBiDi, int32_t charIndex); + +/** + * Get an array of levels for each character.<p> + * + * Note that this function may allocate memory under some + * circumstances, unlike <code>ubidi_getLevelAt()</code>. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object, whose + * text length must be strictly positive. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @return The levels array for the text, + * or <code>NULL</code> if an error occurs. + * + * @see UBiDiLevel + * @see ubidi_getProcessedLength + * @stable ICU 2.0 + */ +U_STABLE const UBiDiLevel * U_EXPORT2 +ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode); + +/** + * Get a logical run. + * This function returns information about a run and is used + * to retrieve runs in logical order.<p> + * This is especially useful for line-breaking on a paragraph. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @param logicalPosition is a logical position within the source text. + * + * @param pLogicalLimit will receive the limit of the corresponding run. + * The l-value that you point to here may be the + * same expression (variable) as the one for + * <code>logicalPosition</code>. + * This pointer can be <code>NULL</code> if this + * value is not necessary. + * + * @param pLevel will receive the level of the corresponding run. + * This pointer can be <code>NULL</code> if this + * value is not necessary. + * + * @see ubidi_getProcessedLength + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_getLogicalRun(const UBiDi *pBiDi, int32_t logicalPosition, + int32_t *pLogicalLimit, UBiDiLevel *pLevel); + +/** + * Get the number of runs. + * This function may invoke the actual reordering on the + * <code>UBiDi</code> object, after <code>ubidi_setPara()</code> + * may have resolved only the levels of the text. Therefore, + * <code>ubidi_countRuns()</code> may have to allocate memory, + * and may fail doing so. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @return The number of runs. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_countRuns(UBiDi *pBiDi, UErrorCode *pErrorCode); + +/** + * Get one run's logical start, length, and directionality, + * which can be 0 for LTR or 1 for RTL. + * In an RTL run, the character at the logical start is + * visually on the right of the displayed run. + * The length is the number of characters in the run.<p> + * <code>ubidi_countRuns()</code> should be called + * before the runs are retrieved. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @param runIndex is the number of the run in visual order, in the + * range <code>[0..ubidi_countRuns(pBiDi)-1]</code>. + * + * @param pLogicalStart is the first logical character index in the text. + * The pointer may be <code>NULL</code> if this index is not needed. + * + * @param pLength is the number of characters (at least one) in the run. + * The pointer may be <code>NULL</code> if this is not needed. + * + * @return the directionality of the run, + * <code>UBIDI_LTR==0</code> or <code>UBIDI_RTL==1</code>, + * never <code>UBIDI_MIXED</code>. + * + * @see ubidi_countRuns + * + * Example: + * <pre> + * \code + * int32_t i, count=ubidi_countRuns(pBiDi), + * logicalStart, visualIndex=0, length; + * for(i=0; i<count; ++i) { + * if(UBIDI_LTR==ubidi_getVisualRun(pBiDi, i, &logicalStart, &length)) { + * do { // LTR + * show_char(text[logicalStart++], visualIndex++); + * } while(--length>0); + * } else { + * logicalStart+=length; // logicalLimit + * do { // RTL + * show_char(text[--logicalStart], visualIndex++); + * } while(--length>0); + * } + * } + *\endcode + * </pre> + * + * Note that in right-to-left runs, code like this places + * second surrogates before first ones (which is generally a bad idea) + * and combining characters before base characters. + * <p> + * Use of <code>ubidi_writeReordered()</code>, optionally with the + * <code>#UBIDI_KEEP_BASE_COMBINING</code> option, can be considered in order + * to avoid these issues. + * @stable ICU 2.0 + */ +U_STABLE UBiDiDirection U_EXPORT2 +ubidi_getVisualRun(UBiDi *pBiDi, int32_t runIndex, + int32_t *pLogicalStart, int32_t *pLength); + +/** + * Get the visual position from a logical text position. + * If such a mapping is used many times on the same + * <code>UBiDi</code> object, then calling + * <code>ubidi_getLogicalMap()</code> is more efficient.<p> + * + * The value returned may be <code>#UBIDI_MAP_NOWHERE</code> if there is no + * visual position because the corresponding text character is a Bidi control + * removed from output by the option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code>. + * <p> + * When the visual output is altered by using options of + * <code>ubidi_writeReordered()</code> such as <code>UBIDI_INSERT_LRM_FOR_NUMERIC</code>, + * <code>UBIDI_KEEP_BASE_COMBINING</code>, <code>UBIDI_OUTPUT_REVERSE</code>, + * <code>UBIDI_REMOVE_BIDI_CONTROLS</code>, the visual position returned may not + * be correct. It is advised to use, when possible, reordering options + * such as <code>UBIDI_OPTION_INSERT_MARKS</code> and <code>UBIDI_OPTION_REMOVE_CONTROLS</code>. + * <p> + * Note that in right-to-left runs, this mapping places + * second surrogates before first ones (which is generally a bad idea) + * and combining characters before base characters. + * Use of <code>ubidi_writeReordered()</code>, optionally with the + * <code>#UBIDI_KEEP_BASE_COMBINING</code> option can be considered instead + * of using the mapping, in order to avoid these issues. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @param logicalIndex is the index of a character in the text. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @return The visual position of this character. + * + * @see ubidi_getLogicalMap + * @see ubidi_getLogicalIndex + * @see ubidi_getProcessedLength + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_getVisualIndex(UBiDi *pBiDi, int32_t logicalIndex, UErrorCode *pErrorCode); + +/** + * Get the logical text position from a visual position. + * If such a mapping is used many times on the same + * <code>UBiDi</code> object, then calling + * <code>ubidi_getVisualMap()</code> is more efficient.<p> + * + * The value returned may be <code>#UBIDI_MAP_NOWHERE</code> if there is no + * logical position because the corresponding text character is a Bidi mark + * inserted in the output by option <code>#UBIDI_OPTION_INSERT_MARKS</code>. + * <p> + * This is the inverse function to <code>ubidi_getVisualIndex()</code>. + * <p> + * When the visual output is altered by using options of + * <code>ubidi_writeReordered()</code> such as <code>UBIDI_INSERT_LRM_FOR_NUMERIC</code>, + * <code>UBIDI_KEEP_BASE_COMBINING</code>, <code>UBIDI_OUTPUT_REVERSE</code>, + * <code>UBIDI_REMOVE_BIDI_CONTROLS</code>, the logical position returned may not + * be correct. It is advised to use, when possible, reordering options + * such as <code>UBIDI_OPTION_INSERT_MARKS</code> and <code>UBIDI_OPTION_REMOVE_CONTROLS</code>. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @param visualIndex is the visual position of a character. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @return The index of this character in the text. + * + * @see ubidi_getVisualMap + * @see ubidi_getVisualIndex + * @see ubidi_getResultLength + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_getLogicalIndex(UBiDi *pBiDi, int32_t visualIndex, UErrorCode *pErrorCode); + +/** + * Get a logical-to-visual index map (array) for the characters in the UBiDi + * (paragraph or line) object. + * <p> + * Some values in the map may be <code>#UBIDI_MAP_NOWHERE</code> if the + * corresponding text characters are Bidi controls removed from the visual + * output by the option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code>. + * <p> + * When the visual output is altered by using options of + * <code>ubidi_writeReordered()</code> such as <code>UBIDI_INSERT_LRM_FOR_NUMERIC</code>, + * <code>UBIDI_KEEP_BASE_COMBINING</code>, <code>UBIDI_OUTPUT_REVERSE</code>, + * <code>UBIDI_REMOVE_BIDI_CONTROLS</code>, the visual positions returned may not + * be correct. It is advised to use, when possible, reordering options + * such as <code>UBIDI_OPTION_INSERT_MARKS</code> and <code>UBIDI_OPTION_REMOVE_CONTROLS</code>. + * <p> + * Note that in right-to-left runs, this mapping places + * second surrogates before first ones (which is generally a bad idea) + * and combining characters before base characters. + * Use of <code>ubidi_writeReordered()</code>, optionally with the + * <code>#UBIDI_KEEP_BASE_COMBINING</code> option can be considered instead + * of using the mapping, in order to avoid these issues. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @param indexMap is a pointer to an array of <code>ubidi_getProcessedLength()</code> + * indexes which will reflect the reordering of the characters. + * If option <code>#UBIDI_OPTION_INSERT_MARKS</code> is set, the number + * of elements allocated in <code>indexMap</code> must be no less than + * <code>ubidi_getResultLength()</code>. + * The array does not need to be initialized.<br><br> + * The index map will result in <code>indexMap[logicalIndex]==visualIndex</code>. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @see ubidi_getVisualMap + * @see ubidi_getVisualIndex + * @see ubidi_getProcessedLength + * @see ubidi_getResultLength + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_getLogicalMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode); + +/** + * Get a visual-to-logical index map (array) for the characters in the UBiDi + * (paragraph or line) object. + * <p> + * Some values in the map may be <code>#UBIDI_MAP_NOWHERE</code> if the + * corresponding text characters are Bidi marks inserted in the visual output + * by the option <code>#UBIDI_OPTION_INSERT_MARKS</code>. + * <p> + * When the visual output is altered by using options of + * <code>ubidi_writeReordered()</code> such as <code>UBIDI_INSERT_LRM_FOR_NUMERIC</code>, + * <code>UBIDI_KEEP_BASE_COMBINING</code>, <code>UBIDI_OUTPUT_REVERSE</code>, + * <code>UBIDI_REMOVE_BIDI_CONTROLS</code>, the logical positions returned may not + * be correct. It is advised to use, when possible, reordering options + * such as <code>UBIDI_OPTION_INSERT_MARKS</code> and <code>UBIDI_OPTION_REMOVE_CONTROLS</code>. + * + * @param pBiDi is the paragraph or line <code>UBiDi</code> object. + * + * @param indexMap is a pointer to an array of <code>ubidi_getResultLength()</code> + * indexes which will reflect the reordering of the characters. + * If option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code> is set, the number + * of elements allocated in <code>indexMap</code> must be no less than + * <code>ubidi_getProcessedLength()</code>. + * The array does not need to be initialized.<br><br> + * The index map will result in <code>indexMap[visualIndex]==logicalIndex</code>. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @see ubidi_getLogicalMap + * @see ubidi_getLogicalIndex + * @see ubidi_getProcessedLength + * @see ubidi_getResultLength + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_getVisualMap(UBiDi *pBiDi, int32_t *indexMap, UErrorCode *pErrorCode); + +/** + * This is a convenience function that does not use a UBiDi object. + * It is intended to be used for when an application has determined the levels + * of objects (character sequences) and just needs to have them reordered (L2). + * This is equivalent to using <code>ubidi_getLogicalMap()</code> on a + * <code>UBiDi</code> object. + * + * @param levels is an array with <code>length</code> levels that have been determined by + * the application. + * + * @param length is the number of levels in the array, or, semantically, + * the number of objects to be reordered. + * It must be <code>length>0</code>. + * + * @param indexMap is a pointer to an array of <code>length</code> + * indexes which will reflect the reordering of the characters. + * The array does not need to be initialized.<p> + * The index map will result in <code>indexMap[logicalIndex]==visualIndex</code>. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_reorderLogical(const UBiDiLevel *levels, int32_t length, int32_t *indexMap); + +/** + * This is a convenience function that does not use a UBiDi object. + * It is intended to be used for when an application has determined the levels + * of objects (character sequences) and just needs to have them reordered (L2). + * This is equivalent to using <code>ubidi_getVisualMap()</code> on a + * <code>UBiDi</code> object. + * + * @param levels is an array with <code>length</code> levels that have been determined by + * the application. + * + * @param length is the number of levels in the array, or, semantically, + * the number of objects to be reordered. + * It must be <code>length>0</code>. + * + * @param indexMap is a pointer to an array of <code>length</code> + * indexes which will reflect the reordering of the characters. + * The array does not need to be initialized.<p> + * The index map will result in <code>indexMap[visualIndex]==logicalIndex</code>. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_reorderVisual(const UBiDiLevel *levels, int32_t length, int32_t *indexMap); + +/** + * Invert an index map. + * The index mapping of the first map is inverted and written to + * the second one. + * + * @param srcMap is an array with <code>length</code> elements + * which defines the original mapping from a source array containing + * <code>length</code> elements to a destination array. + * Some elements of the source array may have no mapping in the + * destination array. In that case, their value will be + * the special value <code>UBIDI_MAP_NOWHERE</code>. + * All elements must be >=0 or equal to <code>UBIDI_MAP_NOWHERE</code>. + * Some elements may have a value >= <code>length</code>, if the + * destination array has more elements than the source array. + * There must be no duplicate indexes (two or more elements with the + * same value except <code>UBIDI_MAP_NOWHERE</code>). + * + * @param destMap is an array with a number of elements equal to 1 + the highest + * value in <code>srcMap</code>. + * <code>destMap</code> will be filled with the inverse mapping. + * If element with index i in <code>srcMap</code> has a value k different + * from <code>UBIDI_MAP_NOWHERE</code>, this means that element i of + * the source array maps to element k in the destination array. + * The inverse map will have value i in its k-th element. + * For all elements of the destination array which do not map to + * an element in the source array, the corresponding element in the + * inverse map will have a value equal to <code>UBIDI_MAP_NOWHERE</code>. + * + * @param length is the length of each array. + * @see UBIDI_MAP_NOWHERE + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubidi_invertMap(const int32_t *srcMap, int32_t *destMap, int32_t length); + +/** option flags for ubidi_writeReordered() */ + +/** + * option bit for ubidi_writeReordered(): + * keep combining characters after their base characters in RTL runs + * + * @see ubidi_writeReordered + * @stable ICU 2.0 + */ +#define UBIDI_KEEP_BASE_COMBINING 1 + +/** + * option bit for ubidi_writeReordered(): + * replace characters with the "mirrored" property in RTL runs + * by their mirror-image mappings + * + * @see ubidi_writeReordered + * @stable ICU 2.0 + */ +#define UBIDI_DO_MIRRORING 2 + +/** + * option bit for ubidi_writeReordered(): + * surround the run with LRMs if necessary; + * this is part of the approximate "inverse Bidi" algorithm + * + * <p>This option does not imply corresponding adjustment of the index + * mappings.</p> + * + * @see ubidi_setInverse + * @see ubidi_writeReordered + * @stable ICU 2.0 + */ +#define UBIDI_INSERT_LRM_FOR_NUMERIC 4 + +/** + * option bit for ubidi_writeReordered(): + * remove Bidi control characters + * (this does not affect #UBIDI_INSERT_LRM_FOR_NUMERIC) + * + * <p>This option does not imply corresponding adjustment of the index + * mappings.</p> + * + * @see ubidi_writeReordered + * @stable ICU 2.0 + */ +#define UBIDI_REMOVE_BIDI_CONTROLS 8 + +/** + * option bit for ubidi_writeReordered(): + * write the output in reverse order + * + * <p>This has the same effect as calling <code>ubidi_writeReordered()</code> + * first without this option, and then calling + * <code>ubidi_writeReverse()</code> without mirroring. + * Doing this in the same step is faster and avoids a temporary buffer. + * An example for using this option is output to a character terminal that + * is designed for RTL scripts and stores text in reverse order.</p> + * + * @see ubidi_writeReordered + * @stable ICU 2.0 + */ +#define UBIDI_OUTPUT_REVERSE 16 + +/** + * Get the length of the source text processed by the last call to + * <code>ubidi_setPara()</code>. This length may be different from the length + * of the source text if option <code>#UBIDI_OPTION_STREAMING</code> + * has been set. + * <br> + * Note that whenever the length of the text affects the execution or the + * result of a function, it is the processed length which must be considered, + * except for <code>ubidi_setPara</code> (which receives unprocessed source + * text) and <code>ubidi_getLength</code> (which returns the original length + * of the source text).<br> + * In particular, the processed length is the one to consider in the following + * cases: + * <ul> + * <li>maximum value of the <code>limit</code> argument of + * <code>ubidi_setLine</code></li> + * <li>maximum value of the <code>charIndex</code> argument of + * <code>ubidi_getParagraph</code></li> + * <li>maximum value of the <code>charIndex</code> argument of + * <code>ubidi_getLevelAt</code></li> + * <li>number of elements in the array returned by <code>ubidi_getLevels</code></li> + * <li>maximum value of the <code>logicalStart</code> argument of + * <code>ubidi_getLogicalRun</code></li> + * <li>maximum value of the <code>logicalIndex</code> argument of + * <code>ubidi_getVisualIndex</code></li> + * <li>number of elements filled in the <code>*indexMap</code> argument of + * <code>ubidi_getLogicalMap</code></li> + * <li>length of text processed by <code>ubidi_writeReordered</code></li> + * </ul> + * + * @param pBiDi is the paragraph <code>UBiDi</code> object. + * + * @return The length of the part of the source text processed by + * the last call to <code>ubidi_setPara</code>. + * @see ubidi_setPara + * @see UBIDI_OPTION_STREAMING + * @stable ICU 3.6 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_getProcessedLength(const UBiDi *pBiDi); + +/** + * Get the length of the reordered text resulting from the last call to + * <code>ubidi_setPara()</code>. This length may be different from the length + * of the source text if option <code>#UBIDI_OPTION_INSERT_MARKS</code> + * or option <code>#UBIDI_OPTION_REMOVE_CONTROLS</code> has been set. + * <br> + * This resulting length is the one to consider in the following cases: + * <ul> + * <li>maximum value of the <code>visualIndex</code> argument of + * <code>ubidi_getLogicalIndex</code></li> + * <li>number of elements of the <code>*indexMap</code> argument of + * <code>ubidi_getVisualMap</code></li> + * </ul> + * Note that this length stays identical to the source text length if + * Bidi marks are inserted or removed using option bits of + * <code>ubidi_writeReordered</code>, or if option + * <code>#UBIDI_REORDER_INVERSE_NUMBERS_AS_L</code> has been set. + * + * @param pBiDi is the paragraph <code>UBiDi</code> object. + * + * @return The length of the reordered text resulting from + * the last call to <code>ubidi_setPara</code>. + * @see ubidi_setPara + * @see UBIDI_OPTION_INSERT_MARKS + * @see UBIDI_OPTION_REMOVE_CONTROLS + * @stable ICU 3.6 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_getResultLength(const UBiDi *pBiDi); + +U_CDECL_BEGIN +/** + * value returned by <code>UBiDiClassCallback</code> callbacks when + * there is no need to override the standard Bidi class for a given code point. + * @see UBiDiClassCallback + * @stable ICU 3.6 + */ +#define U_BIDI_CLASS_DEFAULT U_CHAR_DIRECTION_COUNT + +/** + * Callback type declaration for overriding default Bidi class values with + * custom ones. + * <p>Usually, the function pointer will be propagated to a <code>UBiDi</code> + * object by calling the <code>ubidi_setClassCallback()</code> function; + * then the callback will be invoked by the UBA implementation any time the + * class of a character is to be determined.</p> + * + * @param context is a pointer to the callback private data. + * + * @param c is the code point to get a Bidi class for. + * + * @return The directional property / Bidi class for the given code point + * <code>c</code> if the default class has been overridden, or + * <code>#U_BIDI_CLASS_DEFAULT</code> if the standard Bidi class value + * for <code>c</code> is to be used. + * @see ubidi_setClassCallback + * @see ubidi_getClassCallback + * @stable ICU 3.6 + */ +typedef UCharDirection U_CALLCONV +UBiDiClassCallback(const void *context, UChar32 c); + +U_CDECL_END + +/** + * Retrieve the Bidi class for a given code point. + * <p>If a <code>#UBiDiClassCallback</code> callback is defined and returns a + * value other than <code>#U_BIDI_CLASS_DEFAULT</code>, that value is used; + * otherwise the default class determination mechanism is invoked.</p> + * + * @param pBiDi is the paragraph <code>UBiDi</code> object. + * + * @param c is the code point whose Bidi class must be retrieved. + * + * @return The Bidi class for character <code>c</code> based + * on the given <code>pBiDi</code> instance. + * @see UBiDiClassCallback + * @stable ICU 3.6 + */ +U_STABLE UCharDirection U_EXPORT2 +ubidi_getCustomizedClass(UBiDi *pBiDi, UChar32 c); + +/** + * Set the callback function and callback data used by the UBA + * implementation for Bidi class determination. + * <p>This may be useful for assigning Bidi classes to PUA characters, or + * for special application needs. For instance, an application may want to + * handle all spaces like L or R characters (according to the base direction) + * when creating the visual ordering of logical lines which are part of a report + * organized in columns: there should not be interaction between adjacent + * cells.<p> + * + * @param pBiDi is the paragraph <code>UBiDi</code> object. + * + * @param newFn is the new callback function pointer. + * + * @param newContext is the new callback context pointer. This can be NULL. + * + * @param oldFn fillin: Returns the old callback function pointer. This can be + * NULL. + * + * @param oldContext fillin: Returns the old callback's context. This can be + * NULL. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @see ubidi_getClassCallback + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +ubidi_setClassCallback(UBiDi *pBiDi, UBiDiClassCallback *newFn, + const void *newContext, UBiDiClassCallback **oldFn, + const void **oldContext, UErrorCode *pErrorCode); + +/** + * Get the current callback function used for Bidi class determination. + * + * @param pBiDi is the paragraph <code>UBiDi</code> object. + * + * @param fn fillin: Returns the callback function pointer. + * + * @param context fillin: Returns the callback's private context. + * + * @see ubidi_setClassCallback + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +ubidi_getClassCallback(UBiDi *pBiDi, UBiDiClassCallback **fn, const void **context); + +/** + * Take a <code>UBiDi</code> object containing the reordering + * information for a piece of text (one or more paragraphs) set by + * <code>ubidi_setPara()</code> or for a line of text set by + * <code>ubidi_setLine()</code> and write a reordered string to the + * destination buffer. + * + * This function preserves the integrity of characters with multiple + * code units and (optionally) combining characters. + * Characters in RTL runs can be replaced by mirror-image characters + * in the destination buffer. Note that "real" mirroring has + * to be done in a rendering engine by glyph selection + * and that for many "mirrored" characters there are no + * Unicode characters as mirror-image equivalents. + * There are also options to insert or remove Bidi control + * characters; see the description of the <code>destSize</code> + * and <code>options</code> parameters and of the option bit flags. + * + * @param pBiDi A pointer to a <code>UBiDi</code> object that + * is set by <code>ubidi_setPara()</code> or + * <code>ubidi_setLine()</code> and contains the reordering + * information for the text that it was defined for, + * as well as a pointer to that text.<br><br> + * The text was aliased (only the pointer was stored + * without copying the contents) and must not have been modified + * since the <code>ubidi_setPara()</code> call. + * + * @param dest A pointer to where the reordered text is to be copied. + * The source text and <code>dest[destSize]</code> + * must not overlap. + * + * @param destSize The size of the <code>dest</code> buffer, + * in number of UChars. + * If the <code>UBIDI_INSERT_LRM_FOR_NUMERIC</code> + * option is set, then the destination length could be + * as large as + * <code>ubidi_getLength(pBiDi)+2*ubidi_countRuns(pBiDi)</code>. + * If the <code>UBIDI_REMOVE_BIDI_CONTROLS</code> option + * is set, then the destination length may be less than + * <code>ubidi_getLength(pBiDi)</code>. + * If none of these options is set, then the destination length + * will be exactly <code>ubidi_getProcessedLength(pBiDi)</code>. + * + * @param options A bit set of options for the reordering that control + * how the reordered text is written. + * The options include mirroring the characters on a code + * point basis and inserting LRM characters, which is used + * especially for transforming visually stored text + * to logically stored text (although this is still an + * imperfect implementation of an "inverse Bidi" algorithm + * because it uses the "forward Bidi" algorithm at its core). + * The available options are: + * <code>#UBIDI_DO_MIRRORING</code>, + * <code>#UBIDI_INSERT_LRM_FOR_NUMERIC</code>, + * <code>#UBIDI_KEEP_BASE_COMBINING</code>, + * <code>#UBIDI_OUTPUT_REVERSE</code>, + * <code>#UBIDI_REMOVE_BIDI_CONTROLS</code> + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @return The length of the output string. + * + * @see ubidi_getProcessedLength + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_writeReordered(UBiDi *pBiDi, + UChar *dest, int32_t destSize, + uint16_t options, + UErrorCode *pErrorCode); + +/** + * Reverse a Right-To-Left run of Unicode text. + * + * This function preserves the integrity of characters with multiple + * code units and (optionally) combining characters. + * Characters can be replaced by mirror-image characters + * in the destination buffer. Note that "real" mirroring has + * to be done in a rendering engine by glyph selection + * and that for many "mirrored" characters there are no + * Unicode characters as mirror-image equivalents. + * There are also options to insert or remove Bidi control + * characters. + * + * This function is the implementation for reversing RTL runs as part + * of <code>ubidi_writeReordered()</code>. For detailed descriptions + * of the parameters, see there. + * Since no Bidi controls are inserted here, the output string length + * will never exceed <code>srcLength</code>. + * + * @see ubidi_writeReordered + * + * @param src A pointer to the RTL run text. + * + * @param srcLength The length of the RTL run. + * + * @param dest A pointer to where the reordered text is to be copied. + * <code>src[srcLength]</code> and <code>dest[destSize]</code> + * must not overlap. + * + * @param destSize The size of the <code>dest</code> buffer, + * in number of UChars. + * If the <code>UBIDI_REMOVE_BIDI_CONTROLS</code> option + * is set, then the destination length may be less than + * <code>srcLength</code>. + * If this option is not set, then the destination length + * will be exactly <code>srcLength</code>. + * + * @param options A bit set of options for the reordering that control + * how the reordered text is written. + * See the <code>options</code> parameter in <code>ubidi_writeReordered()</code>. + * + * @param pErrorCode must be a valid pointer to an error code value. + * + * @return The length of the output string. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubidi_writeReverse(const UChar *src, int32_t srcLength, + UChar *dest, int32_t destSize, + uint16_t options, + UErrorCode *pErrorCode); + +/*#define BIDI_SAMPLE_CODE*/ +/*@}*/ + +#endif diff --git a/utils/openttd/unicode/ubrk.h b/utils/openttd/unicode/ubrk.h new file mode 100644 index 00000000000..d57ba37a1a2 --- /dev/null +++ b/utils/openttd/unicode/ubrk.h @@ -0,0 +1,482 @@ +/* +****************************************************************************** +* Copyright (C) 1996-2007, International Business Machines Corporation and others. +* All Rights Reserved. +****************************************************************************** +*/ + +#ifndef UBRK_H +#define UBRK_H + +#include "unicode/utypes.h" +#include "unicode/uloc.h" +#include "unicode/utext.h" + +/** + * A text-break iterator. + * For usage in C programs. + */ +#ifndef UBRK_TYPEDEF_UBREAK_ITERATOR +# define UBRK_TYPEDEF_UBREAK_ITERATOR + /** + * Opaque type representing an ICU Break iterator object. + * @stable ICU 2.0 + */ + typedef void UBreakIterator; +#endif + +#if !UCONFIG_NO_BREAK_ITERATION + +#include "unicode/parseerr.h" + +/** + * \file + * \brief C API: BreakIterator + * + * <h2> BreakIterator C API </h2> + * + * The BreakIterator C API defines methods for finding the location + * of boundaries in text. Pointer to a UBreakIterator maintain a + * current position and scan over text returning the index of characters + * where boundaries occur. + * <p> + * Line boundary analysis determines where a text string can be broken + * when line-wrapping. The mechanism correctly handles punctuation and + * hyphenated words. + * <p> + * Sentence boundary analysis allows selection with correct + * interpretation of periods within numbers and abbreviations, and + * trailing punctuation marks such as quotation marks and parentheses. + * <p> + * Word boundary analysis is used by search and replace functions, as + * well as within text editing applications that allow the user to + * select words with a double click. Word selection provides correct + * interpretation of punctuation marks within and following + * words. Characters that are not part of a word, such as symbols or + * punctuation marks, have word-breaks on both sides. + * <p> + * Character boundary analysis allows users to interact with + * characters as they expect to, for example, when moving the cursor + * through a text string. Character boundary analysis provides correct + * navigation of through character strings, regardless of how the + * character is stored. For example, an accented character might be + * stored as a base character and a diacritical mark. What users + * consider to be a character can differ between languages. + * <p> + * Title boundary analysis locates all positions, + * typically starts of words, that should be set to Title Case + * when title casing the text. + * <p> + * The text boundary positions are found according to the rules + * described in Unicode Standard Annex #29, Text Boundaries, and + * Unicode Standard Annex #14, Line Breaking Properties. These + * are available at http://www.unicode.org/reports/tr14/ and + * http://www.unicode.org/reports/tr29/. + * <p> + * In addition to the plain C API defined in this header file, an + * object oriented C++ API with equivalent functionality is defined in the + * file brkiter.h. + * <p> + * Code snippits illustrating the use of the Break Iterator APIs + * are available in the ICU User Guide, + * http://icu-project.org/userguide/boundaryAnalysis.html + * and in the sample program icu/source/samples/break/break.cpp" + */ + +/** The possible types of text boundaries. @stable ICU 2.0 */ +typedef enum UBreakIteratorType { + /** Character breaks @stable ICU 2.0 */ + UBRK_CHARACTER = 0, + /** Word breaks @stable ICU 2.0 */ + UBRK_WORD = 1, + /** Line breaks @stable ICU 2.0 */ + UBRK_LINE = 2, + /** Sentence breaks @stable ICU 2.0 */ + UBRK_SENTENCE = 3, + +#ifndef U_HIDE_DEPRECATED_API + /** + * Title Case breaks + * The iterator created using this type locates title boundaries as described for + * Unicode 3.2 only. For Unicode 4.0 and above title boundary iteration, + * please use Word Boundary iterator. + * + * @deprecated ICU 2.8 Use the word break iterator for titlecasing for Unicode 4 and later. + */ + UBRK_TITLE = 4, +#endif /* U_HIDE_DEPRECATED_API */ + UBRK_COUNT = 5 +} UBreakIteratorType; + +/** Value indicating all text boundaries have been returned. + * @stable ICU 2.0 + */ +#define UBRK_DONE ((int32_t) -1) + + +/** + * Enum constants for the word break tags returned by + * getRuleStatus(). A range of values is defined for each category of + * word, to allow for further subdivisions of a category in future releases. + * Applications should check for tag values falling within the range, rather + * than for single individual values. + * @stable ICU 2.2 +*/ +typedef enum UWordBreak { + /** Tag value for "words" that do not fit into any of other categories. + * Includes spaces and most punctuation. */ + UBRK_WORD_NONE = 0, + /** Upper bound for tags for uncategorized words. */ + UBRK_WORD_NONE_LIMIT = 100, + /** Tag value for words that appear to be numbers, lower limit. */ + UBRK_WORD_NUMBER = 100, + /** Tag value for words that appear to be numbers, upper limit. */ + UBRK_WORD_NUMBER_LIMIT = 200, + /** Tag value for words that contain letters, excluding + * hiragana, katakana or ideographic characters, lower limit. */ + UBRK_WORD_LETTER = 200, + /** Tag value for words containing letters, upper limit */ + UBRK_WORD_LETTER_LIMIT = 300, + /** Tag value for words containing kana characters, lower limit */ + UBRK_WORD_KANA = 300, + /** Tag value for words containing kana characters, upper limit */ + UBRK_WORD_KANA_LIMIT = 400, + /** Tag value for words containing ideographic characters, lower limit */ + UBRK_WORD_IDEO = 400, + /** Tag value for words containing ideographic characters, upper limit */ + UBRK_WORD_IDEO_LIMIT = 500 +} UWordBreak; + +/** + * Enum constants for the line break tags returned by getRuleStatus(). + * A range of values is defined for each category of + * word, to allow for further subdivisions of a category in future releases. + * Applications should check for tag values falling within the range, rather + * than for single individual values. + * @stable ICU 2.8 +*/ +typedef enum ULineBreakTag { + /** Tag value for soft line breaks, positions at which a line break + * is acceptable but not required */ + UBRK_LINE_SOFT = 0, + /** Upper bound for soft line breaks. */ + UBRK_LINE_SOFT_LIMIT = 100, + /** Tag value for a hard, or mandatory line break */ + UBRK_LINE_HARD = 100, + /** Upper bound for hard line breaks. */ + UBRK_LINE_HARD_LIMIT = 200 +} ULineBreakTag; + + + +/** + * Enum constants for the sentence break tags returned by getRuleStatus(). + * A range of values is defined for each category of + * sentence, to allow for further subdivisions of a category in future releases. + * Applications should check for tag values falling within the range, rather + * than for single individual values. + * @stable ICU 2.8 +*/ +typedef enum USentenceBreakTag { + /** Tag value for for sentences ending with a sentence terminator + * ('.', '?', '!', etc.) character, possibly followed by a + * hard separator (CR, LF, PS, etc.) + */ + UBRK_SENTENCE_TERM = 0, + /** Upper bound for tags for sentences ended by sentence terminators. */ + UBRK_SENTENCE_TERM_LIMIT = 100, + /** Tag value for for sentences that do not contain an ending + * sentence terminator ('.', '?', '!', etc.) character, but + * are ended only by a hard separator (CR, LF, PS, etc.) or end of input. + */ + UBRK_SENTENCE_SEP = 100, + /** Upper bound for tags for sentences ended by a separator. */ + UBRK_SENTENCE_SEP_LIMIT = 200 + /** Tag value for a hard, or mandatory line break */ +} USentenceBreakTag; + + +/** + * Open a new UBreakIterator for locating text boundaries for a specified locale. + * A UBreakIterator may be used for detecting character, line, word, + * and sentence breaks in text. + * @param type The type of UBreakIterator to open: one of UBRK_CHARACTER, UBRK_WORD, + * UBRK_LINE, UBRK_SENTENCE + * @param locale The locale specifying the text-breaking conventions. + * @param text The text to be iterated over. + * @param textLength The number of characters in text, or -1 if null-terminated. + * @param status A UErrorCode to receive any errors. + * @return A UBreakIterator for the specified locale. + * @see ubrk_openRules + * @stable ICU 2.0 + */ +U_STABLE UBreakIterator* U_EXPORT2 +ubrk_open(UBreakIteratorType type, + const char *locale, + const UChar *text, + int32_t textLength, + UErrorCode *status); + +/** + * Open a new UBreakIterator for locating text boundaries using specified breaking rules. + * The rule syntax is ... (TBD) + * @param rules A set of rules specifying the text breaking conventions. + * @param rulesLength The number of characters in rules, or -1 if null-terminated. + * @param text The text to be iterated over. May be null, in which case ubrk_setText() is + * used to specify the text to be iterated. + * @param textLength The number of characters in text, or -1 if null-terminated. + * @param parseErr Receives position and context information for any syntax errors + * detected while parsing the rules. + * @param status A UErrorCode to receive any errors. + * @return A UBreakIterator for the specified rules. + * @see ubrk_open + * @stable ICU 2.2 + */ +U_STABLE UBreakIterator* U_EXPORT2 +ubrk_openRules(const UChar *rules, + int32_t rulesLength, + const UChar *text, + int32_t textLength, + UParseError *parseErr, + UErrorCode *status); + +/** + * Thread safe cloning operation + * @param bi iterator to be cloned + * @param stackBuffer user allocated space for the new clone. If NULL new memory will be allocated. + * If buffer is not large enough, new memory will be allocated. + * Clients can use the U_BRK_SAFECLONE_BUFFERSIZE. This will probably be enough to avoid memory allocations. + * @param pBufferSize pointer to size of allocated space. + * If *pBufferSize == 0, a sufficient size for use in cloning will + * be returned ('pre-flighting') + * If *pBufferSize is not enough for a stack-based safe clone, + * new memory will be allocated. + * @param status to indicate whether the operation went on smoothly or there were errors + * An informational status value, U_SAFECLONE_ALLOCATED_ERROR, is used if any allocations were necessary. + * @return pointer to the new clone + * @stable ICU 2.0 + */ +U_STABLE UBreakIterator * U_EXPORT2 +ubrk_safeClone( + const UBreakIterator *bi, + void *stackBuffer, + int32_t *pBufferSize, + UErrorCode *status); + +/** + * A recommended size (in bytes) for the memory buffer to be passed to ubrk_saveClone(). + * @stable ICU 2.0 + */ +#define U_BRK_SAFECLONE_BUFFERSIZE 512 + +/** +* Close a UBreakIterator. +* Once closed, a UBreakIterator may no longer be used. +* @param bi The break iterator to close. + * @stable ICU 2.0 +*/ +U_STABLE void U_EXPORT2 +ubrk_close(UBreakIterator *bi); + +/** + * Sets an existing iterator to point to a new piece of text + * @param bi The iterator to use + * @param text The text to be set + * @param textLength The length of the text + * @param status The error code + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ubrk_setText(UBreakIterator* bi, + const UChar* text, + int32_t textLength, + UErrorCode* status); + + +/** + * Sets an existing iterator to point to a new piece of text + * @param bi The iterator to use + * @param text The text to be set. + * This function makes a shallow clone of the supplied UText. This means + * that the caller is free to immediately close or otherwise reuse the + * UText that was passed as a parameter, but that the underlying text itself + * must not be altered while being referenced by the break iterator. + * @param status The error code + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +ubrk_setUText(UBreakIterator* bi, + UText* text, + UErrorCode* status); + + + +/** + * Determine the most recently-returned text boundary. + * + * @param bi The break iterator to use. + * @return The character index most recently returned by \ref ubrk_next, \ref ubrk_previous, + * \ref ubrk_first, or \ref ubrk_last. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_current(const UBreakIterator *bi); + +/** + * Determine the text boundary following the current text boundary. + * + * @param bi The break iterator to use. + * @return The character index of the next text boundary, or UBRK_DONE + * if all text boundaries have been returned. + * @see ubrk_previous + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_next(UBreakIterator *bi); + +/** + * Determine the text boundary preceding the current text boundary. + * + * @param bi The break iterator to use. + * @return The character index of the preceding text boundary, or UBRK_DONE + * if all text boundaries have been returned. + * @see ubrk_next + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_previous(UBreakIterator *bi); + +/** + * Determine the index of the first character in the text being scanned. + * This is not always the same as index 0 of the text. + * @param bi The break iterator to use. + * @return The character index of the first character in the text being scanned. + * @see ubrk_last + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_first(UBreakIterator *bi); + +/** + * Determine the index immediately <EM>beyond</EM> the last character in the text being + * scanned. + * This is not the same as the last character. + * @param bi The break iterator to use. + * @return The character offset immediately <EM>beyond</EM> the last character in the + * text being scanned. + * @see ubrk_first + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_last(UBreakIterator *bi); + +/** + * Determine the text boundary preceding the specified offset. + * The value returned is always smaller than offset, or UBRK_DONE. + * @param bi The break iterator to use. + * @param offset The offset to begin scanning. + * @return The text boundary preceding offset, or UBRK_DONE. + * @see ubrk_following + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_preceding(UBreakIterator *bi, + int32_t offset); + +/** + * Determine the text boundary following the specified offset. + * The value returned is always greater than offset, or UBRK_DONE. + * @param bi The break iterator to use. + * @param offset The offset to begin scanning. + * @return The text boundary following offset, or UBRK_DONE. + * @see ubrk_preceding + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_following(UBreakIterator *bi, + int32_t offset); + +/** +* Get a locale for which text breaking information is available. +* A UBreakIterator in a locale returned by this function will perform the correct +* text breaking for the locale. +* @param index The index of the desired locale. +* @return A locale for which number text breaking information is available, or 0 if none. +* @see ubrk_countAvailable +* @stable ICU 2.0 +*/ +U_STABLE const char* U_EXPORT2 +ubrk_getAvailable(int32_t index); + +/** +* Determine how many locales have text breaking information available. +* This function is most useful as determining the loop ending condition for +* calls to \ref ubrk_getAvailable. +* @return The number of locales for which text breaking information is available. +* @see ubrk_getAvailable +* @stable ICU 2.0 +*/ +U_STABLE int32_t U_EXPORT2 +ubrk_countAvailable(void); + + +/** +* Returns true if the specfied position is a boundary position. As a side +* effect, leaves the iterator pointing to the first boundary position at +* or after "offset". +* @param bi The break iterator to use. +* @param offset the offset to check. +* @return True if "offset" is a boundary position. +* @stable ICU 2.0 +*/ +U_STABLE UBool U_EXPORT2 +ubrk_isBoundary(UBreakIterator *bi, int32_t offset); + +/** + * Return the status from the break rule that determined the most recently + * returned break position. The values appear in the rule source + * within brackets, {123}, for example. For rules that do not specify a + * status, a default value of 0 is returned. + * <p> + * For word break iterators, the possible values are defined in enum UWordBreak. + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_getRuleStatus(UBreakIterator *bi); + +/** + * Get the statuses from the break rules that determined the most recently + * returned break position. The values appear in the rule source + * within brackets, {123}, for example. The default status value for rules + * that do not explicitly provide one is zero. + * <p> + * For word break iterators, the possible values are defined in enum UWordBreak. + * @param bi The break iterator to use + * @param fillInVec an array to be filled in with the status values. + * @param capacity the length of the supplied vector. A length of zero causes + * the function to return the number of status values, in the + * normal way, without attemtping to store any values. + * @param status receives error codes. + * @return The number of rule status values from rules that determined + * the most recent boundary returned by the break iterator. + * @stable ICU 3.0 + */ +U_STABLE int32_t U_EXPORT2 +ubrk_getRuleStatusVec(UBreakIterator *bi, int32_t *fillInVec, int32_t capacity, UErrorCode *status); + +/** + * Return the locale of the break iterator. You can choose between the valid and + * the actual locale. + * @param bi break iterator + * @param type locale type (valid or actual) + * @param status error code + * @return locale string + * @stable ICU 2.8 + */ +U_STABLE const char* U_EXPORT2 +ubrk_getLocaleByType(const UBreakIterator *bi, ULocDataLocaleType type, UErrorCode* status); + + +#endif /* #if !UCONFIG_NO_BREAK_ITERATION */ + +#endif diff --git a/utils/openttd/unicode/ucasemap.h b/utils/openttd/unicode/ucasemap.h new file mode 100644 index 00000000000..75e818d6ae3 --- /dev/null +++ b/utils/openttd/unicode/ucasemap.h @@ -0,0 +1,395 @@ +/* +******************************************************************************* +* +* Copyright (C) 2005-2008, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: ucasemap.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2005may06 +* created by: Markus W. Scherer +* +* Case mapping service object and functions using it. +*/ + +#ifndef __UCASEMAP_H__ +#define __UCASEMAP_H__ + +#include "unicode/utypes.h" +#include "unicode/ustring.h" + +/** + * \file + * \brief C API: Unicode case mapping functions using a UCaseMap service object. + * + * The service object takes care of memory allocations, data loading, and setup + * for the attributes, as usual. + * + * Currently, the functionality provided here does not overlap with uchar.h + * and ustring.h, except for ucasemap_toTitle(). + * + * ucasemap_utf8XYZ() functions operate directly on UTF-8 strings. + */ + +/** + * UCaseMap is an opaque service object for newer ICU case mapping functions. + * Older functions did not use a service object. + * @stable ICU 3.4 + */ +struct UCaseMap; +typedef struct UCaseMap UCaseMap; /**< C typedef for struct UCaseMap. @stable ICU 3.4 */ + +/** + * Open a UCaseMap service object for a locale and a set of options. + * The locale ID and options are preprocessed so that functions using the + * service object need not process them in each call. + * + * @param locale ICU locale ID, used for language-dependent + * upper-/lower-/title-casing according to the Unicode standard. + * Usual semantics: ""=root, NULL=default locale, etc. + * @param options Options bit set, used for case folding and string comparisons. + * Same flags as for u_foldCase(), u_strFoldCase(), + * u_strCaseCompare(), etc. + * Use 0 or U_FOLD_CASE_DEFAULT for default behavior. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return Pointer to a UCaseMap service object, if successful. + * + * @see U_FOLD_CASE_DEFAULT + * @see U_FOLD_CASE_EXCLUDE_SPECIAL_I + * @see U_TITLECASE_NO_LOWERCASE + * @see U_TITLECASE_NO_BREAK_ADJUSTMENT + * @stable ICU 3.4 + */ +U_STABLE UCaseMap * U_EXPORT2 +ucasemap_open(const char *locale, uint32_t options, UErrorCode *pErrorCode); + +/** + * Close a UCaseMap service object. + * @param csm Object to be closed. + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +ucasemap_close(UCaseMap *csm); + +/** + * Get the locale ID that is used for language-dependent case mappings. + * @param csm UCaseMap service object. + * @return locale ID + * @stable ICU 3.4 + */ +U_STABLE const char * U_EXPORT2 +ucasemap_getLocale(const UCaseMap *csm); + +/** + * Get the options bit set that is used for case folding and string comparisons. + * @param csm UCaseMap service object. + * @return options bit set + * @stable ICU 3.4 + */ +U_STABLE uint32_t U_EXPORT2 +ucasemap_getOptions(const UCaseMap *csm); + +/** + * Set the locale ID that is used for language-dependent case mappings. + * + * @param csm UCaseMap service object. + * @param locale Locale ID, see ucasemap_open(). + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * + * @see ucasemap_open + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +ucasemap_setLocale(UCaseMap *csm, const char *locale, UErrorCode *pErrorCode); + +/** + * Set the options bit set that is used for case folding and string comparisons. + * + * @param csm UCaseMap service object. + * @param options Options bit set, see ucasemap_open(). + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * + * @see ucasemap_open + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +ucasemap_setOptions(UCaseMap *csm, uint32_t options, UErrorCode *pErrorCode); + +#ifndef U_HIDE_DRAFT_API + +/** + * Do not lowercase non-initial parts of words when titlecasing. + * Option bit for titlecasing APIs that take an options bit set. + * + * By default, titlecasing will titlecase the first cased character + * of a word and lowercase all other characters. + * With this option, the other characters will not be modified. + * + * @see ucasemap_setOptions + * @see ucasemap_toTitle + * @see ucasemap_utf8ToTitle + * @see UnicodeString::toTitle + * @stable ICU 4.0 + */ +#define U_TITLECASE_NO_LOWERCASE 0x100 + +/** + * Do not adjust the titlecasing indexes from BreakIterator::next() indexes; + * titlecase exactly the characters at breaks from the iterator. + * Option bit for titlecasing APIs that take an options bit set. + * + * By default, titlecasing will take each break iterator index, + * adjust it by looking for the next cased character, and titlecase that one. + * Other characters are lowercased. + * + * This follows Unicode 4 & 5 section 3.13 Default Case Operations: + * + * R3 toTitlecase(X): Find the word boundaries based on Unicode Standard Annex + * #29, "Text Boundaries." Between each pair of word boundaries, find the first + * cased character F. If F exists, map F to default_title(F); then map each + * subsequent character C to default_lower(C). + * + * @see ucasemap_setOptions + * @see ucasemap_toTitle + * @see ucasemap_utf8ToTitle + * @see UnicodeString::toTitle + * @see U_TITLECASE_NO_LOWERCASE + * @stable ICU 4.0 + */ +#define U_TITLECASE_NO_BREAK_ADJUSTMENT 0x200 + +#endif + +#if !UCONFIG_NO_BREAK_ITERATION + +/** + * Get the break iterator that is used for titlecasing. + * Do not modify the returned break iterator. + * @param csm UCaseMap service object. + * @return titlecasing break iterator + * @stable ICU 4.0 + */ +U_DRAFT const UBreakIterator * U_EXPORT2 +ucasemap_getBreakIterator(const UCaseMap *csm); + +/** + * Set the break iterator that is used for titlecasing. + * The UCaseMap service object releases a previously set break iterator + * and "adopts" this new one, taking ownership of it. + * It will be released in a subsequent call to ucasemap_setBreakIterator() + * or ucasemap_close(). + * + * Break iterator operations are not thread-safe. Therefore, titlecasing + * functions use non-const UCaseMap objects. It is not possible to titlecase + * strings concurrently using the same UCaseMap. + * + * @param csm UCaseMap service object. + * @param iterToAdopt Break iterator to be adopted for titlecasing. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * + * @see ucasemap_toTitle + * @see ucasemap_utf8ToTitle + * @stable ICU 4.0 + */ +U_DRAFT void U_EXPORT2 +ucasemap_setBreakIterator(UCaseMap *csm, UBreakIterator *iterToAdopt, UErrorCode *pErrorCode); + +/** + * Titlecase a UTF-16 string. This function is almost a duplicate of u_strToTitle(), + * except that it takes ucasemap_setOptions() into account and has performance + * advantages from being able to use a UCaseMap object for multiple case mapping + * operations, saving setup time. + * + * Casing is locale-dependent and context-sensitive. + * Titlecasing uses a break iterator to find the first characters of words + * that are to be titlecased. It titlecases those characters and lowercases + * all others. (This can be modified with ucasemap_setOptions().) + * + * The titlecase break iterator can be provided to customize for arbitrary + * styles, using rules and dictionaries beyond the standard iterators. + * It may be more efficient to always provide an iterator to avoid + * opening and closing one for each string. + * The standard titlecase iterator for the root locale implements the + * algorithm of Unicode TR 21. + * + * This function uses only the setText(), first() and next() methods of the + * provided break iterator. + * + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param csm UCaseMap service object. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful - or in case of a buffer overflow, + * in which case it will be greater than destCapacity. + * + * @see u_strToTitle + * @stable ICU 4.0 + */ +U_DRAFT int32_t U_EXPORT2 +ucasemap_toTitle(UCaseMap *csm, + UChar *dest, int32_t destCapacity, + const UChar *src, int32_t srcLength, + UErrorCode *pErrorCode); + +#endif + +/** + * Lowercase the characters in a UTF-8 string. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param csm UCaseMap service object. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful - or in case of a buffer overflow, + * in which case it will be greater than destCapacity. + * + * @see u_strToLower + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +ucasemap_utf8ToLower(const UCaseMap *csm, + char *dest, int32_t destCapacity, + const char *src, int32_t srcLength, + UErrorCode *pErrorCode); + +/** + * Uppercase the characters in a UTF-8 string. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param csm UCaseMap service object. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful - or in case of a buffer overflow, + * in which case it will be greater than destCapacity. + * + * @see u_strToUpper + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +ucasemap_utf8ToUpper(const UCaseMap *csm, + char *dest, int32_t destCapacity, + const char *src, int32_t srcLength, + UErrorCode *pErrorCode); + +#if !UCONFIG_NO_BREAK_ITERATION + +/** + * Titlecase a UTF-8 string. + * Casing is locale-dependent and context-sensitive. + * Titlecasing uses a break iterator to find the first characters of words + * that are to be titlecased. It titlecases those characters and lowercases + * all others. (This can be modified with ucasemap_setOptions().) + * + * The titlecase break iterator can be provided to customize for arbitrary + * styles, using rules and dictionaries beyond the standard iterators. + * It may be more efficient to always provide an iterator to avoid + * opening and closing one for each string. + * The standard titlecase iterator for the root locale implements the + * algorithm of Unicode TR 21. + * + * This function uses only the setText(), first() and next() methods of the + * provided break iterator. + * + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param csm UCaseMap service object. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful - or in case of a buffer overflow, + * in which case it will be greater than destCapacity. + * + * @see u_strToTitle + * @see U_TITLECASE_NO_LOWERCASE + * @see U_TITLECASE_NO_BREAK_ADJUSTMENT + * @stable ICU 4.0 + */ +U_DRAFT int32_t U_EXPORT2 +ucasemap_utf8ToTitle(UCaseMap *csm, + char *dest, int32_t destCapacity, + const char *src, int32_t srcLength, + UErrorCode *pErrorCode); + +#endif + +/** + * Case-fold the characters in a UTF-8 string. + * Case-folding is locale-independent and not context-sensitive, + * but there is an option for whether to include or exclude mappings for dotted I + * and dotless i that are marked with 'I' in CaseFolding.txt. + * The result may be longer or shorter than the original. + * The source string and the destination buffer must not overlap. + * + * @param csm UCaseMap service object. + * @param dest A buffer for the result string. The result will be NUL-terminated if + * the buffer is large enough. + * The contents is undefined in case of failure. + * @param destCapacity The size of the buffer (number of bytes). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param src The original string. + * @param srcLength The length of the original string. If -1, then src must be NUL-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The length of the result string, if successful - or in case of a buffer overflow, + * in which case it will be greater than destCapacity. + * + * @see u_strFoldCase + * @see ucasemap_setOptions + * @see U_FOLD_CASE_DEFAULT + * @see U_FOLD_CASE_EXCLUDE_SPECIAL_I + * @stable ICU 4.0 + */ +U_DRAFT int32_t U_EXPORT2 +ucasemap_utf8FoldCase(const UCaseMap *csm, + char *dest, int32_t destCapacity, + const char *src, int32_t srcLength, + UErrorCode *pErrorCode); + +#endif diff --git a/utils/openttd/unicode/ucat.h b/utils/openttd/unicode/ucat.h new file mode 100644 index 00000000000..ad9f0373a30 --- /dev/null +++ b/utils/openttd/unicode/ucat.h @@ -0,0 +1,158 @@ +/* +********************************************************************** +* Copyright (c) 2003-2004, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* Author: Alan Liu +* Created: March 19 2003 +* Since: ICU 2.6 +********************************************************************** +*/ +#ifndef UCAT_H +#define UCAT_H + +#include "unicode/utypes.h" +#include "unicode/ures.h" + +/** + * \file + * \brief C API: Message Catalog Wrappers + * + * This C API provides look-alike functions that deliberately resemble + * the POSIX catopen, catclose, and catgets functions. The underlying + * implementation is in terms of ICU resource bundles, rather than + * POSIX message catalogs. + * + * The ICU resource bundles obey standard ICU inheritance policies. + * To facilitate this, sets and messages are flattened into one tier. + * This is done by creating resource bundle keys of the form + * <set_num>%<msg_num> where set_num is the set number and msg_num is + * the message number, formatted as decimal strings. + * + * Example: Consider a message catalog containing two sets: + * + * Set 1: Message 4 = "Good morning." + * Message 5 = "Good afternoon." + * Message 7 = "Good evening." + * Message 8 = "Good night." + * Set 4: Message 14 = "Please " + * Message 19 = "Thank you." + * Message 20 = "Sincerely," + * + * The ICU resource bundle source file would, assuming it is named + * "greet.txt", would look like this: + * + * greet + * { + * 1%4 { "Good morning." } + * 1%5 { "Good afternoon." } + * 1%7 { "Good evening." } + * 1%8 { "Good night." } + * + * 4%14 { "Please " } + * 4%19 { "Thank you." } + * 4%20 { "Sincerely," } + * } + * + * The catgets function is commonly used in combination with functions + * like printf and strftime. ICU components like message format can + * be used instead, although they use a different format syntax. + * There is an ICU package, icuio, that provides some of + * the POSIX-style formatting API. + */ + +U_CDECL_BEGIN + +/** + * An ICU message catalog descriptor, analogous to nl_catd. + * + * @stable ICU 2.6 + */ +typedef UResourceBundle* u_nl_catd; + +/** + * Open and return an ICU message catalog descriptor. The descriptor + * may be passed to u_catgets() to retrieve localized strings. + * + * @param name string containing the full path pointing to the + * directory where the resources reside followed by the package name + * e.g. "/usr/resource/my_app/resources/guimessages" on a Unix system. + * If NULL, ICU default data files will be used. + * + * Unlike POSIX, environment variables are not interpolated within the + * name. + * + * @param locale the locale for which we want to open the resource. If + * NULL, the default ICU locale will be used (see uloc_getDefault). If + * strlen(locale) == 0, the root locale will be used. + * + * @param ec input/output error code. Upon output, + * U_USING_FALLBACK_WARNING indicates that a fallback locale was + * used. For example, 'de_CH' was requested, but nothing was found + * there, so 'de' was used. U_USING_DEFAULT_WARNING indicates that the + * default locale data or root locale data was used; neither the + * requested locale nor any of its fallback locales were found. + * + * @return a message catalog descriptor that may be passed to + * u_catgets(). If the ec parameter indicates success, then the caller + * is responsible for calling u_catclose() to close the message + * catalog. If the ec parameter indicates failure, then NULL will be + * returned. + * + * @stable ICU 2.6 + */ +U_STABLE u_nl_catd U_EXPORT2 +u_catopen(const char* name, const char* locale, UErrorCode* ec); + +/** + * Close an ICU message catalog, given its descriptor. + * + * @param catd a message catalog descriptor to be closed. May be NULL, + * in which case no action is taken. + * + * @stable ICU 2.6 + */ +U_STABLE void U_EXPORT2 +u_catclose(u_nl_catd catd); + +/** + * Retrieve a localized string from an ICU message catalog. + * + * @param catd a message catalog descriptor returned by u_catopen. + * + * @param set_num the message catalog set number. Sets need not be + * numbered consecutively. + * + * @param msg_num the message catalog message number within the + * set. Messages need not be numbered consecutively. + * + * @param s the default string. This is returned if the string + * specified by the set_num and msg_num is not found. It must be + * zero-terminated. + * + * @param len fill-in parameter to receive the length of the result. + * May be NULL, in which case it is ignored. + * + * @param ec input/output error code. May be U_USING_FALLBACK_WARNING + * or U_USING_DEFAULT_WARNING. U_MISSING_RESOURCE_ERROR indicates that + * the set_num/msg_num tuple does not specify a valid message string + * in this catalog. + * + * @return a pointer to a zero-terminated UChar array which lives in + * an internal buffer area, typically a memory mapped/DLL file. The + * caller must NOT delete this pointer. If the call is unsuccessful + * for any reason, then s is returned. This includes the situation in + * which ec indicates a failing error code upon entry to this + * function. + * + * @stable ICU 2.6 + */ +U_STABLE const UChar* U_EXPORT2 +u_catgets(u_nl_catd catd, int32_t set_num, int32_t msg_num, + const UChar* s, + int32_t* len, UErrorCode* ec); + +U_CDECL_END + +#endif /*UCAT_H*/ +/*eof*/ diff --git a/utils/openttd/unicode/uchar.h b/utils/openttd/unicode/uchar.h new file mode 100644 index 00000000000..0f629c0d3c8 --- /dev/null +++ b/utils/openttd/unicode/uchar.h @@ -0,0 +1,3062 @@ +/* +********************************************************************** +* Copyright (C) 1997-2008, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* +* File UCHAR.H +* +* Modification History: +* +* Date Name Description +* 04/02/97 aliu Creation. +* 03/29/99 helena Updated for C APIs. +* 4/15/99 Madhu Updated for C Implementation and Javadoc +* 5/20/99 Madhu Added the function u_getVersion() +* 8/19/1999 srl Upgraded scripts to Unicode 3.0 +* 8/27/1999 schererm UCharDirection constants: U_... +* 11/11/1999 weiv added u_isalnum(), cleaned comments +* 01/11/2000 helena Renamed u_getVersion to u_getUnicodeVersion(). +****************************************************************************** +*/ + +#ifndef UCHAR_H +#define UCHAR_H + +#include "unicode/utypes.h" + +U_CDECL_BEGIN + +/*==========================================================================*/ +/* Unicode version number */ +/*==========================================================================*/ +/** + * Unicode version number, default for the current ICU version. + * The actual Unicode Character Database (UCD) data is stored in uprops.dat + * and may be generated from UCD files from a different Unicode version. + * Call u_getUnicodeVersion to get the actual Unicode version of the data. + * + * @see u_getUnicodeVersion + * @stable ICU 2.0 + */ +#define U_UNICODE_VERSION "5.1" + +/** + * \file + * \brief C API: Unicode Properties + * + * This C API provides low-level access to the Unicode Character Database. + * In addition to raw property values, some convenience functions calculate + * derived properties, for example for Java-style programming. + * + * Unicode assigns each code point (not just assigned character) values for + * many properties. + * Most of them are simple boolean flags, or constants from a small enumerated list. + * For some properties, values are strings or other relatively more complex types. + * + * For more information see + * "About the Unicode Character Database" (http://www.unicode.org/ucd/) + * and the ICU User Guide chapter on Properties (http://icu-project.org/userguide/properties.html). + * + * Many functions are designed to match java.lang.Character functions. + * See the individual function documentation, + * and see the JDK 1.4 java.lang.Character documentation + * at http://java.sun.com/j2se/1.4/docs/api/java/lang/Character.html + * + * There are also functions that provide easy migration from C/POSIX functions + * like isblank(). Their use is generally discouraged because the C/POSIX + * standards do not define their semantics beyond the ASCII range, which means + * that different implementations exhibit very different behavior. + * Instead, Unicode properties should be used directly. + * + * There are also only a few, broad C/POSIX character classes, and they tend + * to be used for conflicting purposes. For example, the "isalpha()" class + * is sometimes used to determine word boundaries, while a more sophisticated + * approach would at least distinguish initial letters from continuation + * characters (the latter including combining marks). + * (In ICU, BreakIterator is the most sophisticated API for word boundaries.) + * Another example: There is no "istitle()" class for titlecase characters. + * + * ICU 3.4 and later provides API access for all twelve C/POSIX character classes. + * ICU implements them according to the Standard Recommendations in + * Annex C: Compatibility Properties of UTS #18 Unicode Regular Expressions + * (http://www.unicode.org/reports/tr18/#Compatibility_Properties). + * + * API access for C/POSIX character classes is as follows: + * - alpha: u_isUAlphabetic(c) or u_hasBinaryProperty(c, UCHAR_ALPHABETIC) + * - lower: u_isULowercase(c) or u_hasBinaryProperty(c, UCHAR_LOWERCASE) + * - upper: u_isUUppercase(c) or u_hasBinaryProperty(c, UCHAR_UPPERCASE) + * - punct: u_ispunct(c) + * - digit: u_isdigit(c) or u_charType(c)==U_DECIMAL_DIGIT_NUMBER + * - xdigit: u_isxdigit(c) or u_hasBinaryProperty(c, UCHAR_POSIX_XDIGIT) + * - alnum: u_hasBinaryProperty(c, UCHAR_POSIX_ALNUM) + * - space: u_isUWhiteSpace(c) or u_hasBinaryProperty(c, UCHAR_WHITE_SPACE) + * - blank: u_isblank(c) or u_hasBinaryProperty(c, UCHAR_POSIX_BLANK) + * - cntrl: u_charType(c)==U_CONTROL_CHAR + * - graph: u_hasBinaryProperty(c, UCHAR_POSIX_GRAPH) + * - print: u_hasBinaryProperty(c, UCHAR_POSIX_PRINT) + * + * Note: Some of the u_isxyz() functions in uchar.h predate, and do not match, + * the Standard Recommendations in UTS #18. Instead, they match Java + * functions according to their API documentation. + * + * \htmlonly + * The C/POSIX character classes are also available in UnicodeSet patterns, + * using patterns like [:graph:] or \p{graph}. + * \endhtmlonly + * + * Note: There are several ICU whitespace functions. + * Comparison: + * - u_isUWhiteSpace=UCHAR_WHITE_SPACE: Unicode White_Space property; + * most of general categories "Z" (separators) + most whitespace ISO controls + * (including no-break spaces, but excluding IS1..IS4 and ZWSP) + * - u_isWhitespace: Java isWhitespace; Z + whitespace ISO controls but excluding no-break spaces + * - u_isJavaSpaceChar: Java isSpaceChar; just Z (including no-break spaces) + * - u_isspace: Z + whitespace ISO controls (including no-break spaces) + * - u_isblank: "horizontal spaces" = TAB + Zs - ZWSP + */ + +/** + * Constants. + */ + +/** The lowest Unicode code point value. Code points are non-negative. @stable ICU 2.0 */ +#define UCHAR_MIN_VALUE 0 + +/** + * The highest Unicode code point value (scalar value) according to + * The Unicode Standard. This is a 21-bit value (20.1 bits, rounded up). + * For a single character, UChar32 is a simple type that can hold any code point value. + * + * @see UChar32 + * @stable ICU 2.0 + */ +#define UCHAR_MAX_VALUE 0x10ffff + +/** + * Get a single-bit bit set (a flag) from a bit number 0..31. + * @stable ICU 2.1 + */ +#define U_MASK(x) ((uint32_t)1<<(x)) + +/* + * !! Note: Several comments in this file are machine-read by the + * genpname tool. These comments describe the correspondence between + * icu enum constants and UCD entities. Do not delete them. Update + * these comments as needed. + * + * Any comment of the form "/ *[name]* /" (spaces added) is such + * a comment. + * + * The U_JG_* and U_GC_*_MASK constants are matched by their symbolic + * name, which must match PropertyValueAliases.txt. + */ + +/** + * Selection constants for Unicode properties. + * These constants are used in functions like u_hasBinaryProperty to select + * one of the Unicode properties. + * + * The properties APIs are intended to reflect Unicode properties as defined + * in the Unicode Character Database (UCD) and Unicode Technical Reports (UTR). + * For details about the properties see http://www.unicode.org/ucd/ . + * For names of Unicode properties see the UCD file PropertyAliases.txt. + * + * Important: If ICU is built with UCD files from Unicode versions below, e.g., 3.2, + * then properties marked with "new in Unicode 3.2" are not or not fully available. + * Check u_getUnicodeVersion to be sure. + * + * @see u_hasBinaryProperty + * @see u_getIntPropertyValue + * @see u_getUnicodeVersion + * @stable ICU 2.1 + */ +typedef enum UProperty { + /* See note !!. Comments of the form "Binary property Dash", + "Enumerated property Script", "Double property Numeric_Value", + and "String property Age" are read by genpname. */ + + /* Note: Place UCHAR_ALPHABETIC before UCHAR_BINARY_START so that + debuggers display UCHAR_ALPHABETIC as the symbolic name for 0, + rather than UCHAR_BINARY_START. Likewise for other *_START + identifiers. */ + + /** Binary property Alphabetic. Same as u_isUAlphabetic, different from u_isalpha. + Lu+Ll+Lt+Lm+Lo+Nl+Other_Alphabetic @stable ICU 2.1 */ + UCHAR_ALPHABETIC=0, + /** First constant for binary Unicode properties. @stable ICU 2.1 */ + UCHAR_BINARY_START=UCHAR_ALPHABETIC, + /** Binary property ASCII_Hex_Digit. 0-9 A-F a-f @stable ICU 2.1 */ + UCHAR_ASCII_HEX_DIGIT=1, + /** Binary property Bidi_Control. + Format controls which have specific functions + in the Bidi Algorithm. @stable ICU 2.1 */ + UCHAR_BIDI_CONTROL=2, + /** Binary property Bidi_Mirrored. + Characters that may change display in RTL text. + Same as u_isMirrored. + See Bidi Algorithm, UTR 9. @stable ICU 2.1 */ + UCHAR_BIDI_MIRRORED=3, + /** Binary property Dash. Variations of dashes. @stable ICU 2.1 */ + UCHAR_DASH=4, + /** Binary property Default_Ignorable_Code_Point (new in Unicode 3.2). + Ignorable in most processing. + <2060..206F, FFF0..FFFB, E0000..E0FFF>+Other_Default_Ignorable_Code_Point+(Cf+Cc+Cs-White_Space) @stable ICU 2.1 */ + UCHAR_DEFAULT_IGNORABLE_CODE_POINT=5, + /** Binary property Deprecated (new in Unicode 3.2). + The usage of deprecated characters is strongly discouraged. @stable ICU 2.1 */ + UCHAR_DEPRECATED=6, + /** Binary property Diacritic. Characters that linguistically modify + the meaning of another character to which they apply. @stable ICU 2.1 */ + UCHAR_DIACRITIC=7, + /** Binary property Extender. + Extend the value or shape of a preceding alphabetic character, + e.g., length and iteration marks. @stable ICU 2.1 */ + UCHAR_EXTENDER=8, + /** Binary property Full_Composition_Exclusion. + CompositionExclusions.txt+Singleton Decompositions+ + Non-Starter Decompositions. @stable ICU 2.1 */ + UCHAR_FULL_COMPOSITION_EXCLUSION=9, + /** Binary property Grapheme_Base (new in Unicode 3.2). + For programmatic determination of grapheme cluster boundaries. + [0..10FFFF]-Cc-Cf-Cs-Co-Cn-Zl-Zp-Grapheme_Link-Grapheme_Extend-CGJ @stable ICU 2.1 */ + UCHAR_GRAPHEME_BASE=10, + /** Binary property Grapheme_Extend (new in Unicode 3.2). + For programmatic determination of grapheme cluster boundaries. + Me+Mn+Mc+Other_Grapheme_Extend-Grapheme_Link-CGJ @stable ICU 2.1 */ + UCHAR_GRAPHEME_EXTEND=11, + /** Binary property Grapheme_Link (new in Unicode 3.2). + For programmatic determination of grapheme cluster boundaries. @stable ICU 2.1 */ + UCHAR_GRAPHEME_LINK=12, + /** Binary property Hex_Digit. + Characters commonly used for hexadecimal numbers. @stable ICU 2.1 */ + UCHAR_HEX_DIGIT=13, + /** Binary property Hyphen. Dashes used to mark connections + between pieces of words, plus the Katakana middle dot. @stable ICU 2.1 */ + UCHAR_HYPHEN=14, + /** Binary property ID_Continue. + Characters that can continue an identifier. + DerivedCoreProperties.txt also says "NOTE: Cf characters should be filtered out." + ID_Start+Mn+Mc+Nd+Pc @stable ICU 2.1 */ + UCHAR_ID_CONTINUE=15, + /** Binary property ID_Start. + Characters that can start an identifier. + Lu+Ll+Lt+Lm+Lo+Nl @stable ICU 2.1 */ + UCHAR_ID_START=16, + /** Binary property Ideographic. + CJKV ideographs. @stable ICU 2.1 */ + UCHAR_IDEOGRAPHIC=17, + /** Binary property IDS_Binary_Operator (new in Unicode 3.2). + For programmatic determination of + Ideographic Description Sequences. @stable ICU 2.1 */ + UCHAR_IDS_BINARY_OPERATOR=18, + /** Binary property IDS_Trinary_Operator (new in Unicode 3.2). + For programmatic determination of + Ideographic Description Sequences. @stable ICU 2.1 */ + UCHAR_IDS_TRINARY_OPERATOR=19, + /** Binary property Join_Control. + Format controls for cursive joining and ligation. @stable ICU 2.1 */ + UCHAR_JOIN_CONTROL=20, + /** Binary property Logical_Order_Exception (new in Unicode 3.2). + Characters that do not use logical order and + require special handling in most processing. @stable ICU 2.1 */ + UCHAR_LOGICAL_ORDER_EXCEPTION=21, + /** Binary property Lowercase. Same as u_isULowercase, different from u_islower. + Ll+Other_Lowercase @stable ICU 2.1 */ + UCHAR_LOWERCASE=22, + /** Binary property Math. Sm+Other_Math @stable ICU 2.1 */ + UCHAR_MATH=23, + /** Binary property Noncharacter_Code_Point. + Code points that are explicitly defined as illegal + for the encoding of characters. @stable ICU 2.1 */ + UCHAR_NONCHARACTER_CODE_POINT=24, + /** Binary property Quotation_Mark. @stable ICU 2.1 */ + UCHAR_QUOTATION_MARK=25, + /** Binary property Radical (new in Unicode 3.2). + For programmatic determination of + Ideographic Description Sequences. @stable ICU 2.1 */ + UCHAR_RADICAL=26, + /** Binary property Soft_Dotted (new in Unicode 3.2). + Characters with a "soft dot", like i or j. + An accent placed on these characters causes + the dot to disappear. @stable ICU 2.1 */ + UCHAR_SOFT_DOTTED=27, + /** Binary property Terminal_Punctuation. + Punctuation characters that generally mark + the end of textual units. @stable ICU 2.1 */ + UCHAR_TERMINAL_PUNCTUATION=28, + /** Binary property Unified_Ideograph (new in Unicode 3.2). + For programmatic determination of + Ideographic Description Sequences. @stable ICU 2.1 */ + UCHAR_UNIFIED_IDEOGRAPH=29, + /** Binary property Uppercase. Same as u_isUUppercase, different from u_isupper. + Lu+Other_Uppercase @stable ICU 2.1 */ + UCHAR_UPPERCASE=30, + /** Binary property White_Space. + Same as u_isUWhiteSpace, different from u_isspace and u_isWhitespace. + Space characters+TAB+CR+LF-ZWSP-ZWNBSP @stable ICU 2.1 */ + UCHAR_WHITE_SPACE=31, + /** Binary property XID_Continue. + ID_Continue modified to allow closure under + normalization forms NFKC and NFKD. @stable ICU 2.1 */ + UCHAR_XID_CONTINUE=32, + /** Binary property XID_Start. ID_Start modified to allow + closure under normalization forms NFKC and NFKD. @stable ICU 2.1 */ + UCHAR_XID_START=33, + /** Binary property Case_Sensitive. Either the source of a case + mapping or _in_ the target of a case mapping. Not the same as + the general category Cased_Letter. @stable ICU 2.6 */ + UCHAR_CASE_SENSITIVE=34, + /** Binary property STerm (new in Unicode 4.0.1). + Sentence Terminal. Used in UAX #29: Text Boundaries + (http://www.unicode.org/reports/tr29/) + @stable ICU 3.0 */ + UCHAR_S_TERM=35, + /** Binary property Variation_Selector (new in Unicode 4.0.1). + Indicates all those characters that qualify as Variation Selectors. + For details on the behavior of these characters, + see StandardizedVariants.html and 15.6 Variation Selectors. + @stable ICU 3.0 */ + UCHAR_VARIATION_SELECTOR=36, + /** Binary property NFD_Inert. + ICU-specific property for characters that are inert under NFD, + i.e., they do not interact with adjacent characters. + Used for example in normalizing transforms in incremental mode + to find the boundary of safely normalizable text despite possible + text additions. + + There is one such property per normalization form. + These properties are computed as follows - an inert character is: + a) unassigned, or ALL of the following: + b) of combining class 0. + c) not decomposed by this normalization form. + AND if NFC or NFKC, + d) can never compose with a previous character. + e) can never compose with a following character. + f) can never change if another character is added. + Example: a-breve might satisfy all but f, but if you + add an ogonek it changes to a-ogonek + breve + + See also com.ibm.text.UCD.NFSkippable in the ICU4J repository, + and icu/source/common/unormimp.h . + @stable ICU 3.0 */ + UCHAR_NFD_INERT=37, + /** Binary property NFKD_Inert. + ICU-specific property for characters that are inert under NFKD, + i.e., they do not interact with adjacent characters. + Used for example in normalizing transforms in incremental mode + to find the boundary of safely normalizable text despite possible + text additions. + @see UCHAR_NFD_INERT + @stable ICU 3.0 */ + UCHAR_NFKD_INERT=38, + /** Binary property NFC_Inert. + ICU-specific property for characters that are inert under NFC, + i.e., they do not interact with adjacent characters. + Used for example in normalizing transforms in incremental mode + to find the boundary of safely normalizable text despite possible + text additions. + @see UCHAR_NFD_INERT + @stable ICU 3.0 */ + UCHAR_NFC_INERT=39, + /** Binary property NFKC_Inert. + ICU-specific property for characters that are inert under NFKC, + i.e., they do not interact with adjacent characters. + Used for example in normalizing transforms in incremental mode + to find the boundary of safely normalizable text despite possible + text additions. + @see UCHAR_NFD_INERT + @stable ICU 3.0 */ + UCHAR_NFKC_INERT=40, + /** Binary Property Segment_Starter. + ICU-specific property for characters that are starters in terms of + Unicode normalization and combining character sequences. + They have ccc=0 and do not occur in non-initial position of the + canonical decomposition of any character + (like " in NFD(a-umlaut) and a Jamo T in an NFD(Hangul LVT)). + ICU uses this property for segmenting a string for generating a set of + canonically equivalent strings, e.g. for canonical closure while + processing collation tailoring rules. + @stable ICU 3.0 */ + UCHAR_SEGMENT_STARTER=41, + /** Binary property Pattern_Syntax (new in Unicode 4.1). + See UAX #31 Identifier and Pattern Syntax + (http://www.unicode.org/reports/tr31/) + @stable ICU 3.4 */ + UCHAR_PATTERN_SYNTAX=42, + /** Binary property Pattern_White_Space (new in Unicode 4.1). + See UAX #31 Identifier and Pattern Syntax + (http://www.unicode.org/reports/tr31/) + @stable ICU 3.4 */ + UCHAR_PATTERN_WHITE_SPACE=43, + /** Binary property alnum (a C/POSIX character class). + Implemented according to the UTS #18 Annex C Standard Recommendation. + See the uchar.h file documentation. + @stable ICU 3.4 */ + UCHAR_POSIX_ALNUM=44, + /** Binary property blank (a C/POSIX character class). + Implemented according to the UTS #18 Annex C Standard Recommendation. + See the uchar.h file documentation. + @stable ICU 3.4 */ + UCHAR_POSIX_BLANK=45, + /** Binary property graph (a C/POSIX character class). + Implemented according to the UTS #18 Annex C Standard Recommendation. + See the uchar.h file documentation. + @stable ICU 3.4 */ + UCHAR_POSIX_GRAPH=46, + /** Binary property print (a C/POSIX character class). + Implemented according to the UTS #18 Annex C Standard Recommendation. + See the uchar.h file documentation. + @stable ICU 3.4 */ + UCHAR_POSIX_PRINT=47, + /** Binary property xdigit (a C/POSIX character class). + Implemented according to the UTS #18 Annex C Standard Recommendation. + See the uchar.h file documentation. + @stable ICU 3.4 */ + UCHAR_POSIX_XDIGIT=48, + /** One more than the last constant for binary Unicode properties. @stable ICU 2.1 */ + UCHAR_BINARY_LIMIT=49, + + /** Enumerated property Bidi_Class. + Same as u_charDirection, returns UCharDirection values. @stable ICU 2.2 */ + UCHAR_BIDI_CLASS=0x1000, + /** First constant for enumerated/integer Unicode properties. @stable ICU 2.2 */ + UCHAR_INT_START=UCHAR_BIDI_CLASS, + /** Enumerated property Block. + Same as ublock_getCode, returns UBlockCode values. @stable ICU 2.2 */ + UCHAR_BLOCK=0x1001, + /** Enumerated property Canonical_Combining_Class. + Same as u_getCombiningClass, returns 8-bit numeric values. @stable ICU 2.2 */ + UCHAR_CANONICAL_COMBINING_CLASS=0x1002, + /** Enumerated property Decomposition_Type. + Returns UDecompositionType values. @stable ICU 2.2 */ + UCHAR_DECOMPOSITION_TYPE=0x1003, + /** Enumerated property East_Asian_Width. + See http://www.unicode.org/reports/tr11/ + Returns UEastAsianWidth values. @stable ICU 2.2 */ + UCHAR_EAST_ASIAN_WIDTH=0x1004, + /** Enumerated property General_Category. + Same as u_charType, returns UCharCategory values. @stable ICU 2.2 */ + UCHAR_GENERAL_CATEGORY=0x1005, + /** Enumerated property Joining_Group. + Returns UJoiningGroup values. @stable ICU 2.2 */ + UCHAR_JOINING_GROUP=0x1006, + /** Enumerated property Joining_Type. + Returns UJoiningType values. @stable ICU 2.2 */ + UCHAR_JOINING_TYPE=0x1007, + /** Enumerated property Line_Break. + Returns ULineBreak values. @stable ICU 2.2 */ + UCHAR_LINE_BREAK=0x1008, + /** Enumerated property Numeric_Type. + Returns UNumericType values. @stable ICU 2.2 */ + UCHAR_NUMERIC_TYPE=0x1009, + /** Enumerated property Script. + Same as uscript_getScript, returns UScriptCode values. @stable ICU 2.2 */ + UCHAR_SCRIPT=0x100A, + /** Enumerated property Hangul_Syllable_Type, new in Unicode 4. + Returns UHangulSyllableType values. @stable ICU 2.6 */ + UCHAR_HANGUL_SYLLABLE_TYPE=0x100B, + /** Enumerated property NFD_Quick_Check. + Returns UNormalizationCheckResult values. @stable ICU 3.0 */ + UCHAR_NFD_QUICK_CHECK=0x100C, + /** Enumerated property NFKD_Quick_Check. + Returns UNormalizationCheckResult values. @stable ICU 3.0 */ + UCHAR_NFKD_QUICK_CHECK=0x100D, + /** Enumerated property NFC_Quick_Check. + Returns UNormalizationCheckResult values. @stable ICU 3.0 */ + UCHAR_NFC_QUICK_CHECK=0x100E, + /** Enumerated property NFKC_Quick_Check. + Returns UNormalizationCheckResult values. @stable ICU 3.0 */ + UCHAR_NFKC_QUICK_CHECK=0x100F, + /** Enumerated property Lead_Canonical_Combining_Class. + ICU-specific property for the ccc of the first code point + of the decomposition, or lccc(c)=ccc(NFD(c)[0]). + Useful for checking for canonically ordered text; + see UNORM_FCD and http://www.unicode.org/notes/tn5/#FCD . + Returns 8-bit numeric values like UCHAR_CANONICAL_COMBINING_CLASS. @stable ICU 3.0 */ + UCHAR_LEAD_CANONICAL_COMBINING_CLASS=0x1010, + /** Enumerated property Trail_Canonical_Combining_Class. + ICU-specific property for the ccc of the last code point + of the decomposition, or tccc(c)=ccc(NFD(c)[last]). + Useful for checking for canonically ordered text; + see UNORM_FCD and http://www.unicode.org/notes/tn5/#FCD . + Returns 8-bit numeric values like UCHAR_CANONICAL_COMBINING_CLASS. @stable ICU 3.0 */ + UCHAR_TRAIL_CANONICAL_COMBINING_CLASS=0x1011, + /** Enumerated property Grapheme_Cluster_Break (new in Unicode 4.1). + Used in UAX #29: Text Boundaries + (http://www.unicode.org/reports/tr29/) + Returns UGraphemeClusterBreak values. @stable ICU 3.4 */ + UCHAR_GRAPHEME_CLUSTER_BREAK=0x1012, + /** Enumerated property Sentence_Break (new in Unicode 4.1). + Used in UAX #29: Text Boundaries + (http://www.unicode.org/reports/tr29/) + Returns USentenceBreak values. @stable ICU 3.4 */ + UCHAR_SENTENCE_BREAK=0x1013, + /** Enumerated property Word_Break (new in Unicode 4.1). + Used in UAX #29: Text Boundaries + (http://www.unicode.org/reports/tr29/) + Returns UWordBreakValues values. @stable ICU 3.4 */ + UCHAR_WORD_BREAK=0x1014, + /** One more than the last constant for enumerated/integer Unicode properties. @stable ICU 2.2 */ + UCHAR_INT_LIMIT=0x1015, + + /** Bitmask property General_Category_Mask. + This is the General_Category property returned as a bit mask. + When used in u_getIntPropertyValue(c), same as U_MASK(u_charType(c)), + returns bit masks for UCharCategory values where exactly one bit is set. + When used with u_getPropertyValueName() and u_getPropertyValueEnum(), + a multi-bit mask is used for sets of categories like "Letters". + Mask values should be cast to uint32_t. + @stable ICU 2.4 */ + UCHAR_GENERAL_CATEGORY_MASK=0x2000, + /** First constant for bit-mask Unicode properties. @stable ICU 2.4 */ + UCHAR_MASK_START=UCHAR_GENERAL_CATEGORY_MASK, + /** One more than the last constant for bit-mask Unicode properties. @stable ICU 2.4 */ + UCHAR_MASK_LIMIT=0x2001, + + /** Double property Numeric_Value. + Corresponds to u_getNumericValue. @stable ICU 2.4 */ + UCHAR_NUMERIC_VALUE=0x3000, + /** First constant for double Unicode properties. @stable ICU 2.4 */ + UCHAR_DOUBLE_START=UCHAR_NUMERIC_VALUE, + /** One more than the last constant for double Unicode properties. @stable ICU 2.4 */ + UCHAR_DOUBLE_LIMIT=0x3001, + + /** String property Age. + Corresponds to u_charAge. @stable ICU 2.4 */ + UCHAR_AGE=0x4000, + /** First constant for string Unicode properties. @stable ICU 2.4 */ + UCHAR_STRING_START=UCHAR_AGE, + /** String property Bidi_Mirroring_Glyph. + Corresponds to u_charMirror. @stable ICU 2.4 */ + UCHAR_BIDI_MIRRORING_GLYPH=0x4001, + /** String property Case_Folding. + Corresponds to u_strFoldCase in ustring.h. @stable ICU 2.4 */ + UCHAR_CASE_FOLDING=0x4002, + /** String property ISO_Comment. + Corresponds to u_getISOComment. @stable ICU 2.4 */ + UCHAR_ISO_COMMENT=0x4003, + /** String property Lowercase_Mapping. + Corresponds to u_strToLower in ustring.h. @stable ICU 2.4 */ + UCHAR_LOWERCASE_MAPPING=0x4004, + /** String property Name. + Corresponds to u_charName. @stable ICU 2.4 */ + UCHAR_NAME=0x4005, + /** String property Simple_Case_Folding. + Corresponds to u_foldCase. @stable ICU 2.4 */ + UCHAR_SIMPLE_CASE_FOLDING=0x4006, + /** String property Simple_Lowercase_Mapping. + Corresponds to u_tolower. @stable ICU 2.4 */ + UCHAR_SIMPLE_LOWERCASE_MAPPING=0x4007, + /** String property Simple_Titlecase_Mapping. + Corresponds to u_totitle. @stable ICU 2.4 */ + UCHAR_SIMPLE_TITLECASE_MAPPING=0x4008, + /** String property Simple_Uppercase_Mapping. + Corresponds to u_toupper. @stable ICU 2.4 */ + UCHAR_SIMPLE_UPPERCASE_MAPPING=0x4009, + /** String property Titlecase_Mapping. + Corresponds to u_strToTitle in ustring.h. @stable ICU 2.4 */ + UCHAR_TITLECASE_MAPPING=0x400A, + /** String property Unicode_1_Name. + Corresponds to u_charName. @stable ICU 2.4 */ + UCHAR_UNICODE_1_NAME=0x400B, + /** String property Uppercase_Mapping. + Corresponds to u_strToUpper in ustring.h. @stable ICU 2.4 */ + UCHAR_UPPERCASE_MAPPING=0x400C, + /** One more than the last constant for string Unicode properties. @stable ICU 2.4 */ + UCHAR_STRING_LIMIT=0x400D, + + /** Represents a nonexistent or invalid property or property value. @stable ICU 2.4 */ + UCHAR_INVALID_CODE = -1 +} UProperty; + +/** + * Data for enumerated Unicode general category types. + * See http://www.unicode.org/Public/UNIDATA/UnicodeData.html . + * @stable ICU 2.0 + */ +typedef enum UCharCategory +{ + /** See note !!. Comments of the form "Cn" are read by genpname. */ + + /** Non-category for unassigned and non-character code points. @stable ICU 2.0 */ + U_UNASSIGNED = 0, + /** Cn "Other, Not Assigned (no characters in [UnicodeData.txt] have this property)" (same as U_UNASSIGNED!) @stable ICU 2.0 */ + U_GENERAL_OTHER_TYPES = 0, + /** Lu @stable ICU 2.0 */ + U_UPPERCASE_LETTER = 1, + /** Ll @stable ICU 2.0 */ + U_LOWERCASE_LETTER = 2, + /** Lt @stable ICU 2.0 */ + U_TITLECASE_LETTER = 3, + /** Lm @stable ICU 2.0 */ + U_MODIFIER_LETTER = 4, + /** Lo @stable ICU 2.0 */ + U_OTHER_LETTER = 5, + /** Mn @stable ICU 2.0 */ + U_NON_SPACING_MARK = 6, + /** Me @stable ICU 2.0 */ + U_ENCLOSING_MARK = 7, + /** Mc @stable ICU 2.0 */ + U_COMBINING_SPACING_MARK = 8, + /** Nd @stable ICU 2.0 */ + U_DECIMAL_DIGIT_NUMBER = 9, + /** Nl @stable ICU 2.0 */ + U_LETTER_NUMBER = 10, + /** No @stable ICU 2.0 */ + U_OTHER_NUMBER = 11, + /** Zs @stable ICU 2.0 */ + U_SPACE_SEPARATOR = 12, + /** Zl @stable ICU 2.0 */ + U_LINE_SEPARATOR = 13, + /** Zp @stable ICU 2.0 */ + U_PARAGRAPH_SEPARATOR = 14, + /** Cc @stable ICU 2.0 */ + U_CONTROL_CHAR = 15, + /** Cf @stable ICU 2.0 */ + U_FORMAT_CHAR = 16, + /** Co @stable ICU 2.0 */ + U_PRIVATE_USE_CHAR = 17, + /** Cs @stable ICU 2.0 */ + U_SURROGATE = 18, + /** Pd @stable ICU 2.0 */ + U_DASH_PUNCTUATION = 19, + /** Ps @stable ICU 2.0 */ + U_START_PUNCTUATION = 20, + /** Pe @stable ICU 2.0 */ + U_END_PUNCTUATION = 21, + /** Pc @stable ICU 2.0 */ + U_CONNECTOR_PUNCTUATION = 22, + /** Po @stable ICU 2.0 */ + U_OTHER_PUNCTUATION = 23, + /** Sm @stable ICU 2.0 */ + U_MATH_SYMBOL = 24, + /** Sc @stable ICU 2.0 */ + U_CURRENCY_SYMBOL = 25, + /** Sk @stable ICU 2.0 */ + U_MODIFIER_SYMBOL = 26, + /** So @stable ICU 2.0 */ + U_OTHER_SYMBOL = 27, + /** Pi @stable ICU 2.0 */ + U_INITIAL_PUNCTUATION = 28, + /** Pf @stable ICU 2.0 */ + U_FINAL_PUNCTUATION = 29, + /** One higher than the last enum UCharCategory constant. @stable ICU 2.0 */ + U_CHAR_CATEGORY_COUNT +} UCharCategory; + +/** + * U_GC_XX_MASK constants are bit flags corresponding to Unicode + * general category values. + * For each category, the nth bit is set if the numeric value of the + * corresponding UCharCategory constant is n. + * + * There are also some U_GC_Y_MASK constants for groups of general categories + * like L for all letter categories. + * + * @see u_charType + * @see U_GET_GC_MASK + * @see UCharCategory + * @stable ICU 2.1 + */ +#define U_GC_CN_MASK U_MASK(U_GENERAL_OTHER_TYPES) + +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_LU_MASK U_MASK(U_UPPERCASE_LETTER) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_LL_MASK U_MASK(U_LOWERCASE_LETTER) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_LT_MASK U_MASK(U_TITLECASE_LETTER) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_LM_MASK U_MASK(U_MODIFIER_LETTER) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_LO_MASK U_MASK(U_OTHER_LETTER) + +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_MN_MASK U_MASK(U_NON_SPACING_MARK) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_ME_MASK U_MASK(U_ENCLOSING_MARK) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_MC_MASK U_MASK(U_COMBINING_SPACING_MARK) + +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_ND_MASK U_MASK(U_DECIMAL_DIGIT_NUMBER) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_NL_MASK U_MASK(U_LETTER_NUMBER) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_NO_MASK U_MASK(U_OTHER_NUMBER) + +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_ZS_MASK U_MASK(U_SPACE_SEPARATOR) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_ZL_MASK U_MASK(U_LINE_SEPARATOR) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_ZP_MASK U_MASK(U_PARAGRAPH_SEPARATOR) + +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_CC_MASK U_MASK(U_CONTROL_CHAR) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_CF_MASK U_MASK(U_FORMAT_CHAR) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_CO_MASK U_MASK(U_PRIVATE_USE_CHAR) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_CS_MASK U_MASK(U_SURROGATE) + +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_PD_MASK U_MASK(U_DASH_PUNCTUATION) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_PS_MASK U_MASK(U_START_PUNCTUATION) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_PE_MASK U_MASK(U_END_PUNCTUATION) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_PC_MASK U_MASK(U_CONNECTOR_PUNCTUATION) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_PO_MASK U_MASK(U_OTHER_PUNCTUATION) + +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_SM_MASK U_MASK(U_MATH_SYMBOL) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_SC_MASK U_MASK(U_CURRENCY_SYMBOL) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_SK_MASK U_MASK(U_MODIFIER_SYMBOL) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_SO_MASK U_MASK(U_OTHER_SYMBOL) + +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_PI_MASK U_MASK(U_INITIAL_PUNCTUATION) +/** Mask constant for a UCharCategory. @stable ICU 2.1 */ +#define U_GC_PF_MASK U_MASK(U_FINAL_PUNCTUATION) + + +/** Mask constant for multiple UCharCategory bits (L Letters). @stable ICU 2.1 */ +#define U_GC_L_MASK \ + (U_GC_LU_MASK|U_GC_LL_MASK|U_GC_LT_MASK|U_GC_LM_MASK|U_GC_LO_MASK) + +/** Mask constant for multiple UCharCategory bits (LC Cased Letters). @stable ICU 2.1 */ +#define U_GC_LC_MASK \ + (U_GC_LU_MASK|U_GC_LL_MASK|U_GC_LT_MASK) + +/** Mask constant for multiple UCharCategory bits (M Marks). @stable ICU 2.1 */ +#define U_GC_M_MASK (U_GC_MN_MASK|U_GC_ME_MASK|U_GC_MC_MASK) + +/** Mask constant for multiple UCharCategory bits (N Numbers). @stable ICU 2.1 */ +#define U_GC_N_MASK (U_GC_ND_MASK|U_GC_NL_MASK|U_GC_NO_MASK) + +/** Mask constant for multiple UCharCategory bits (Z Separators). @stable ICU 2.1 */ +#define U_GC_Z_MASK (U_GC_ZS_MASK|U_GC_ZL_MASK|U_GC_ZP_MASK) + +/** Mask constant for multiple UCharCategory bits (C Others). @stable ICU 2.1 */ +#define U_GC_C_MASK \ + (U_GC_CN_MASK|U_GC_CC_MASK|U_GC_CF_MASK|U_GC_CO_MASK|U_GC_CS_MASK) + +/** Mask constant for multiple UCharCategory bits (P Punctuation). @stable ICU 2.1 */ +#define U_GC_P_MASK \ + (U_GC_PD_MASK|U_GC_PS_MASK|U_GC_PE_MASK|U_GC_PC_MASK|U_GC_PO_MASK| \ + U_GC_PI_MASK|U_GC_PF_MASK) + +/** Mask constant for multiple UCharCategory bits (S Symbols). @stable ICU 2.1 */ +#define U_GC_S_MASK (U_GC_SM_MASK|U_GC_SC_MASK|U_GC_SK_MASK|U_GC_SO_MASK) + +/** + * This specifies the language directional property of a character set. + * @stable ICU 2.0 + */ +typedef enum UCharDirection { + /** See note !!. Comments of the form "EN" are read by genpname. */ + + /** L @stable ICU 2.0 */ + U_LEFT_TO_RIGHT = 0, + /** R @stable ICU 2.0 */ + U_RIGHT_TO_LEFT = 1, + /** EN @stable ICU 2.0 */ + U_EUROPEAN_NUMBER = 2, + /** ES @stable ICU 2.0 */ + U_EUROPEAN_NUMBER_SEPARATOR = 3, + /** ET @stable ICU 2.0 */ + U_EUROPEAN_NUMBER_TERMINATOR = 4, + /** AN @stable ICU 2.0 */ + U_ARABIC_NUMBER = 5, + /** CS @stable ICU 2.0 */ + U_COMMON_NUMBER_SEPARATOR = 6, + /** B @stable ICU 2.0 */ + U_BLOCK_SEPARATOR = 7, + /** S @stable ICU 2.0 */ + U_SEGMENT_SEPARATOR = 8, + /** WS @stable ICU 2.0 */ + U_WHITE_SPACE_NEUTRAL = 9, + /** ON @stable ICU 2.0 */ + U_OTHER_NEUTRAL = 10, + /** LRE @stable ICU 2.0 */ + U_LEFT_TO_RIGHT_EMBEDDING = 11, + /** LRO @stable ICU 2.0 */ + U_LEFT_TO_RIGHT_OVERRIDE = 12, + /** AL @stable ICU 2.0 */ + U_RIGHT_TO_LEFT_ARABIC = 13, + /** RLE @stable ICU 2.0 */ + U_RIGHT_TO_LEFT_EMBEDDING = 14, + /** RLO @stable ICU 2.0 */ + U_RIGHT_TO_LEFT_OVERRIDE = 15, + /** PDF @stable ICU 2.0 */ + U_POP_DIRECTIONAL_FORMAT = 16, + /** NSM @stable ICU 2.0 */ + U_DIR_NON_SPACING_MARK = 17, + /** BN @stable ICU 2.0 */ + U_BOUNDARY_NEUTRAL = 18, + /** @stable ICU 2.0 */ + U_CHAR_DIRECTION_COUNT +} UCharDirection; + +/** + * Constants for Unicode blocks, see the Unicode Data file Blocks.txt + * @stable ICU 2.0 + */ +enum UBlockCode { + + /** New No_Block value in Unicode 4. @stable ICU 2.6 */ + UBLOCK_NO_BLOCK = 0, /*[none]*/ /* Special range indicating No_Block */ + + /** @stable ICU 2.0 */ + UBLOCK_BASIC_LATIN = 1, /*[0000]*/ /*See note !!*/ + + /** @stable ICU 2.0 */ + UBLOCK_LATIN_1_SUPPLEMENT=2, /*[0080]*/ + + /** @stable ICU 2.0 */ + UBLOCK_LATIN_EXTENDED_A =3, /*[0100]*/ + + /** @stable ICU 2.0 */ + UBLOCK_LATIN_EXTENDED_B =4, /*[0180]*/ + + /** @stable ICU 2.0 */ + UBLOCK_IPA_EXTENSIONS =5, /*[0250]*/ + + /** @stable ICU 2.0 */ + UBLOCK_SPACING_MODIFIER_LETTERS =6, /*[02B0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_COMBINING_DIACRITICAL_MARKS =7, /*[0300]*/ + + /** + * Unicode 3.2 renames this block to "Greek and Coptic". + * @stable ICU 2.0 + */ + UBLOCK_GREEK =8, /*[0370]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CYRILLIC =9, /*[0400]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ARMENIAN =10, /*[0530]*/ + + /** @stable ICU 2.0 */ + UBLOCK_HEBREW =11, /*[0590]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ARABIC =12, /*[0600]*/ + + /** @stable ICU 2.0 */ + UBLOCK_SYRIAC =13, /*[0700]*/ + + /** @stable ICU 2.0 */ + UBLOCK_THAANA =14, /*[0780]*/ + + /** @stable ICU 2.0 */ + UBLOCK_DEVANAGARI =15, /*[0900]*/ + + /** @stable ICU 2.0 */ + UBLOCK_BENGALI =16, /*[0980]*/ + + /** @stable ICU 2.0 */ + UBLOCK_GURMUKHI =17, /*[0A00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_GUJARATI =18, /*[0A80]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ORIYA =19, /*[0B00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_TAMIL =20, /*[0B80]*/ + + /** @stable ICU 2.0 */ + UBLOCK_TELUGU =21, /*[0C00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_KANNADA =22, /*[0C80]*/ + + /** @stable ICU 2.0 */ + UBLOCK_MALAYALAM =23, /*[0D00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_SINHALA =24, /*[0D80]*/ + + /** @stable ICU 2.0 */ + UBLOCK_THAI =25, /*[0E00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_LAO =26, /*[0E80]*/ + + /** @stable ICU 2.0 */ + UBLOCK_TIBETAN =27, /*[0F00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_MYANMAR =28, /*[1000]*/ + + /** @stable ICU 2.0 */ + UBLOCK_GEORGIAN =29, /*[10A0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_HANGUL_JAMO =30, /*[1100]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ETHIOPIC =31, /*[1200]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CHEROKEE =32, /*[13A0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS =33, /*[1400]*/ + + /** @stable ICU 2.0 */ + UBLOCK_OGHAM =34, /*[1680]*/ + + /** @stable ICU 2.0 */ + UBLOCK_RUNIC =35, /*[16A0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_KHMER =36, /*[1780]*/ + + /** @stable ICU 2.0 */ + UBLOCK_MONGOLIAN =37, /*[1800]*/ + + /** @stable ICU 2.0 */ + UBLOCK_LATIN_EXTENDED_ADDITIONAL =38, /*[1E00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_GREEK_EXTENDED =39, /*[1F00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_GENERAL_PUNCTUATION =40, /*[2000]*/ + + /** @stable ICU 2.0 */ + UBLOCK_SUPERSCRIPTS_AND_SUBSCRIPTS =41, /*[2070]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CURRENCY_SYMBOLS =42, /*[20A0]*/ + + /** + * Unicode 3.2 renames this block to "Combining Diacritical Marks for Symbols". + * @stable ICU 2.0 + */ + UBLOCK_COMBINING_MARKS_FOR_SYMBOLS =43, /*[20D0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_LETTERLIKE_SYMBOLS =44, /*[2100]*/ + + /** @stable ICU 2.0 */ + UBLOCK_NUMBER_FORMS =45, /*[2150]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ARROWS =46, /*[2190]*/ + + /** @stable ICU 2.0 */ + UBLOCK_MATHEMATICAL_OPERATORS =47, /*[2200]*/ + + /** @stable ICU 2.0 */ + UBLOCK_MISCELLANEOUS_TECHNICAL =48, /*[2300]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CONTROL_PICTURES =49, /*[2400]*/ + + /** @stable ICU 2.0 */ + UBLOCK_OPTICAL_CHARACTER_RECOGNITION =50, /*[2440]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ENCLOSED_ALPHANUMERICS =51, /*[2460]*/ + + /** @stable ICU 2.0 */ + UBLOCK_BOX_DRAWING =52, /*[2500]*/ + + /** @stable ICU 2.0 */ + UBLOCK_BLOCK_ELEMENTS =53, /*[2580]*/ + + /** @stable ICU 2.0 */ + UBLOCK_GEOMETRIC_SHAPES =54, /*[25A0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_MISCELLANEOUS_SYMBOLS =55, /*[2600]*/ + + /** @stable ICU 2.0 */ + UBLOCK_DINGBATS =56, /*[2700]*/ + + /** @stable ICU 2.0 */ + UBLOCK_BRAILLE_PATTERNS =57, /*[2800]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CJK_RADICALS_SUPPLEMENT =58, /*[2E80]*/ + + /** @stable ICU 2.0 */ + UBLOCK_KANGXI_RADICALS =59, /*[2F00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS =60, /*[2FF0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION =61, /*[3000]*/ + + /** @stable ICU 2.0 */ + UBLOCK_HIRAGANA =62, /*[3040]*/ + + /** @stable ICU 2.0 */ + UBLOCK_KATAKANA =63, /*[30A0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_BOPOMOFO =64, /*[3100]*/ + + /** @stable ICU 2.0 */ + UBLOCK_HANGUL_COMPATIBILITY_JAMO =65, /*[3130]*/ + + /** @stable ICU 2.0 */ + UBLOCK_KANBUN =66, /*[3190]*/ + + /** @stable ICU 2.0 */ + UBLOCK_BOPOMOFO_EXTENDED =67, /*[31A0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS =68, /*[3200]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CJK_COMPATIBILITY =69, /*[3300]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A =70, /*[3400]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CJK_UNIFIED_IDEOGRAPHS =71, /*[4E00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_YI_SYLLABLES =72, /*[A000]*/ + + /** @stable ICU 2.0 */ + UBLOCK_YI_RADICALS =73, /*[A490]*/ + + /** @stable ICU 2.0 */ + UBLOCK_HANGUL_SYLLABLES =74, /*[AC00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_HIGH_SURROGATES =75, /*[D800]*/ + + /** @stable ICU 2.0 */ + UBLOCK_HIGH_PRIVATE_USE_SURROGATES =76, /*[DB80]*/ + + /** @stable ICU 2.0 */ + UBLOCK_LOW_SURROGATES =77, /*[DC00]*/ + + /** + * Same as UBLOCK_PRIVATE_USE_AREA. + * Until Unicode 3.1.1, the corresponding block name was "Private Use", + * and multiple code point ranges had this block. + * Unicode 3.2 renames the block for the BMP PUA to "Private Use Area" and + * adds separate blocks for the supplementary PUAs. + * + * @stable ICU 2.0 + */ + UBLOCK_PRIVATE_USE = 78, + /** + * Same as UBLOCK_PRIVATE_USE. + * Until Unicode 3.1.1, the corresponding block name was "Private Use", + * and multiple code point ranges had this block. + * Unicode 3.2 renames the block for the BMP PUA to "Private Use Area" and + * adds separate blocks for the supplementary PUAs. + * + * @stable ICU 2.0 + */ + UBLOCK_PRIVATE_USE_AREA =UBLOCK_PRIVATE_USE, /*[E000]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS =79, /*[F900]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ALPHABETIC_PRESENTATION_FORMS =80, /*[FB00]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ARABIC_PRESENTATION_FORMS_A =81, /*[FB50]*/ + + /** @stable ICU 2.0 */ + UBLOCK_COMBINING_HALF_MARKS =82, /*[FE20]*/ + + /** @stable ICU 2.0 */ + UBLOCK_CJK_COMPATIBILITY_FORMS =83, /*[FE30]*/ + + /** @stable ICU 2.0 */ + UBLOCK_SMALL_FORM_VARIANTS =84, /*[FE50]*/ + + /** @stable ICU 2.0 */ + UBLOCK_ARABIC_PRESENTATION_FORMS_B =85, /*[FE70]*/ + + /** @stable ICU 2.0 */ + UBLOCK_SPECIALS =86, /*[FFF0]*/ + + /** @stable ICU 2.0 */ + UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS =87, /*[FF00]*/ + + /* New blocks in Unicode 3.1 */ + + /** @stable ICU 2.0 */ + UBLOCK_OLD_ITALIC = 88 , /*[10300]*/ + /** @stable ICU 2.0 */ + UBLOCK_GOTHIC = 89 , /*[10330]*/ + /** @stable ICU 2.0 */ + UBLOCK_DESERET = 90 , /*[10400]*/ + /** @stable ICU 2.0 */ + UBLOCK_BYZANTINE_MUSICAL_SYMBOLS = 91 , /*[1D000]*/ + /** @stable ICU 2.0 */ + UBLOCK_MUSICAL_SYMBOLS = 92 , /*[1D100]*/ + /** @stable ICU 2.0 */ + UBLOCK_MATHEMATICAL_ALPHANUMERIC_SYMBOLS = 93 , /*[1D400]*/ + /** @stable ICU 2.0 */ + UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B = 94 , /*[20000]*/ + /** @stable ICU 2.0 */ + UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT = 95 , /*[2F800]*/ + /** @stable ICU 2.0 */ + UBLOCK_TAGS = 96, /*[E0000]*/ + + /* New blocks in Unicode 3.2 */ + + /** + * Unicode 4.0.1 renames the "Cyrillic Supplementary" block to "Cyrillic Supplement". + * @stable ICU 2.2 + */ + UBLOCK_CYRILLIC_SUPPLEMENTARY = 97, + /** @stable ICU 3.0 */ + UBLOCK_CYRILLIC_SUPPLEMENT = UBLOCK_CYRILLIC_SUPPLEMENTARY, /*[0500]*/ + /** @stable ICU 2.2 */ + UBLOCK_TAGALOG = 98, /*[1700]*/ + /** @stable ICU 2.2 */ + UBLOCK_HANUNOO = 99, /*[1720]*/ + /** @stable ICU 2.2 */ + UBLOCK_BUHID = 100, /*[1740]*/ + /** @stable ICU 2.2 */ + UBLOCK_TAGBANWA = 101, /*[1760]*/ + /** @stable ICU 2.2 */ + UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A = 102, /*[27C0]*/ + /** @stable ICU 2.2 */ + UBLOCK_SUPPLEMENTAL_ARROWS_A = 103, /*[27F0]*/ + /** @stable ICU 2.2 */ + UBLOCK_SUPPLEMENTAL_ARROWS_B = 104, /*[2900]*/ + /** @stable ICU 2.2 */ + UBLOCK_MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B = 105, /*[2980]*/ + /** @stable ICU 2.2 */ + UBLOCK_SUPPLEMENTAL_MATHEMATICAL_OPERATORS = 106, /*[2A00]*/ + /** @stable ICU 2.2 */ + UBLOCK_KATAKANA_PHONETIC_EXTENSIONS = 107, /*[31F0]*/ + /** @stable ICU 2.2 */ + UBLOCK_VARIATION_SELECTORS = 108, /*[FE00]*/ + /** @stable ICU 2.2 */ + UBLOCK_SUPPLEMENTARY_PRIVATE_USE_AREA_A = 109, /*[F0000]*/ + /** @stable ICU 2.2 */ + UBLOCK_SUPPLEMENTARY_PRIVATE_USE_AREA_B = 110, /*[100000]*/ + + /* New blocks in Unicode 4 */ + + /** @stable ICU 2.6 */ + UBLOCK_LIMBU = 111, /*[1900]*/ + /** @stable ICU 2.6 */ + UBLOCK_TAI_LE = 112, /*[1950]*/ + /** @stable ICU 2.6 */ + UBLOCK_KHMER_SYMBOLS = 113, /*[19E0]*/ + /** @stable ICU 2.6 */ + UBLOCK_PHONETIC_EXTENSIONS = 114, /*[1D00]*/ + /** @stable ICU 2.6 */ + UBLOCK_MISCELLANEOUS_SYMBOLS_AND_ARROWS = 115, /*[2B00]*/ + /** @stable ICU 2.6 */ + UBLOCK_YIJING_HEXAGRAM_SYMBOLS = 116, /*[4DC0]*/ + /** @stable ICU 2.6 */ + UBLOCK_LINEAR_B_SYLLABARY = 117, /*[10000]*/ + /** @stable ICU 2.6 */ + UBLOCK_LINEAR_B_IDEOGRAMS = 118, /*[10080]*/ + /** @stable ICU 2.6 */ + UBLOCK_AEGEAN_NUMBERS = 119, /*[10100]*/ + /** @stable ICU 2.6 */ + UBLOCK_UGARITIC = 120, /*[10380]*/ + /** @stable ICU 2.6 */ + UBLOCK_SHAVIAN = 121, /*[10450]*/ + /** @stable ICU 2.6 */ + UBLOCK_OSMANYA = 122, /*[10480]*/ + /** @stable ICU 2.6 */ + UBLOCK_CYPRIOT_SYLLABARY = 123, /*[10800]*/ + /** @stable ICU 2.6 */ + UBLOCK_TAI_XUAN_JING_SYMBOLS = 124, /*[1D300]*/ + /** @stable ICU 2.6 */ + UBLOCK_VARIATION_SELECTORS_SUPPLEMENT = 125, /*[E0100]*/ + + /* New blocks in Unicode 4.1 */ + + /** @stable ICU 3.4 */ + UBLOCK_ANCIENT_GREEK_MUSICAL_NOTATION = 126, /*[1D200]*/ + /** @stable ICU 3.4 */ + UBLOCK_ANCIENT_GREEK_NUMBERS = 127, /*[10140]*/ + /** @stable ICU 3.4 */ + UBLOCK_ARABIC_SUPPLEMENT = 128, /*[0750]*/ + /** @stable ICU 3.4 */ + UBLOCK_BUGINESE = 129, /*[1A00]*/ + /** @stable ICU 3.4 */ + UBLOCK_CJK_STROKES = 130, /*[31C0]*/ + /** @stable ICU 3.4 */ + UBLOCK_COMBINING_DIACRITICAL_MARKS_SUPPLEMENT = 131, /*[1DC0]*/ + /** @stable ICU 3.4 */ + UBLOCK_COPTIC = 132, /*[2C80]*/ + /** @stable ICU 3.4 */ + UBLOCK_ETHIOPIC_EXTENDED = 133, /*[2D80]*/ + /** @stable ICU 3.4 */ + UBLOCK_ETHIOPIC_SUPPLEMENT = 134, /*[1380]*/ + /** @stable ICU 3.4 */ + UBLOCK_GEORGIAN_SUPPLEMENT = 135, /*[2D00]*/ + /** @stable ICU 3.4 */ + UBLOCK_GLAGOLITIC = 136, /*[2C00]*/ + /** @stable ICU 3.4 */ + UBLOCK_KHAROSHTHI = 137, /*[10A00]*/ + /** @stable ICU 3.4 */ + UBLOCK_MODIFIER_TONE_LETTERS = 138, /*[A700]*/ + /** @stable ICU 3.4 */ + UBLOCK_NEW_TAI_LUE = 139, /*[1980]*/ + /** @stable ICU 3.4 */ + UBLOCK_OLD_PERSIAN = 140, /*[103A0]*/ + /** @stable ICU 3.4 */ + UBLOCK_PHONETIC_EXTENSIONS_SUPPLEMENT = 141, /*[1D80]*/ + /** @stable ICU 3.4 */ + UBLOCK_SUPPLEMENTAL_PUNCTUATION = 142, /*[2E00]*/ + /** @stable ICU 3.4 */ + UBLOCK_SYLOTI_NAGRI = 143, /*[A800]*/ + /** @stable ICU 3.4 */ + UBLOCK_TIFINAGH = 144, /*[2D30]*/ + /** @stable ICU 3.4 */ + UBLOCK_VERTICAL_FORMS = 145, /*[FE10]*/ + + /* New blocks in Unicode 5.0 */ + + /** @stable ICU 3.6 */ + UBLOCK_NKO = 146, /*[07C0]*/ + /** @stable ICU 3.6 */ + UBLOCK_BALINESE = 147, /*[1B00]*/ + /** @stable ICU 3.6 */ + UBLOCK_LATIN_EXTENDED_C = 148, /*[2C60]*/ + /** @stable ICU 3.6 */ + UBLOCK_LATIN_EXTENDED_D = 149, /*[A720]*/ + /** @stable ICU 3.6 */ + UBLOCK_PHAGS_PA = 150, /*[A840]*/ + /** @stable ICU 3.6 */ + UBLOCK_PHOENICIAN = 151, /*[10900]*/ + /** @stable ICU 3.6 */ + UBLOCK_CUNEIFORM = 152, /*[12000]*/ + /** @stable ICU 3.6 */ + UBLOCK_CUNEIFORM_NUMBERS_AND_PUNCTUATION = 153, /*[12400]*/ + /** @stable ICU 3.6 */ + UBLOCK_COUNTING_ROD_NUMERALS = 154, /*[1D360]*/ + + /* New blocks in Unicode 5.1 */ + + /** @draft ICU 4.0 */ + UBLOCK_SUNDANESE = 155, /*[1B80]*/ + /** @draft ICU 4.0 */ + UBLOCK_LEPCHA = 156, /*[1C00]*/ + /** @draft ICU 4.0 */ + UBLOCK_OL_CHIKI = 157, /*[1C50]*/ + /** @draft ICU 4.0 */ + UBLOCK_CYRILLIC_EXTENDED_A = 158, /*[2DE0]*/ + /** @draft ICU 4.0 */ + UBLOCK_VAI = 159, /*[A500]*/ + /** @draft ICU 4.0 */ + UBLOCK_CYRILLIC_EXTENDED_B = 160, /*[A640]*/ + /** @draft ICU 4.0 */ + UBLOCK_SAURASHTRA = 161, /*[A880]*/ + /** @draft ICU 4.0 */ + UBLOCK_KAYAH_LI = 162, /*[A900]*/ + /** @draft ICU 4.0 */ + UBLOCK_REJANG = 163, /*[A930]*/ + /** @draft ICU 4.0 */ + UBLOCK_CHAM = 164, /*[AA00]*/ + /** @draft ICU 4.0 */ + UBLOCK_ANCIENT_SYMBOLS = 165, /*[10190]*/ + /** @draft ICU 4.0 */ + UBLOCK_PHAISTOS_DISC = 166, /*[101D0]*/ + /** @draft ICU 4.0 */ + UBLOCK_LYCIAN = 167, /*[10280]*/ + /** @draft ICU 4.0 */ + UBLOCK_CARIAN = 168, /*[102A0]*/ + /** @draft ICU 4.0 */ + UBLOCK_LYDIAN = 169, /*[10920]*/ + /** @draft ICU 4.0 */ + UBLOCK_MAHJONG_TILES = 170, /*[1F000]*/ + /** @draft ICU 4.0 */ + UBLOCK_DOMINO_TILES = 171, /*[1F030]*/ + + /** @stable ICU 2.0 */ + UBLOCK_COUNT = 172, + + /** @stable ICU 2.0 */ + UBLOCK_INVALID_CODE=-1 +}; + +/** @stable ICU 2.0 */ +typedef enum UBlockCode UBlockCode; + +/** + * East Asian Width constants. + * + * @see UCHAR_EAST_ASIAN_WIDTH + * @see u_getIntPropertyValue + * @stable ICU 2.2 + */ +typedef enum UEastAsianWidth { + U_EA_NEUTRAL, /*[N]*/ /*See note !!*/ + U_EA_AMBIGUOUS, /*[A]*/ + U_EA_HALFWIDTH, /*[H]*/ + U_EA_FULLWIDTH, /*[F]*/ + U_EA_NARROW, /*[Na]*/ + U_EA_WIDE, /*[W]*/ + U_EA_COUNT +} UEastAsianWidth; +/* + * Implementation note: + * Keep UEastAsianWidth constant values in sync with names list in genprops/props2.c. + */ + +/** + * Selector constants for u_charName(). + * u_charName() returns the "modern" name of a + * Unicode character; or the name that was defined in + * Unicode version 1.0, before the Unicode standard merged + * with ISO-10646; or an "extended" name that gives each + * Unicode code point a unique name. + * + * @see u_charName + * @stable ICU 2.0 + */ +typedef enum UCharNameChoice { + U_UNICODE_CHAR_NAME, + U_UNICODE_10_CHAR_NAME, + U_EXTENDED_CHAR_NAME, + U_CHAR_NAME_CHOICE_COUNT +} UCharNameChoice; + +/** + * Selector constants for u_getPropertyName() and + * u_getPropertyValueName(). These selectors are used to choose which + * name is returned for a given property or value. All properties and + * values have a long name. Most have a short name, but some do not. + * Unicode allows for additional names, beyond the long and short + * name, which would be indicated by U_LONG_PROPERTY_NAME + i, where + * i=1, 2,... + * + * @see u_getPropertyName() + * @see u_getPropertyValueName() + * @stable ICU 2.4 + */ +typedef enum UPropertyNameChoice { + U_SHORT_PROPERTY_NAME, + U_LONG_PROPERTY_NAME, + U_PROPERTY_NAME_CHOICE_COUNT +} UPropertyNameChoice; + +/** + * Decomposition Type constants. + * + * @see UCHAR_DECOMPOSITION_TYPE + * @stable ICU 2.2 + */ +typedef enum UDecompositionType { + U_DT_NONE, /*[none]*/ /*See note !!*/ + U_DT_CANONICAL, /*[can]*/ + U_DT_COMPAT, /*[com]*/ + U_DT_CIRCLE, /*[enc]*/ + U_DT_FINAL, /*[fin]*/ + U_DT_FONT, /*[font]*/ + U_DT_FRACTION, /*[fra]*/ + U_DT_INITIAL, /*[init]*/ + U_DT_ISOLATED, /*[iso]*/ + U_DT_MEDIAL, /*[med]*/ + U_DT_NARROW, /*[nar]*/ + U_DT_NOBREAK, /*[nb]*/ + U_DT_SMALL, /*[sml]*/ + U_DT_SQUARE, /*[sqr]*/ + U_DT_SUB, /*[sub]*/ + U_DT_SUPER, /*[sup]*/ + U_DT_VERTICAL, /*[vert]*/ + U_DT_WIDE, /*[wide]*/ + U_DT_COUNT /* 18 */ +} UDecompositionType; + +/** + * Joining Type constants. + * + * @see UCHAR_JOINING_TYPE + * @stable ICU 2.2 + */ +typedef enum UJoiningType { + U_JT_NON_JOINING, /*[U]*/ /*See note !!*/ + U_JT_JOIN_CAUSING, /*[C]*/ + U_JT_DUAL_JOINING, /*[D]*/ + U_JT_LEFT_JOINING, /*[L]*/ + U_JT_RIGHT_JOINING, /*[R]*/ + U_JT_TRANSPARENT, /*[T]*/ + U_JT_COUNT /* 6 */ +} UJoiningType; + +/** + * Joining Group constants. + * + * @see UCHAR_JOINING_GROUP + * @stable ICU 2.2 + */ +typedef enum UJoiningGroup { + U_JG_NO_JOINING_GROUP, + U_JG_AIN, + U_JG_ALAPH, + U_JG_ALEF, + U_JG_BEH, + U_JG_BETH, + U_JG_DAL, + U_JG_DALATH_RISH, + U_JG_E, + U_JG_FEH, + U_JG_FINAL_SEMKATH, + U_JG_GAF, + U_JG_GAMAL, + U_JG_HAH, + U_JG_HAMZA_ON_HEH_GOAL, + U_JG_HE, + U_JG_HEH, + U_JG_HEH_GOAL, + U_JG_HETH, + U_JG_KAF, + U_JG_KAPH, + U_JG_KNOTTED_HEH, + U_JG_LAM, + U_JG_LAMADH, + U_JG_MEEM, + U_JG_MIM, + U_JG_NOON, + U_JG_NUN, + U_JG_PE, + U_JG_QAF, + U_JG_QAPH, + U_JG_REH, + U_JG_REVERSED_PE, + U_JG_SAD, + U_JG_SADHE, + U_JG_SEEN, + U_JG_SEMKATH, + U_JG_SHIN, + U_JG_SWASH_KAF, + U_JG_SYRIAC_WAW, + U_JG_TAH, + U_JG_TAW, + U_JG_TEH_MARBUTA, + U_JG_TETH, + U_JG_WAW, + U_JG_YEH, + U_JG_YEH_BARREE, + U_JG_YEH_WITH_TAIL, + U_JG_YUDH, + U_JG_YUDH_HE, + U_JG_ZAIN, + U_JG_FE, /**< @stable ICU 2.6 */ + U_JG_KHAPH, /**< @stable ICU 2.6 */ + U_JG_ZHAIN, /**< @stable ICU 2.6 */ + U_JG_BURUSHASKI_YEH_BARREE, /**< @draft ICU 4.0 */ + U_JG_COUNT +} UJoiningGroup; + +/** + * Grapheme Cluster Break constants. + * + * @see UCHAR_GRAPHEME_CLUSTER_BREAK + * @stable ICU 3.4 + */ +typedef enum UGraphemeClusterBreak { + U_GCB_OTHER = 0, /*[XX]*/ /*See note !!*/ + U_GCB_CONTROL = 1, /*[CN]*/ + U_GCB_CR = 2, /*[CR]*/ + U_GCB_EXTEND = 3, /*[EX]*/ + U_GCB_L = 4, /*[L]*/ + U_GCB_LF = 5, /*[LF]*/ + U_GCB_LV = 6, /*[LV]*/ + U_GCB_LVT = 7, /*[LVT]*/ + U_GCB_T = 8, /*[T]*/ + U_GCB_V = 9, /*[V]*/ + U_GCB_SPACING_MARK = 10, /*[SM]*/ /* from here on: new in Unicode 5.1/ICU 4.0 */ + U_GCB_PREPEND = 11, /*[PP]*/ + U_GCB_COUNT = 12 +} UGraphemeClusterBreak; + +/** + * Word Break constants. + * (UWordBreak is a pre-existing enum type in ubrk.h for word break status tags.) + * + * @see UCHAR_WORD_BREAK + * @stable ICU 3.4 + */ +typedef enum UWordBreakValues { + U_WB_OTHER = 0, /*[XX]*/ /*See note !!*/ + U_WB_ALETTER = 1, /*[LE]*/ + U_WB_FORMAT = 2, /*[FO]*/ + U_WB_KATAKANA = 3, /*[KA]*/ + U_WB_MIDLETTER = 4, /*[ML]*/ + U_WB_MIDNUM = 5, /*[MN]*/ + U_WB_NUMERIC = 6, /*[NU]*/ + U_WB_EXTENDNUMLET = 7, /*[EX]*/ + U_WB_CR = 8, /*[CR]*/ /* from here on: new in Unicode 5.1/ICU 4.0 */ + U_WB_EXTEND = 9, /*[Extend]*/ + U_WB_LF = 10, /*[LF]*/ + U_WB_MIDNUMLET =11, /*[MB]*/ + U_WB_NEWLINE =12, /*[NL]*/ + U_WB_COUNT = 13 +} UWordBreakValues; + +/** + * Sentence Break constants. + * + * @see UCHAR_SENTENCE_BREAK + * @stable ICU 3.4 + */ +typedef enum USentenceBreak { + U_SB_OTHER = 0, /*[XX]*/ /*See note !!*/ + U_SB_ATERM = 1, /*[AT]*/ + U_SB_CLOSE = 2, /*[CL]*/ + U_SB_FORMAT = 3, /*[FO]*/ + U_SB_LOWER = 4, /*[LO]*/ + U_SB_NUMERIC = 5, /*[NU]*/ + U_SB_OLETTER = 6, /*[LE]*/ + U_SB_SEP = 7, /*[SE]*/ + U_SB_SP = 8, /*[SP]*/ + U_SB_STERM = 9, /*[ST]*/ + U_SB_UPPER = 10, /*[UP]*/ + U_SB_CR = 11, /*[CR]*/ /* from here on: new in Unicode 5.1/ICU 4.0 */ + U_SB_EXTEND = 12, /*[EX]*/ + U_SB_LF = 13, /*[LF]*/ + U_SB_SCONTINUE = 14, /*[SC]*/ + U_SB_COUNT = 15 +} USentenceBreak; + +/** + * Line Break constants. + * + * @see UCHAR_LINE_BREAK + * @stable ICU 2.2 + */ +typedef enum ULineBreak { + U_LB_UNKNOWN = 0, /*[XX]*/ /*See note !!*/ + U_LB_AMBIGUOUS = 1, /*[AI]*/ + U_LB_ALPHABETIC = 2, /*[AL]*/ + U_LB_BREAK_BOTH = 3, /*[B2]*/ + U_LB_BREAK_AFTER = 4, /*[BA]*/ + U_LB_BREAK_BEFORE = 5, /*[BB]*/ + U_LB_MANDATORY_BREAK = 6, /*[BK]*/ + U_LB_CONTINGENT_BREAK = 7, /*[CB]*/ + U_LB_CLOSE_PUNCTUATION = 8, /*[CL]*/ + U_LB_COMBINING_MARK = 9, /*[CM]*/ + U_LB_CARRIAGE_RETURN = 10, /*[CR]*/ + U_LB_EXCLAMATION = 11, /*[EX]*/ + U_LB_GLUE = 12, /*[GL]*/ + U_LB_HYPHEN = 13, /*[HY]*/ + U_LB_IDEOGRAPHIC = 14, /*[ID]*/ + U_LB_INSEPERABLE = 15, + /** Renamed from the misspelled "inseperable" in Unicode 4.0.1/ICU 3.0 @stable ICU 3.0 */ + U_LB_INSEPARABLE=U_LB_INSEPERABLE,/*[IN]*/ + U_LB_INFIX_NUMERIC = 16, /*[IS]*/ + U_LB_LINE_FEED = 17, /*[LF]*/ + U_LB_NONSTARTER = 18, /*[NS]*/ + U_LB_NUMERIC = 19, /*[NU]*/ + U_LB_OPEN_PUNCTUATION = 20, /*[OP]*/ + U_LB_POSTFIX_NUMERIC = 21, /*[PO]*/ + U_LB_PREFIX_NUMERIC = 22, /*[PR]*/ + U_LB_QUOTATION = 23, /*[QU]*/ + U_LB_COMPLEX_CONTEXT = 24, /*[SA]*/ + U_LB_SURROGATE = 25, /*[SG]*/ + U_LB_SPACE = 26, /*[SP]*/ + U_LB_BREAK_SYMBOLS = 27, /*[SY]*/ + U_LB_ZWSPACE = 28, /*[ZW]*/ + U_LB_NEXT_LINE = 29, /*[NL]*/ /* from here on: new in Unicode 4/ICU 2.6 */ + U_LB_WORD_JOINER = 30, /*[WJ]*/ + U_LB_H2 = 31, /*[H2]*/ /* from here on: new in Unicode 4.1/ICU 3.4 */ + U_LB_H3 = 32, /*[H3]*/ + U_LB_JL = 33, /*[JL]*/ + U_LB_JT = 34, /*[JT]*/ + U_LB_JV = 35, /*[JV]*/ + U_LB_COUNT = 36 +} ULineBreak; + +/** + * Numeric Type constants. + * + * @see UCHAR_NUMERIC_TYPE + * @stable ICU 2.2 + */ +typedef enum UNumericType { + U_NT_NONE, /*[None]*/ /*See note !!*/ + U_NT_DECIMAL, /*[de]*/ + U_NT_DIGIT, /*[di]*/ + U_NT_NUMERIC, /*[nu]*/ + U_NT_COUNT +} UNumericType; + +/** + * Hangul Syllable Type constants. + * + * @see UCHAR_HANGUL_SYLLABLE_TYPE + * @stable ICU 2.6 + */ +typedef enum UHangulSyllableType { + U_HST_NOT_APPLICABLE, /*[NA]*/ /*See note !!*/ + U_HST_LEADING_JAMO, /*[L]*/ + U_HST_VOWEL_JAMO, /*[V]*/ + U_HST_TRAILING_JAMO, /*[T]*/ + U_HST_LV_SYLLABLE, /*[LV]*/ + U_HST_LVT_SYLLABLE, /*[LVT]*/ + U_HST_COUNT +} UHangulSyllableType; + +/** + * Check a binary Unicode property for a code point. + * + * Unicode, especially in version 3.2, defines many more properties than the + * original set in UnicodeData.txt. + * + * The properties APIs are intended to reflect Unicode properties as defined + * in the Unicode Character Database (UCD) and Unicode Technical Reports (UTR). + * For details about the properties see http://www.unicode.org/ucd/ . + * For names of Unicode properties see the UCD file PropertyAliases.txt. + * + * Important: If ICU is built with UCD files from Unicode versions below 3.2, + * then properties marked with "new in Unicode 3.2" are not or not fully available. + * + * @param c Code point to test. + * @param which UProperty selector constant, identifies which binary property to check. + * Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT. + * @return TRUE or FALSE according to the binary Unicode property value for c. + * Also FALSE if 'which' is out of bounds or if the Unicode version + * does not have data for the property at all, or not for this code point. + * + * @see UProperty + * @see u_getIntPropertyValue + * @see u_getUnicodeVersion + * @stable ICU 2.1 + */ +U_STABLE UBool U_EXPORT2 +u_hasBinaryProperty(UChar32 c, UProperty which); + +/** + * Check if a code point has the Alphabetic Unicode property. + * Same as u_hasBinaryProperty(c, UCHAR_ALPHABETIC). + * This is different from u_isalpha! + * @param c Code point to test + * @return true if the code point has the Alphabetic Unicode property, false otherwise + * + * @see UCHAR_ALPHABETIC + * @see u_isalpha + * @see u_hasBinaryProperty + * @stable ICU 2.1 + */ +U_STABLE UBool U_EXPORT2 +u_isUAlphabetic(UChar32 c); + +/** + * Check if a code point has the Lowercase Unicode property. + * Same as u_hasBinaryProperty(c, UCHAR_LOWERCASE). + * This is different from u_islower! + * @param c Code point to test + * @return true if the code point has the Lowercase Unicode property, false otherwise + * + * @see UCHAR_LOWERCASE + * @see u_islower + * @see u_hasBinaryProperty + * @stable ICU 2.1 + */ +U_STABLE UBool U_EXPORT2 +u_isULowercase(UChar32 c); + +/** + * Check if a code point has the Uppercase Unicode property. + * Same as u_hasBinaryProperty(c, UCHAR_UPPERCASE). + * This is different from u_isupper! + * @param c Code point to test + * @return true if the code point has the Uppercase Unicode property, false otherwise + * + * @see UCHAR_UPPERCASE + * @see u_isupper + * @see u_hasBinaryProperty + * @stable ICU 2.1 + */ +U_STABLE UBool U_EXPORT2 +u_isUUppercase(UChar32 c); + +/** + * Check if a code point has the White_Space Unicode property. + * Same as u_hasBinaryProperty(c, UCHAR_WHITE_SPACE). + * This is different from both u_isspace and u_isWhitespace! + * + * Note: There are several ICU whitespace functions; please see the uchar.h + * file documentation for a detailed comparison. + * + * @param c Code point to test + * @return true if the code point has the White_Space Unicode property, false otherwise. + * + * @see UCHAR_WHITE_SPACE + * @see u_isWhitespace + * @see u_isspace + * @see u_isJavaSpaceChar + * @see u_hasBinaryProperty + * @stable ICU 2.1 + */ +U_STABLE UBool U_EXPORT2 +u_isUWhiteSpace(UChar32 c); + +/** + * Get the property value for an enumerated or integer Unicode property for a code point. + * Also returns binary and mask property values. + * + * Unicode, especially in version 3.2, defines many more properties than the + * original set in UnicodeData.txt. + * + * The properties APIs are intended to reflect Unicode properties as defined + * in the Unicode Character Database (UCD) and Unicode Technical Reports (UTR). + * For details about the properties see http://www.unicode.org/ . + * For names of Unicode properties see the UCD file PropertyAliases.txt. + * + * Sample usage: + * UEastAsianWidth ea=(UEastAsianWidth)u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH); + * UBool b=(UBool)u_getIntPropertyValue(c, UCHAR_IDEOGRAPHIC); + * + * @param c Code point to test. + * @param which UProperty selector constant, identifies which property to check. + * Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT + * or UCHAR_INT_START<=which<UCHAR_INT_LIMIT + * or UCHAR_MASK_START<=which<UCHAR_MASK_LIMIT. + * @return Numeric value that is directly the property value or, + * for enumerated properties, corresponds to the numeric value of the enumerated + * constant of the respective property value enumeration type + * (cast to enum type if necessary). + * Returns 0 or 1 (for FALSE/TRUE) for binary Unicode properties. + * Returns a bit-mask for mask properties. + * Returns 0 if 'which' is out of bounds or if the Unicode version + * does not have data for the property at all, or not for this code point. + * + * @see UProperty + * @see u_hasBinaryProperty + * @see u_getIntPropertyMinValue + * @see u_getIntPropertyMaxValue + * @see u_getUnicodeVersion + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +u_getIntPropertyValue(UChar32 c, UProperty which); + +/** + * Get the minimum value for an enumerated/integer/binary Unicode property. + * Can be used together with u_getIntPropertyMaxValue + * to allocate arrays of UnicodeSet or similar. + * + * @param which UProperty selector constant, identifies which binary property to check. + * Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT + * or UCHAR_INT_START<=which<UCHAR_INT_LIMIT. + * @return Minimum value returned by u_getIntPropertyValue for a Unicode property. + * 0 if the property selector is out of range. + * + * @see UProperty + * @see u_hasBinaryProperty + * @see u_getUnicodeVersion + * @see u_getIntPropertyMaxValue + * @see u_getIntPropertyValue + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +u_getIntPropertyMinValue(UProperty which); + +/** + * Get the maximum value for an enumerated/integer/binary Unicode property. + * Can be used together with u_getIntPropertyMinValue + * to allocate arrays of UnicodeSet or similar. + * + * Examples for min/max values (for Unicode 3.2): + * + * - UCHAR_BIDI_CLASS: 0/18 (U_LEFT_TO_RIGHT/U_BOUNDARY_NEUTRAL) + * - UCHAR_SCRIPT: 0/45 (USCRIPT_COMMON/USCRIPT_TAGBANWA) + * - UCHAR_IDEOGRAPHIC: 0/1 (FALSE/TRUE) + * + * For undefined UProperty constant values, min/max values will be 0/-1. + * + * @param which UProperty selector constant, identifies which binary property to check. + * Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT + * or UCHAR_INT_START<=which<UCHAR_INT_LIMIT. + * @return Maximum value returned by u_getIntPropertyValue for a Unicode property. + * <=0 if the property selector is out of range. + * + * @see UProperty + * @see u_hasBinaryProperty + * @see u_getUnicodeVersion + * @see u_getIntPropertyMaxValue + * @see u_getIntPropertyValue + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +u_getIntPropertyMaxValue(UProperty which); + +/** + * Get the numeric value for a Unicode code point as defined in the + * Unicode Character Database. + * + * A "double" return type is necessary because + * some numeric values are fractions, negative, or too large for int32_t. + * + * For characters without any numeric values in the Unicode Character Database, + * this function will return U_NO_NUMERIC_VALUE. + * + * Similar to java.lang.Character.getNumericValue(), but u_getNumericValue() + * also supports negative values, large values, and fractions, + * while Java's getNumericValue() returns values 10..35 for ASCII letters. + * + * @param c Code point to get the numeric value for. + * @return Numeric value of c, or U_NO_NUMERIC_VALUE if none is defined. + * + * @see U_NO_NUMERIC_VALUE + * @stable ICU 2.2 + */ +U_STABLE double U_EXPORT2 +u_getNumericValue(UChar32 c); + +/** + * Special value that is returned by u_getNumericValue when + * no numeric value is defined for a code point. + * + * @see u_getNumericValue + * @stable ICU 2.2 + */ +#define U_NO_NUMERIC_VALUE ((double)-123456789.) + +/** + * Determines whether the specified code point has the general category "Ll" + * (lowercase letter). + * + * Same as java.lang.Character.isLowerCase(). + * + * This misses some characters that are also lowercase but + * have a different general category value. + * In order to include those, use UCHAR_LOWERCASE. + * + * In addition to being equivalent to a Java function, this also serves + * as a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is an Ll lowercase letter + * + * @see UCHAR_LOWERCASE + * @see u_isupper + * @see u_istitle + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_islower(UChar32 c); + +/** + * Determines whether the specified code point has the general category "Lu" + * (uppercase letter). + * + * Same as java.lang.Character.isUpperCase(). + * + * This misses some characters that are also uppercase but + * have a different general category value. + * In order to include those, use UCHAR_UPPERCASE. + * + * In addition to being equivalent to a Java function, this also serves + * as a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is an Lu uppercase letter + * + * @see UCHAR_UPPERCASE + * @see u_islower + * @see u_istitle + * @see u_tolower + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isupper(UChar32 c); + +/** + * Determines whether the specified code point is a titlecase letter. + * True for general category "Lt" (titlecase letter). + * + * Same as java.lang.Character.isTitleCase(). + * + * @param c the code point to be tested + * @return TRUE if the code point is an Lt titlecase letter + * + * @see u_isupper + * @see u_islower + * @see u_totitle + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_istitle(UChar32 c); + +/** + * Determines whether the specified code point is a digit character according to Java. + * True for characters with general category "Nd" (decimal digit numbers). + * Beginning with Unicode 4, this is the same as + * testing for the Numeric_Type of Decimal. + * + * Same as java.lang.Character.isDigit(). + * + * In addition to being equivalent to a Java function, this also serves + * as a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is a digit character according to Character.isDigit() + * + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isdigit(UChar32 c); + +/** + * Determines whether the specified code point is a letter character. + * True for general categories "L" (letters). + * + * Same as java.lang.Character.isLetter(). + * + * In addition to being equivalent to a Java function, this also serves + * as a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is a letter character + * + * @see u_isdigit + * @see u_isalnum + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isalpha(UChar32 c); + +/** + * Determines whether the specified code point is an alphanumeric character + * (letter or digit) according to Java. + * True for characters with general categories + * "L" (letters) and "Nd" (decimal digit numbers). + * + * Same as java.lang.Character.isLetterOrDigit(). + * + * In addition to being equivalent to a Java function, this also serves + * as a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is an alphanumeric character according to Character.isLetterOrDigit() + * + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isalnum(UChar32 c); + +/** + * Determines whether the specified code point is a hexadecimal digit. + * This is equivalent to u_digit(c, 16)>=0. + * True for characters with general category "Nd" (decimal digit numbers) + * as well as Latin letters a-f and A-F in both ASCII and Fullwidth ASCII. + * (That is, for letters with code points + * 0041..0046, 0061..0066, FF21..FF26, FF41..FF46.) + * + * In order to narrow the definition of hexadecimal digits to only ASCII + * characters, use (c<=0x7f && u_isxdigit(c)). + * + * This is a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is a hexadecimal digit + * + * @stable ICU 2.6 + */ +U_STABLE UBool U_EXPORT2 +u_isxdigit(UChar32 c); + +/** + * Determines whether the specified code point is a punctuation character. + * True for characters with general categories "P" (punctuation). + * + * This is a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is a punctuation character + * + * @stable ICU 2.6 + */ +U_STABLE UBool U_EXPORT2 +u_ispunct(UChar32 c); + +/** + * Determines whether the specified code point is a "graphic" character + * (printable, excluding spaces). + * TRUE for all characters except those with general categories + * "Cc" (control codes), "Cf" (format controls), "Cs" (surrogates), + * "Cn" (unassigned), and "Z" (separators). + * + * This is a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is a "graphic" character + * + * @stable ICU 2.6 + */ +U_STABLE UBool U_EXPORT2 +u_isgraph(UChar32 c); + +/** + * Determines whether the specified code point is a "blank" or "horizontal space", + * a character that visibly separates words on a line. + * The following are equivalent definitions: + * + * TRUE for Unicode White_Space characters except for "vertical space controls" + * where "vertical space controls" are the following characters: + * U+000A (LF) U+000B (VT) U+000C (FF) U+000D (CR) U+0085 (NEL) U+2028 (LS) U+2029 (PS) + * + * same as + * + * TRUE for U+0009 (TAB) and characters with general category "Zs" (space separators) + * except Zero Width Space (ZWSP, U+200B). + * + * Note: There are several ICU whitespace functions; please see the uchar.h + * file documentation for a detailed comparison. + * + * This is a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is a "blank" + * + * @stable ICU 2.6 + */ +U_STABLE UBool U_EXPORT2 +u_isblank(UChar32 c); + +/** + * Determines whether the specified code point is "defined", + * which usually means that it is assigned a character. + * True for general categories other than "Cn" (other, not assigned), + * i.e., true for all code points mentioned in UnicodeData.txt. + * + * Note that non-character code points (e.g., U+FDD0) are not "defined" + * (they are Cn), but surrogate code points are "defined" (Cs). + * + * Same as java.lang.Character.isDefined(). + * + * @param c the code point to be tested + * @return TRUE if the code point is assigned a character + * + * @see u_isdigit + * @see u_isalpha + * @see u_isalnum + * @see u_isupper + * @see u_islower + * @see u_istitle + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isdefined(UChar32 c); + +/** + * Determines if the specified character is a space character or not. + * + * Note: There are several ICU whitespace functions; please see the uchar.h + * file documentation for a detailed comparison. + * + * This is a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the character to be tested + * @return true if the character is a space character; false otherwise. + * + * @see u_isJavaSpaceChar + * @see u_isWhitespace + * @see u_isUWhiteSpace + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isspace(UChar32 c); + +/** + * Determine if the specified code point is a space character according to Java. + * True for characters with general categories "Z" (separators), + * which does not include control codes (e.g., TAB or Line Feed). + * + * Same as java.lang.Character.isSpaceChar(). + * + * Note: There are several ICU whitespace functions; please see the uchar.h + * file documentation for a detailed comparison. + * + * @param c the code point to be tested + * @return TRUE if the code point is a space character according to Character.isSpaceChar() + * + * @see u_isspace + * @see u_isWhitespace + * @see u_isUWhiteSpace + * @stable ICU 2.6 + */ +U_STABLE UBool U_EXPORT2 +u_isJavaSpaceChar(UChar32 c); + +/** + * Determines if the specified code point is a whitespace character according to Java/ICU. + * A character is considered to be a Java whitespace character if and only + * if it satisfies one of the following criteria: + * + * - It is a Unicode separator (categories "Z"), but is not + * a no-break space (U+00A0 NBSP or U+2007 Figure Space or U+202F Narrow NBSP). + * - It is U+0009 HORIZONTAL TABULATION. + * - It is U+000A LINE FEED. + * - It is U+000B VERTICAL TABULATION. + * - It is U+000C FORM FEED. + * - It is U+000D CARRIAGE RETURN. + * - It is U+001C FILE SEPARATOR. + * - It is U+001D GROUP SEPARATOR. + * - It is U+001E RECORD SEPARATOR. + * - It is U+001F UNIT SEPARATOR. + * - It is U+0085 NEXT LINE. + * + * Same as java.lang.Character.isWhitespace() except that Java omits U+0085. + * + * Note: There are several ICU whitespace functions; please see the uchar.h + * file documentation for a detailed comparison. + * + * @param c the code point to be tested + * @return TRUE if the code point is a whitespace character according to Java/ICU + * + * @see u_isspace + * @see u_isJavaSpaceChar + * @see u_isUWhiteSpace + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isWhitespace(UChar32 c); + +/** + * Determines whether the specified code point is a control character + * (as defined by this function). + * A control character is one of the following: + * - ISO 8-bit control character (U+0000..U+001f and U+007f..U+009f) + * - U_CONTROL_CHAR (Cc) + * - U_FORMAT_CHAR (Cf) + * - U_LINE_SEPARATOR (Zl) + * - U_PARAGRAPH_SEPARATOR (Zp) + * + * This is a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is a control character + * + * @see UCHAR_DEFAULT_IGNORABLE_CODE_POINT + * @see u_isprint + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_iscntrl(UChar32 c); + +/** + * Determines whether the specified code point is an ISO control code. + * True for U+0000..U+001f and U+007f..U+009f (general category "Cc"). + * + * Same as java.lang.Character.isISOControl(). + * + * @param c the code point to be tested + * @return TRUE if the code point is an ISO control code + * + * @see u_iscntrl + * @stable ICU 2.6 + */ +U_STABLE UBool U_EXPORT2 +u_isISOControl(UChar32 c); + +/** + * Determines whether the specified code point is a printable character. + * True for general categories <em>other</em> than "C" (controls). + * + * This is a C/POSIX migration function. + * See the comments about C/POSIX character classification functions in the + * documentation at the top of this header file. + * + * @param c the code point to be tested + * @return TRUE if the code point is a printable character + * + * @see UCHAR_DEFAULT_IGNORABLE_CODE_POINT + * @see u_iscntrl + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isprint(UChar32 c); + +/** + * Determines whether the specified code point is a base character. + * True for general categories "L" (letters), "N" (numbers), + * "Mc" (spacing combining marks), and "Me" (enclosing marks). + * + * Note that this is different from the Unicode definition in + * chapter 3.5, conformance clause D13, + * which defines base characters to be all characters (not Cn) + * that do not graphically combine with preceding characters (M) + * and that are neither control (Cc) or format (Cf) characters. + * + * @param c the code point to be tested + * @return TRUE if the code point is a base character according to this function + * + * @see u_isalpha + * @see u_isdigit + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isbase(UChar32 c); + +/** + * Returns the bidirectional category value for the code point, + * which is used in the Unicode bidirectional algorithm + * (UAX #9 http://www.unicode.org/reports/tr9/). + * Note that some <em>unassigned</em> code points have bidi values + * of R or AL because they are in blocks that are reserved + * for Right-To-Left scripts. + * + * Same as java.lang.Character.getDirectionality() + * + * @param c the code point to be tested + * @return the bidirectional category (UCharDirection) value + * + * @see UCharDirection + * @stable ICU 2.0 + */ +U_STABLE UCharDirection U_EXPORT2 +u_charDirection(UChar32 c); + +/** + * Determines whether the code point has the Bidi_Mirrored property. + * This property is set for characters that are commonly used in + * Right-To-Left contexts and need to be displayed with a "mirrored" + * glyph. + * + * Same as java.lang.Character.isMirrored(). + * Same as UCHAR_BIDI_MIRRORED + * + * @param c the code point to be tested + * @return TRUE if the character has the Bidi_Mirrored property + * + * @see UCHAR_BIDI_MIRRORED + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isMirrored(UChar32 c); + +/** + * Maps the specified character to a "mirror-image" character. + * For characters with the Bidi_Mirrored property, implementations + * sometimes need a "poor man's" mapping to another Unicode + * character (code point) such that the default glyph may serve + * as the mirror-image of the default glyph of the specified + * character. This is useful for text conversion to and from + * codepages with visual order, and for displays without glyph + * selecetion capabilities. + * + * @param c the code point to be mapped + * @return another Unicode code point that may serve as a mirror-image + * substitute, or c itself if there is no such mapping or c + * does not have the Bidi_Mirrored property + * + * @see UCHAR_BIDI_MIRRORED + * @see u_isMirrored + * @stable ICU 2.0 + */ +U_STABLE UChar32 U_EXPORT2 +u_charMirror(UChar32 c); + +/** + * Returns the general category value for the code point. + * + * Same as java.lang.Character.getType(). + * + * @param c the code point to be tested + * @return the general category (UCharCategory) value + * + * @see UCharCategory + * @stable ICU 2.0 + */ +U_STABLE int8_t U_EXPORT2 +u_charType(UChar32 c); + +/** + * Get a single-bit bit set for the general category of a character. + * This bit set can be compared bitwise with U_GC_SM_MASK, U_GC_L_MASK, etc. + * Same as U_MASK(u_charType(c)). + * + * @param c the code point to be tested + * @return a single-bit mask corresponding to the general category (UCharCategory) value + * + * @see u_charType + * @see UCharCategory + * @see U_GC_CN_MASK + * @stable ICU 2.1 + */ +#define U_GET_GC_MASK(c) U_MASK(u_charType(c)) + +/** + * Callback from u_enumCharTypes(), is called for each contiguous range + * of code points c (where start<=c<limit) + * with the same Unicode general category ("character type"). + * + * The callback function can stop the enumeration by returning FALSE. + * + * @param context an opaque pointer, as passed into utrie_enum() + * @param start the first code point in a contiguous range with value + * @param limit one past the last code point in a contiguous range with value + * @param type the general category for all code points in [start..limit[ + * @return FALSE to stop the enumeration + * + * @stable ICU 2.1 + * @see UCharCategory + * @see u_enumCharTypes + */ +typedef UBool U_CALLCONV +UCharEnumTypeRange(const void *context, UChar32 start, UChar32 limit, UCharCategory type); + +/** + * Enumerate efficiently all code points with their Unicode general categories. + * + * This is useful for building data structures (e.g., UnicodeSet's), + * for enumerating all assigned code points (type!=U_UNASSIGNED), etc. + * + * For each contiguous range of code points with a given general category ("character type"), + * the UCharEnumTypeRange function is called. + * Adjacent ranges have different types. + * The Unicode Standard guarantees that the numeric value of the type is 0..31. + * + * @param enumRange a pointer to a function that is called for each contiguous range + * of code points with the same general category + * @param context an opaque pointer that is passed on to the callback function + * + * @stable ICU 2.1 + * @see UCharCategory + * @see UCharEnumTypeRange + */ +U_STABLE void U_EXPORT2 +u_enumCharTypes(UCharEnumTypeRange *enumRange, const void *context); + +#if !UCONFIG_NO_NORMALIZATION + +/** + * Returns the combining class of the code point as specified in UnicodeData.txt. + * + * @param c the code point of the character + * @return the combining class of the character + * @stable ICU 2.0 + */ +U_STABLE uint8_t U_EXPORT2 +u_getCombiningClass(UChar32 c); + +#endif + +/** + * Returns the decimal digit value of a decimal digit character. + * Such characters have the general category "Nd" (decimal digit numbers) + * and a Numeric_Type of Decimal. + * + * Unlike ICU releases before 2.6, no digit values are returned for any + * Han characters because Han number characters are often used with a special + * Chinese-style number format (with characters for powers of 10 in between) + * instead of in decimal-positional notation. + * Unicode 4 explicitly assigns Han number characters the Numeric_Type + * Numeric instead of Decimal. + * See Jitterbug 1483 for more details. + * + * Use u_getIntPropertyValue(c, UCHAR_NUMERIC_TYPE) and u_getNumericValue() + * for complete numeric Unicode properties. + * + * @param c the code point for which to get the decimal digit value + * @return the decimal digit value of c, + * or -1 if c is not a decimal digit character + * + * @see u_getNumericValue + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_charDigitValue(UChar32 c); + +/** + * Returns the Unicode allocation block that contains the character. + * + * @param c the code point to be tested + * @return the block value (UBlockCode) for c + * + * @see UBlockCode + * @stable ICU 2.0 + */ +U_STABLE UBlockCode U_EXPORT2 +ublock_getCode(UChar32 c); + +/** + * Retrieve the name of a Unicode character. + * Depending on <code>nameChoice</code>, the character name written + * into the buffer is the "modern" name or the name that was defined + * in Unicode version 1.0. + * The name contains only "invariant" characters + * like A-Z, 0-9, space, and '-'. + * Unicode 1.0 names are only retrieved if they are different from the modern + * names and if the data file contains the data for them. gennames may or may + * not be called with a command line option to include 1.0 names in unames.dat. + * + * @param code The character (code point) for which to get the name. + * It must be <code>0<=code<=0x10ffff</code>. + * @param nameChoice Selector for which name to get. + * @param buffer Destination address for copying the name. + * The name will always be zero-terminated. + * If there is no name, then the buffer will be set to the empty string. + * @param bufferLength <code>==sizeof(buffer)</code> + * @param pErrorCode Pointer to a UErrorCode variable; + * check for <code>U_SUCCESS()</code> after <code>u_charName()</code> + * returns. + * @return The length of the name, or 0 if there is no name for this character. + * If the bufferLength is less than or equal to the length, then the buffer + * contains the truncated name and the returned length indicates the full + * length of the name. + * The length does not include the zero-termination. + * + * @see UCharNameChoice + * @see u_charFromName + * @see u_enumCharNames + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_charName(UChar32 code, UCharNameChoice nameChoice, + char *buffer, int32_t bufferLength, + UErrorCode *pErrorCode); + +/** + * Get the ISO 10646 comment for a character. + * The ISO 10646 comment is an informative field in the Unicode Character + * Database (UnicodeData.txt field 11) and is from the ISO 10646 names list. + * + * @param c The character (code point) for which to get the ISO comment. + * It must be <code>0<=c<=0x10ffff</code>. + * @param dest Destination address for copying the comment. + * The comment will be zero-terminated if possible. + * If there is no comment, then the buffer will be set to the empty string. + * @param destCapacity <code>==sizeof(dest)</code> + * @param pErrorCode Pointer to a UErrorCode variable; + * check for <code>U_SUCCESS()</code> after <code>u_getISOComment()</code> + * returns. + * @return The length of the comment, or 0 if there is no comment for this character. + * If the destCapacity is less than or equal to the length, then the buffer + * contains the truncated name and the returned length indicates the full + * length of the name. + * The length does not include the zero-termination. + * + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +u_getISOComment(UChar32 c, + char *dest, int32_t destCapacity, + UErrorCode *pErrorCode); + +/** + * Find a Unicode character by its name and return its code point value. + * The name is matched exactly and completely. + * If the name does not correspond to a code point, <i>pErrorCode</i> + * is set to <code>U_INVALID_CHAR_FOUND</code>. + * A Unicode 1.0 name is matched only if it differs from the modern name. + * Unicode names are all uppercase. Extended names are lowercase followed + * by an uppercase hexadecimal number, and within angle brackets. + * + * @param nameChoice Selector for which name to match. + * @param name The name to match. + * @param pErrorCode Pointer to a UErrorCode variable + * @return The Unicode value of the code point with the given name, + * or an undefined value if there is no such code point. + * + * @see UCharNameChoice + * @see u_charName + * @see u_enumCharNames + * @stable ICU 1.7 + */ +U_STABLE UChar32 U_EXPORT2 +u_charFromName(UCharNameChoice nameChoice, + const char *name, + UErrorCode *pErrorCode); + +/** + * Type of a callback function for u_enumCharNames() that gets called + * for each Unicode character with the code point value and + * the character name. + * If such a function returns FALSE, then the enumeration is stopped. + * + * @param context The context pointer that was passed to u_enumCharNames(). + * @param code The Unicode code point for the character with this name. + * @param nameChoice Selector for which kind of names is enumerated. + * @param name The character's name, zero-terminated. + * @param length The length of the name. + * @return TRUE if the enumeration should continue, FALSE to stop it. + * + * @see UCharNameChoice + * @see u_enumCharNames + * @stable ICU 1.7 + */ +typedef UBool U_CALLCONV UEnumCharNamesFn(void *context, + UChar32 code, + UCharNameChoice nameChoice, + const char *name, + int32_t length); + +/** + * Enumerate all assigned Unicode characters between the start and limit + * code points (start inclusive, limit exclusive) and call a function + * for each, passing the code point value and the character name. + * For Unicode 1.0 names, only those are enumerated that differ from the + * modern names. + * + * @param start The first code point in the enumeration range. + * @param limit One more than the last code point in the enumeration range + * (the first one after the range). + * @param fn The function that is to be called for each character name. + * @param context An arbitrary pointer that is passed to the function. + * @param nameChoice Selector for which kind of names to enumerate. + * @param pErrorCode Pointer to a UErrorCode variable + * + * @see UCharNameChoice + * @see UEnumCharNamesFn + * @see u_charName + * @see u_charFromName + * @stable ICU 1.7 + */ +U_STABLE void U_EXPORT2 +u_enumCharNames(UChar32 start, UChar32 limit, + UEnumCharNamesFn *fn, + void *context, + UCharNameChoice nameChoice, + UErrorCode *pErrorCode); + +/** + * Return the Unicode name for a given property, as given in the + * Unicode database file PropertyAliases.txt. + * + * In addition, this function maps the property + * UCHAR_GENERAL_CATEGORY_MASK to the synthetic names "gcm" / + * "General_Category_Mask". These names are not in + * PropertyAliases.txt. + * + * @param property UProperty selector other than UCHAR_INVALID_CODE. + * If out of range, NULL is returned. + * + * @param nameChoice selector for which name to get. If out of range, + * NULL is returned. All properties have a long name. Most + * have a short name, but some do not. Unicode allows for + * additional names; if present these will be returned by + * U_LONG_PROPERTY_NAME + i, where i=1, 2,... + * + * @return a pointer to the name, or NULL if either the + * property or the nameChoice is out of range. If a given + * nameChoice returns NULL, then all larger values of + * nameChoice will return NULL, with one exception: if NULL is + * returned for U_SHORT_PROPERTY_NAME, then + * U_LONG_PROPERTY_NAME (and higher) may still return a + * non-NULL value. The returned pointer is valid until + * u_cleanup() is called. + * + * @see UProperty + * @see UPropertyNameChoice + * @stable ICU 2.4 + */ +U_STABLE const char* U_EXPORT2 +u_getPropertyName(UProperty property, + UPropertyNameChoice nameChoice); + +/** + * Return the UProperty enum for a given property name, as specified + * in the Unicode database file PropertyAliases.txt. Short, long, and + * any other variants are recognized. + * + * In addition, this function maps the synthetic names "gcm" / + * "General_Category_Mask" to the property + * UCHAR_GENERAL_CATEGORY_MASK. These names are not in + * PropertyAliases.txt. + * + * @param alias the property name to be matched. The name is compared + * using "loose matching" as described in PropertyAliases.txt. + * + * @return a UProperty enum, or UCHAR_INVALID_CODE if the given name + * does not match any property. + * + * @see UProperty + * @stable ICU 2.4 + */ +U_STABLE UProperty U_EXPORT2 +u_getPropertyEnum(const char* alias); + +/** + * Return the Unicode name for a given property value, as given in the + * Unicode database file PropertyValueAliases.txt. + * + * Note: Some of the names in PropertyValueAliases.txt can only be + * retrieved using UCHAR_GENERAL_CATEGORY_MASK, not + * UCHAR_GENERAL_CATEGORY. These include: "C" / "Other", "L" / + * "Letter", "LC" / "Cased_Letter", "M" / "Mark", "N" / "Number", "P" + * / "Punctuation", "S" / "Symbol", and "Z" / "Separator". + * + * @param property UProperty selector constant. + * Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT + * or UCHAR_INT_START<=which<UCHAR_INT_LIMIT + * or UCHAR_MASK_START<=which<UCHAR_MASK_LIMIT. + * If out of range, NULL is returned. + * + * @param value selector for a value for the given property. If out + * of range, NULL is returned. In general, valid values range + * from 0 up to some maximum. There are a few exceptions: + * (1.) UCHAR_BLOCK values begin at the non-zero value + * UBLOCK_BASIC_LATIN. (2.) UCHAR_CANONICAL_COMBINING_CLASS + * values are not contiguous and range from 0..240. (3.) + * UCHAR_GENERAL_CATEGORY_MASK values are not values of + * UCharCategory, but rather mask values produced by + * U_GET_GC_MASK(). This allows grouped categories such as + * [:L:] to be represented. Mask values range + * non-contiguously from 1..U_GC_P_MASK. + * + * @param nameChoice selector for which name to get. If out of range, + * NULL is returned. All values have a long name. Most have + * a short name, but some do not. Unicode allows for + * additional names; if present these will be returned by + * U_LONG_PROPERTY_NAME + i, where i=1, 2,... + + * @return a pointer to the name, or NULL if either the + * property or the nameChoice is out of range. If a given + * nameChoice returns NULL, then all larger values of + * nameChoice will return NULL, with one exception: if NULL is + * returned for U_SHORT_PROPERTY_NAME, then + * U_LONG_PROPERTY_NAME (and higher) may still return a + * non-NULL value. The returned pointer is valid until + * u_cleanup() is called. + * + * @see UProperty + * @see UPropertyNameChoice + * @stable ICU 2.4 + */ +U_STABLE const char* U_EXPORT2 +u_getPropertyValueName(UProperty property, + int32_t value, + UPropertyNameChoice nameChoice); + +/** + * Return the property value integer for a given value name, as + * specified in the Unicode database file PropertyValueAliases.txt. + * Short, long, and any other variants are recognized. + * + * Note: Some of the names in PropertyValueAliases.txt will only be + * recognized with UCHAR_GENERAL_CATEGORY_MASK, not + * UCHAR_GENERAL_CATEGORY. These include: "C" / "Other", "L" / + * "Letter", "LC" / "Cased_Letter", "M" / "Mark", "N" / "Number", "P" + * / "Punctuation", "S" / "Symbol", and "Z" / "Separator". + * + * @param property UProperty selector constant. + * Must be UCHAR_BINARY_START<=which<UCHAR_BINARY_LIMIT + * or UCHAR_INT_START<=which<UCHAR_INT_LIMIT + * or UCHAR_MASK_START<=which<UCHAR_MASK_LIMIT. + * If out of range, UCHAR_INVALID_CODE is returned. + * + * @param alias the value name to be matched. The name is compared + * using "loose matching" as described in + * PropertyValueAliases.txt. + * + * @return a value integer or UCHAR_INVALID_CODE if the given name + * does not match any value of the given property, or if the + * property is invalid. Note: U CHAR_GENERAL_CATEGORY values + * are not values of UCharCategory, but rather mask values + * produced by U_GET_GC_MASK(). This allows grouped + * categories such as [:L:] to be represented. + * + * @see UProperty + * @stable ICU 2.4 + */ +U_STABLE int32_t U_EXPORT2 +u_getPropertyValueEnum(UProperty property, + const char* alias); + +/** + * Determines if the specified character is permissible as the + * first character in an identifier according to Unicode + * (The Unicode Standard, Version 3.0, chapter 5.16 Identifiers). + * True for characters with general categories "L" (letters) and "Nl" (letter numbers). + * + * Same as java.lang.Character.isUnicodeIdentifierStart(). + * Same as UCHAR_ID_START + * + * @param c the code point to be tested + * @return TRUE if the code point may start an identifier + * + * @see UCHAR_ID_START + * @see u_isalpha + * @see u_isIDPart + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isIDStart(UChar32 c); + +/** + * Determines if the specified character is permissible + * in an identifier according to Java. + * True for characters with general categories "L" (letters), + * "Nl" (letter numbers), "Nd" (decimal digits), + * "Mc" and "Mn" (combining marks), "Pc" (connecting punctuation), and + * u_isIDIgnorable(c). + * + * Same as java.lang.Character.isUnicodeIdentifierPart(). + * Almost the same as Unicode's ID_Continue (UCHAR_ID_CONTINUE) + * except that Unicode recommends to ignore Cf which is less than + * u_isIDIgnorable(c). + * + * @param c the code point to be tested + * @return TRUE if the code point may occur in an identifier according to Java + * + * @see UCHAR_ID_CONTINUE + * @see u_isIDStart + * @see u_isIDIgnorable + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isIDPart(UChar32 c); + +/** + * Determines if the specified character should be regarded + * as an ignorable character in an identifier, + * according to Java. + * True for characters with general category "Cf" (format controls) as well as + * non-whitespace ISO controls + * (U+0000..U+0008, U+000E..U+001B, U+007F..U+0084, U+0086..U+009F). + * + * Same as java.lang.Character.isIdentifierIgnorable() + * except that Java also returns TRUE for U+0085 Next Line + * (it omits U+0085 from whitespace ISO controls). + * + * Note that Unicode just recommends to ignore Cf (format controls). + * + * @param c the code point to be tested + * @return TRUE if the code point is ignorable in identifiers according to Java + * + * @see UCHAR_DEFAULT_IGNORABLE_CODE_POINT + * @see u_isIDStart + * @see u_isIDPart + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isIDIgnorable(UChar32 c); + +/** + * Determines if the specified character is permissible as the + * first character in a Java identifier. + * In addition to u_isIDStart(c), true for characters with + * general categories "Sc" (currency symbols) and "Pc" (connecting punctuation). + * + * Same as java.lang.Character.isJavaIdentifierStart(). + * + * @param c the code point to be tested + * @return TRUE if the code point may start a Java identifier + * + * @see u_isJavaIDPart + * @see u_isalpha + * @see u_isIDStart + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isJavaIDStart(UChar32 c); + +/** + * Determines if the specified character is permissible + * in a Java identifier. + * In addition to u_isIDPart(c), true for characters with + * general category "Sc" (currency symbols). + * + * Same as java.lang.Character.isJavaIdentifierPart(). + * + * @param c the code point to be tested + * @return TRUE if the code point may occur in a Java identifier + * + * @see u_isIDIgnorable + * @see u_isJavaIDStart + * @see u_isalpha + * @see u_isdigit + * @see u_isIDPart + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +u_isJavaIDPart(UChar32 c); + +/** + * The given character is mapped to its lowercase equivalent according to + * UnicodeData.txt; if the character has no lowercase equivalent, the character + * itself is returned. + * + * Same as java.lang.Character.toLowerCase(). + * + * This function only returns the simple, single-code point case mapping. + * Full case mappings should be used whenever possible because they produce + * better results by working on whole strings. + * They take into account the string context and the language and can map + * to a result string with a different length as appropriate. + * Full case mappings are applied by the string case mapping functions, + * see ustring.h and the UnicodeString class. + * See also the User Guide chapter on C/POSIX migration: + * http://icu-project.org/userguide/posix.html#case_mappings + * + * @param c the code point to be mapped + * @return the Simple_Lowercase_Mapping of the code point, if any; + * otherwise the code point itself. + * @stable ICU 2.0 + */ +U_STABLE UChar32 U_EXPORT2 +u_tolower(UChar32 c); + +/** + * The given character is mapped to its uppercase equivalent according to UnicodeData.txt; + * if the character has no uppercase equivalent, the character itself is + * returned. + * + * Same as java.lang.Character.toUpperCase(). + * + * This function only returns the simple, single-code point case mapping. + * Full case mappings should be used whenever possible because they produce + * better results by working on whole strings. + * They take into account the string context and the language and can map + * to a result string with a different length as appropriate. + * Full case mappings are applied by the string case mapping functions, + * see ustring.h and the UnicodeString class. + * See also the User Guide chapter on C/POSIX migration: + * http://icu-project.org/userguide/posix.html#case_mappings + * + * @param c the code point to be mapped + * @return the Simple_Uppercase_Mapping of the code point, if any; + * otherwise the code point itself. + * @stable ICU 2.0 + */ +U_STABLE UChar32 U_EXPORT2 +u_toupper(UChar32 c); + +/** + * The given character is mapped to its titlecase equivalent + * according to UnicodeData.txt; + * if none is defined, the character itself is returned. + * + * Same as java.lang.Character.toTitleCase(). + * + * This function only returns the simple, single-code point case mapping. + * Full case mappings should be used whenever possible because they produce + * better results by working on whole strings. + * They take into account the string context and the language and can map + * to a result string with a different length as appropriate. + * Full case mappings are applied by the string case mapping functions, + * see ustring.h and the UnicodeString class. + * See also the User Guide chapter on C/POSIX migration: + * http://icu-project.org/userguide/posix.html#case_mappings + * + * @param c the code point to be mapped + * @return the Simple_Titlecase_Mapping of the code point, if any; + * otherwise the code point itself. + * @stable ICU 2.0 + */ +U_STABLE UChar32 U_EXPORT2 +u_totitle(UChar32 c); + +/** Option value for case folding: use default mappings defined in CaseFolding.txt. @stable ICU 2.0 */ +#define U_FOLD_CASE_DEFAULT 0 + +/** + * Option value for case folding: + * + * Use the modified set of mappings provided in CaseFolding.txt to handle dotted I + * and dotless i appropriately for Turkic languages (tr, az). + * + * Before Unicode 3.2, CaseFolding.txt contains mappings marked with 'I' that + * are to be included for default mappings and + * excluded for the Turkic-specific mappings. + * + * Unicode 3.2 CaseFolding.txt instead contains mappings marked with 'T' that + * are to be excluded for default mappings and + * included for the Turkic-specific mappings. + * + * @stable ICU 2.0 + */ +#define U_FOLD_CASE_EXCLUDE_SPECIAL_I 1 + +/** + * The given character is mapped to its case folding equivalent according to + * UnicodeData.txt and CaseFolding.txt; + * if the character has no case folding equivalent, the character + * itself is returned. + * + * This function only returns the simple, single-code point case mapping. + * Full case mappings should be used whenever possible because they produce + * better results by working on whole strings. + * They take into account the string context and the language and can map + * to a result string with a different length as appropriate. + * Full case mappings are applied by the string case mapping functions, + * see ustring.h and the UnicodeString class. + * See also the User Guide chapter on C/POSIX migration: + * http://icu-project.org/userguide/posix.html#case_mappings + * + * @param c the code point to be mapped + * @param options Either U_FOLD_CASE_DEFAULT or U_FOLD_CASE_EXCLUDE_SPECIAL_I + * @return the Simple_Case_Folding of the code point, if any; + * otherwise the code point itself. + * @stable ICU 2.0 + */ +U_STABLE UChar32 U_EXPORT2 +u_foldCase(UChar32 c, uint32_t options); + +/** + * Returns the decimal digit value of the code point in the + * specified radix. + * + * If the radix is not in the range <code>2<=radix<=36</code> or if the + * value of <code>c</code> is not a valid digit in the specified + * radix, <code>-1</code> is returned. A character is a valid digit + * if at least one of the following is true: + * <ul> + * <li>The character has a decimal digit value. + * Such characters have the general category "Nd" (decimal digit numbers) + * and a Numeric_Type of Decimal. + * In this case the value is the character's decimal digit value.</li> + * <li>The character is one of the uppercase Latin letters + * <code>'A'</code> through <code>'Z'</code>. + * In this case the value is <code>c-'A'+10</code>.</li> + * <li>The character is one of the lowercase Latin letters + * <code>'a'</code> through <code>'z'</code>. + * In this case the value is <code>ch-'a'+10</code>.</li> + * <li>Latin letters from both the ASCII range (0061..007A, 0041..005A) + * as well as from the Fullwidth ASCII range (FF41..FF5A, FF21..FF3A) + * are recognized.</li> + * </ul> + * + * Same as java.lang.Character.digit(). + * + * @param ch the code point to be tested. + * @param radix the radix. + * @return the numeric value represented by the character in the + * specified radix, + * or -1 if there is no value or if the value exceeds the radix. + * + * @see UCHAR_NUMERIC_TYPE + * @see u_forDigit + * @see u_charDigitValue + * @see u_isdigit + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_digit(UChar32 ch, int8_t radix); + +/** + * Determines the character representation for a specific digit in + * the specified radix. If the value of <code>radix</code> is not a + * valid radix, or the value of <code>digit</code> is not a valid + * digit in the specified radix, the null character + * (<code>U+0000</code>) is returned. + * <p> + * The <code>radix</code> argument is valid if it is greater than or + * equal to 2 and less than or equal to 36. + * The <code>digit</code> argument is valid if + * <code>0 <= digit < radix</code>. + * <p> + * If the digit is less than 10, then + * <code>'0' + digit</code> is returned. Otherwise, the value + * <code>'a' + digit - 10</code> is returned. + * + * Same as java.lang.Character.forDigit(). + * + * @param digit the number to convert to a character. + * @param radix the radix. + * @return the <code>char</code> representation of the specified digit + * in the specified radix. + * + * @see u_digit + * @see u_charDigitValue + * @see u_isdigit + * @stable ICU 2.0 + */ +U_STABLE UChar32 U_EXPORT2 +u_forDigit(int32_t digit, int8_t radix); + +/** + * Get the "age" of the code point. + * The "age" is the Unicode version when the code point was first + * designated (as a non-character or for Private Use) + * or assigned a character. + * This can be useful to avoid emitting code points to receiving + * processes that do not accept newer characters. + * The data is from the UCD file DerivedAge.txt. + * + * @param c The code point. + * @param versionArray The Unicode version number array, to be filled in. + * + * @stable ICU 2.1 + */ +U_STABLE void U_EXPORT2 +u_charAge(UChar32 c, UVersionInfo versionArray); + +/** + * Gets the Unicode version information. + * The version array is filled in with the version information + * for the Unicode standard that is currently used by ICU. + * For example, Unicode version 3.1.1 is represented as an array with + * the values { 3, 1, 1, 0 }. + * + * @param versionArray an output array that will be filled in with + * the Unicode version number + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +u_getUnicodeVersion(UVersionInfo versionArray); + +/** + * Get the FC_NFKC_Closure property string for a character. + * See Unicode Standard Annex #15 for details, search for "FC_NFKC_Closure" + * or for "FNC": http://www.unicode.org/reports/tr15/ + * + * @param c The character (code point) for which to get the FC_NFKC_Closure string. + * It must be <code>0<=c<=0x10ffff</code>. + * @param dest Destination address for copying the string. + * The string will be zero-terminated if possible. + * If there is no FC_NFKC_Closure string, + * then the buffer will be set to the empty string. + * @param destCapacity <code>==sizeof(dest)</code> + * @param pErrorCode Pointer to a UErrorCode variable. + * @return The length of the string, or 0 if there is no FC_NFKC_Closure string for this character. + * If the destCapacity is less than or equal to the length, then the buffer + * contains the truncated name and the returned length indicates the full + * length of the name. + * The length does not include the zero-termination. + * + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +u_getFC_NFKC_Closure(UChar32 c, UChar *dest, int32_t destCapacity, UErrorCode *pErrorCode); + +U_CDECL_END + +#endif /*_UCHAR*/ +/*eof*/ diff --git a/utils/openttd/unicode/uchriter.h b/utils/openttd/unicode/uchriter.h new file mode 100644 index 00000000000..6d5a990f7b7 --- /dev/null +++ b/utils/openttd/unicode/uchriter.h @@ -0,0 +1,381 @@ +/* +********************************************************************** +* Copyright (C) 1998-2005, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +*/ + +#ifndef UCHRITER_H +#define UCHRITER_H + +#include "unicode/utypes.h" +#include "unicode/chariter.h" + +/** + * \file + * \brief C++ API: UChar Character Iterator + */ + +U_NAMESPACE_BEGIN + +/** + * A concrete subclass of CharacterIterator that iterates over the + * characters (code units or code points) in a UChar array. + * It's possible not only to create an + * iterator that iterates over an entire UChar array, but also to + * create one that iterates over only a subrange of a UChar array + * (iterators over different subranges of the same UChar array don't + * compare equal). + * @see CharacterIterator + * @see ForwardCharacterIterator + * @stable ICU 2.0 + */ +class U_COMMON_API UCharCharacterIterator : public CharacterIterator { +public: + /** + * Create an iterator over the UChar array referred to by "textPtr". + * The iteration range is 0 to <code>length-1</code>. + * text is only aliased, not adopted (the + * destructor will not delete it). + * @param textPtr The UChar array to be iterated over + * @param length The length of the UChar array + * @stable ICU 2.0 + */ + UCharCharacterIterator(const UChar* textPtr, int32_t length); + + /** + * Create an iterator over the UChar array referred to by "textPtr". + * The iteration range is 0 to <code>length-1</code>. + * text is only aliased, not adopted (the + * destructor will not delete it). + * The starting + * position is specified by "position". If "position" is outside the valid + * iteration range, the behavior of this object is undefined. + * @param textPtr The UChar array to be iteratd over + * @param length The length of the UChar array + * @param position The starting position of the iteration + * @stable ICU 2.0 + */ + UCharCharacterIterator(const UChar* textPtr, int32_t length, + int32_t position); + + /** + * Create an iterator over the UChar array referred to by "textPtr". + * The iteration range is 0 to <code>end-1</code>. + * text is only aliased, not adopted (the + * destructor will not delete it). + * The starting + * position is specified by "position". If begin and end do not + * form a valid iteration range or "position" is outside the valid + * iteration range, the behavior of this object is undefined. + * @param textPtr The UChar array to be iterated over + * @param length The length of the UChar array + * @param textBegin The begin position of the iteration range + * @param textEnd The end position of the iteration range + * @param position The starting position of the iteration + * @stable ICU 2.0 + */ + UCharCharacterIterator(const UChar* textPtr, int32_t length, + int32_t textBegin, + int32_t textEnd, + int32_t position); + + /** + * Copy constructor. The new iterator iterates over the same range + * of the same string as "that", and its initial position is the + * same as "that"'s current position. + * @param that The UCharCharacterIterator to be copied + * @stable ICU 2.0 + */ + UCharCharacterIterator(const UCharCharacterIterator& that); + + /** + * Destructor. + * @stable ICU 2.0 + */ + virtual ~UCharCharacterIterator(); + + /** + * Assignment operator. *this is altered to iterate over the sane + * range of the same string as "that", and refers to the same + * character within that string as "that" does. + * @param that The object to be copied + * @return the newly created object + * @stable ICU 2.0 + */ + UCharCharacterIterator& + operator=(const UCharCharacterIterator& that); + + /** + * Returns true if the iterators iterate over the same range of the + * same string and are pointing at the same character. + * @param that The ForwardCharacterIterator used to be compared for equality + * @return true if the iterators iterate over the same range of the + * same string and are pointing at the same character. + * @stable ICU 2.0 + */ + virtual UBool operator==(const ForwardCharacterIterator& that) const; + + /** + * Generates a hash code for this iterator. + * @return the hash code. + * @stable ICU 2.0 + */ + virtual int32_t hashCode(void) const; + + /** + * Returns a new UCharCharacterIterator referring to the same + * character in the same range of the same string as this one. The + * caller must delete the new iterator. + * @return the CharacterIterator newly created + * @stable ICU 2.0 + */ + virtual CharacterIterator* clone(void) const; + + /** + * Sets the iterator to refer to the first code unit in its + * iteration range, and returns that code unit. + * This can be used to begin an iteration with next(). + * @return the first code unit in its iteration range. + * @stable ICU 2.0 + */ + virtual UChar first(void); + + /** + * Sets the iterator to refer to the first code unit in its + * iteration range, returns that code unit, and moves the position + * to the second code unit. This is an alternative to setToStart() + * for forward iteration with nextPostInc(). + * @return the first code unit in its iteration range + * @stable ICU 2.0 + */ + virtual UChar firstPostInc(void); + + /** + * Sets the iterator to refer to the first code point in its + * iteration range, and returns that code unit, + * This can be used to begin an iteration with next32(). + * Note that an iteration with next32PostInc(), beginning with, + * e.g., setToStart() or firstPostInc(), is more efficient. + * @return the first code point in its iteration range + * @stable ICU 2.0 + */ + virtual UChar32 first32(void); + + /** + * Sets the iterator to refer to the first code point in its + * iteration range, returns that code point, and moves the position + * to the second code point. This is an alternative to setToStart() + * for forward iteration with next32PostInc(). + * @return the first code point in its iteration range. + * @stable ICU 2.0 + */ + virtual UChar32 first32PostInc(void); + + /** + * Sets the iterator to refer to the last code unit in its + * iteration range, and returns that code unit. + * This can be used to begin an iteration with previous(). + * @return the last code unit in its iteration range. + * @stable ICU 2.0 + */ + virtual UChar last(void); + + /** + * Sets the iterator to refer to the last code point in its + * iteration range, and returns that code unit. + * This can be used to begin an iteration with previous32(). + * @return the last code point in its iteration range. + * @stable ICU 2.0 + */ + virtual UChar32 last32(void); + + /** + * Sets the iterator to refer to the "position"-th code unit + * in the text-storage object the iterator refers to, and + * returns that code unit. + * @param position the position within the text-storage object + * @return the code unit + * @stable ICU 2.0 + */ + virtual UChar setIndex(int32_t position); + + /** + * Sets the iterator to refer to the beginning of the code point + * that contains the "position"-th code unit + * in the text-storage object the iterator refers to, and + * returns that code point. + * The current position is adjusted to the beginning of the code point + * (its first code unit). + * @param position the position within the text-storage object + * @return the code unit + * @stable ICU 2.0 + */ + virtual UChar32 setIndex32(int32_t position); + + /** + * Returns the code unit the iterator currently refers to. + * @return the code unit the iterator currently refers to. + * @stable ICU 2.0 + */ + virtual UChar current(void) const; + + /** + * Returns the code point the iterator currently refers to. + * @return the code point the iterator currently refers to. + * @stable ICU 2.0 + */ + virtual UChar32 current32(void) const; + + /** + * Advances to the next code unit in the iteration range (toward + * endIndex()), and returns that code unit. If there are no more + * code units to return, returns DONE. + * @return the next code unit in the iteration range. + * @stable ICU 2.0 + */ + virtual UChar next(void); + + /** + * Gets the current code unit for returning and advances to the next code unit + * in the iteration range + * (toward endIndex()). If there are + * no more code units to return, returns DONE. + * @return the current code unit. + * @stable ICU 2.0 + */ + virtual UChar nextPostInc(void); + + /** + * Advances to the next code point in the iteration range (toward + * endIndex()), and returns that code point. If there are no more + * code points to return, returns DONE. + * Note that iteration with "pre-increment" semantics is less + * efficient than iteration with "post-increment" semantics + * that is provided by next32PostInc(). + * @return the next code point in the iteration range. + * @stable ICU 2.0 + */ + virtual UChar32 next32(void); + + /** + * Gets the current code point for returning and advances to the next code point + * in the iteration range + * (toward endIndex()). If there are + * no more code points to return, returns DONE. + * @return the current point. + * @stable ICU 2.0 + */ + virtual UChar32 next32PostInc(void); + + /** + * Returns FALSE if there are no more code units or code points + * at or after the current position in the iteration range. + * This is used with nextPostInc() or next32PostInc() in forward + * iteration. + * @return FALSE if there are no more code units or code points + * at or after the current position in the iteration range. + * @stable ICU 2.0 + */ + virtual UBool hasNext(); + + /** + * Advances to the previous code unit in the iteration range (toward + * startIndex()), and returns that code unit. If there are no more + * code units to return, returns DONE. + * @return the previous code unit in the iteration range. + * @stable ICU 2.0 + */ + virtual UChar previous(void); + + /** + * Advances to the previous code point in the iteration range (toward + * startIndex()), and returns that code point. If there are no more + * code points to return, returns DONE. + * @return the previous code point in the iteration range. + * @stable ICU 2.0 + */ + virtual UChar32 previous32(void); + + /** + * Returns FALSE if there are no more code units or code points + * before the current position in the iteration range. + * This is used with previous() or previous32() in backward + * iteration. + * @return FALSE if there are no more code units or code points + * before the current position in the iteration range. + * @stable ICU 2.0 + */ + virtual UBool hasPrevious(); + + /** + * Moves the current position relative to the start or end of the + * iteration range, or relative to the current position itself. + * The movement is expressed in numbers of code units forward + * or backward by specifying a positive or negative delta. + * @param delta the position relative to origin. A positive delta means forward; + * a negative delta means backward. + * @param origin Origin enumeration {kStart, kCurrent, kEnd} + * @return the new position + * @stable ICU 2.0 + */ + virtual int32_t move(int32_t delta, EOrigin origin); + + /** + * Moves the current position relative to the start or end of the + * iteration range, or relative to the current position itself. + * The movement is expressed in numbers of code points forward + * or backward by specifying a positive or negative delta. + * @param delta the position relative to origin. A positive delta means forward; + * a negative delta means backward. + * @param origin Origin enumeration {kStart, kCurrent, kEnd} + * @return the new position + * @stable ICU 2.0 + */ + virtual int32_t move32(int32_t delta, EOrigin origin); + + /** + * Sets the iterator to iterate over a new range of text + * @stable ICU 2.0 + */ + void setText(const UChar* newText, int32_t newTextLength); + + /** + * Copies the UChar array under iteration into the UnicodeString + * referred to by "result". Even if this iterator iterates across + * only a part of this string, the whole string is copied. + * @param result Receives a copy of the text under iteration. + * @stable ICU 2.0 + */ + virtual void getText(UnicodeString& result); + + /** + * Return a class ID for this class (not really public) + * @return a class ID for this class + * @stable ICU 2.0 + */ + static UClassID U_EXPORT2 getStaticClassID(void); + + /** + * Return a class ID for this object (not really public) + * @return a class ID for this object. + * @stable ICU 2.0 + */ + virtual UClassID getDynamicClassID(void) const; + +protected: + /** + * Protected constructor + * @stable ICU 2.0 + */ + UCharCharacterIterator(); + /** + * Protected member text + * @stable ICU 2.0 + */ + const UChar* text; + +}; + +U_NAMESPACE_END +#endif diff --git a/utils/openttd/unicode/uclean.h b/utils/openttd/unicode/uclean.h new file mode 100644 index 00000000000..a13924a0c3f --- /dev/null +++ b/utils/openttd/unicode/uclean.h @@ -0,0 +1,267 @@ +/* +****************************************************************************** +* * +* Copyright (C) 2001-2005, International Business Machines * +* Corporation and others. All Rights Reserved. * +* * +****************************************************************************** +* file name: uclean.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2001July05 +* created by: George Rhoten +*/ + +#ifndef __UCLEAN_H__ +#define __UCLEAN_H__ + +#include "unicode/utypes.h" +/** + * \file + * \brief C API: Initialize and clean up ICU + */ + +/** + * Initialize ICU. The description further below applies to ICU 2.6 to ICU 3.4. + * Starting with ICU 3.4, u_init() needs not be called any more for + * ensuring thread safety, but it can give an indication for whether ICU + * can load its data. In ICU 3.4, it will try to load the converter alias table + * (cnvalias.icu) and give an error code if that fails. + * This may change in the future. + * <p> + * For ensuring the availability of necessary data, an application should + * open the service objects (converters, collators, etc.) that it will use + * and check for error codes there. + * <p> + * Documentation for ICU 2.6 to ICU 3.4: + * <p> + * This function loads and initializes data items + * that are required internally by various ICU functions. Use of this explicit + * initialization is required in multi-threaded applications; in + * single threaded apps, use is optional, but incurs little additional + * cost, and is thus recommended. + * <p> + * In multi-threaded applications, u_init() should be called in the + * main thread before starting additional threads, or, alternatively + * it can be called in each individual thread once, before other ICU + * functions are called in that thread. In this second scenario, the + * application must guarantee that the first call to u_init() happen + * without contention, in a single thread only. + * <p> + * If <code>u_setMemoryFunctions()</code> or + * <code>u_setMutexFunctions</code> are needed (uncommon), they must be + * called _before_ <code>u_init()</code>. + * <p> + * Extra, repeated, or otherwise unneeded calls to u_init() do no harm, + * other than taking a small amount of time. + * + * @param status An ICU UErrorCode parameter. It must not be <code>NULL</code>. + * An Error will be returned if some required part of ICU data can not + * be loaded or initialized. + * The function returns immediately if the input error code indicates a + * failure, as usual. + * + * @stable ICU 2.6 + */ +U_STABLE void U_EXPORT2 +u_init(UErrorCode *status); + +/** + * Clean up the system resources, such as allocated memory or open files, + * used in all ICU libraries. This will free/delete all memory owned by the + * ICU libraries, and return them to their original load state. All open ICU + * items (collators, resource bundles, converters, etc.) must be closed before + * calling this function, otherwise ICU may not free its allocated memory + * (e.g. close your converters and resource bundles before calling this + * function). Generally, this function should be called once just before + * an application exits. For applications that dynamically load and unload + * the ICU libraries (relatively uncommon), u_cleanup() should be called + * just before the library unload. + * <p> + * u_cleanup() also clears any ICU heap functions, mutex functions or + * trace functions that may have been set for the process. + * This has the effect of restoring ICU to its initial condition, before + * any of these override functions were installed. Refer to + * u_setMemoryFunctions(), u_setMutexFunctions and + * utrace_setFunctions(). If ICU is to be reinitialized after after + * calling u_cleanup(), these runtime override functions will need to + * be set up again if they are still required. + * <p> + * u_cleanup() is not thread safe. All other threads should stop using ICU + * before calling this function. + * <p> + * Any open ICU items will be left in an undefined state by u_cleanup(), + * and any subsequent attempt to use such an item will give unpredictable + * results. + * <p> + * After calling u_cleanup(), an application may continue to use ICU by + * calling u_init(). An application must invoke u_init() first from one single + * thread before allowing other threads call u_init(). All threads existing + * at the time of the first thread's call to u_init() must also call + * u_init() themselves before continuing with other ICU operations. + * <p> + * The use of u_cleanup() just before an application terminates is optional, + * but it should be called only once for performance reasons. The primary + * benefit is to eliminate reports of memory or resource leaks originating + * in ICU code from the results generated by heap analysis tools. + * <p> + * <strong>Use this function with great care!</strong> + * </p> + * + * @stable ICU 2.0 + * @system + */ +U_STABLE void U_EXPORT2 +u_cleanup(void); + + + + +/** + * An opaque pointer type that represents an ICU mutex. + * For user-implemented mutexes, the value will typically point to a + * struct or object that implements the mutex. + * @stable ICU 2.8 + * @system + */ +typedef void *UMTX; + +/** + * Function Pointer type for a user supplied mutex initialization function. + * The user-supplied function will be called by ICU whenever ICU needs to create a + * new mutex. The function implementation should create a mutex, and store a pointer + * to something that uniquely identifies the mutex into the UMTX that is supplied + * as a paramter. + * @param context user supplied value, obtained from from u_setMutexFunctions(). + * @param mutex Receives a pointer that identifies the new mutex. + * The mutex init function must set the UMTX to a non-null value. + * Subsequent calls by ICU to lock, unlock, or destroy a mutex will + * identify the mutex by the UMTX value. + * @param status Error status. Report errors back to ICU by setting this variable + * with an error code. + * @stable ICU 2.8 + * @system + */ +typedef void U_CALLCONV UMtxInitFn (const void *context, UMTX *mutex, UErrorCode* status); + + +/** + * Function Pointer type for a user supplied mutex functions. + * One of the user-supplied functions with this signature will be called by ICU + * whenever ICU needs to lock, unlock, or destroy a mutex. + * @param context user supplied value, obtained from from u_setMutexFunctions(). + * @param mutex specify the mutex on which to operate. + * @stable ICU 2.8 + * @system + */ +typedef void U_CALLCONV UMtxFn (const void *context, UMTX *mutex); + + +/** + * Set the functions that ICU will use for mutex operations + * Use of this function is optional; by default (without this function), ICU will + * directly access system functions for mutex operations + * This function can only be used when ICU is in an initial, unused state, before + * u_init() has been called. + * This function may be used even when ICU has been built without multi-threaded + * support (see ICU_USE_THREADS pre-processor variable, umutex.h) + * @param context This pointer value will be saved, and then (later) passed as + * a parameter to the user-supplied mutex functions each time they + * are called. + * @param init Pointer to a mutex initialization function. Must be non-null. + * @param destroy Pointer to the mutex destroy function. Must be non-null. + * @param lock pointer to the mutex lock function. Must be non-null. + * @param unlock Pointer to the mutex unlock function. Must be non-null. + * @param status Receives error values. + * @stable ICU 2.8 + * @system + */ +U_STABLE void U_EXPORT2 +u_setMutexFunctions(const void *context, UMtxInitFn *init, UMtxFn *destroy, UMtxFn *lock, UMtxFn *unlock, + UErrorCode *status); + + +/** + * Pointer type for a user supplied atomic increment or decrement function. + * @param context user supplied value, obtained from from u_setAtomicIncDecFunctions(). + * @param p Pointer to a 32 bit int to be incremented or decremented + * @return The value of the variable after the inc or dec operation. + * @stable ICU 2.8 + * @system + */ +typedef int32_t U_CALLCONV UMtxAtomicFn(const void *context, int32_t *p); + +/** + * Set the functions that ICU will use for atomic increment and decrement of int32_t values. + * Use of this function is optional; by default (without this function), ICU will + * use its own internal implementation of atomic increment/decrement. + * This function can only be used when ICU is in an initial, unused state, before + * u_init() has been called. + * @param context This pointer value will be saved, and then (later) passed as + * a parameter to the increment and decrement functions each time they + * are called. This function can only be called + * @param inc Pointer to a function to do an atomic increment operation. Must be non-null. + * @param dec Pointer to a function to do an atomic decrement operation. Must be non-null. + * @param status Receives error values. + * @stable ICU 2.8 + * @system + */ +U_STABLE void U_EXPORT2 +u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *inc, UMtxAtomicFn *dec, + UErrorCode *status); + + + +/** + * Pointer type for a user supplied memory allocation function. + * @param context user supplied value, obtained from from u_setMemoryFunctions(). + * @param size The number of bytes to be allocated + * @return Pointer to the newly allocated memory, or NULL if the allocation failed. + * @stable ICU 2.8 + * @system + */ +typedef void *U_CALLCONV UMemAllocFn(const void *context, size_t size); +/** + * Pointer type for a user supplied memory re-allocation function. + * @param context user supplied value, obtained from from u_setMemoryFunctions(). + * @param size The number of bytes to be allocated + * @return Pointer to the newly allocated memory, or NULL if the allocation failed. + * @stable ICU 2.8 + * @system + */ +typedef void *U_CALLCONV UMemReallocFn(const void *context, void *mem, size_t size); +/** + * Pointer type for a user supplied memory free function. Behavior should be + * similar the standard C library free(). + * @param context user supplied value, obtained from from u_setMemoryFunctions(). + * @param mem Pointer to the memory block to be resized + * @param size The new size for the block + * @return Pointer to the resized memory block, or NULL if the resizing failed. + * @stable ICU 2.8 + * @system + */ +typedef void U_CALLCONV UMemFreeFn (const void *context, void *mem); + +/** + * Set the functions that ICU will use for memory allocation. + * Use of this function is optional; by default (without this function), ICU will + * use the standard C library malloc() and free() functions. + * This function can only be used when ICU is in an initial, unused state, before + * u_init() has been called. + * @param context This pointer value will be saved, and then (later) passed as + * a parameter to the memory functions each time they + * are called. + * @param a Pointer to a user-supplied malloc function. + * @param r Pointer to a user-supplied realloc function. + * @param f Pointer to a user-supplied free function. + * @param status Receives error values. + * @stable ICU 2.8 + * @system + */ +U_STABLE void U_EXPORT2 +u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f, + UErrorCode *status); + +#endif diff --git a/utils/openttd/unicode/ucnv.h b/utils/openttd/unicode/ucnv.h new file mode 100644 index 00000000000..bfd7198ee73 --- /dev/null +++ b/utils/openttd/unicode/ucnv.h @@ -0,0 +1,1967 @@ +/* +********************************************************************** +* Copyright (C) 1999-2008, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** + * ucnv.h: + * External APIs for the ICU's codeset conversion library + * Bertrand A. Damiba + * + * Modification History: + * + * Date Name Description + * 04/04/99 helena Fixed internal header inclusion. + * 05/11/00 helena Added setFallback and usesFallback APIs. + * 06/29/2000 helena Major rewrite of the callback APIs. + * 12/07/2000 srl Update of documentation + */ + +/** + * \file + * \brief C API: Character conversion + * + * <h2>Character Conversion C API</h2> + * + * <p>This API is used to convert codepage or character encoded data to and + * from UTF-16. You can open a converter with {@link ucnv_open() }. With that + * converter, you can get its properties, set options, convert your data and + * close the converter.</p> + * + * <p>Since many software programs recogize different converter names for + * different types of converters, there are other functions in this API to + * iterate over the converter aliases. The functions {@link ucnv_getAvailableName() }, + * {@link ucnv_getAlias() } and {@link ucnv_getStandardName() } are some of the + * more frequently used alias functions to get this information.</p> + * + * <p>When a converter encounters an illegal, irregular, invalid or unmappable character + * its default behavior is to use a substitution character to replace the + * bad byte sequence. This behavior can be changed by using {@link ucnv_setFromUCallBack() } + * or {@link ucnv_setToUCallBack() } on the converter. The header ucnv_err.h defines + * many other callback actions that can be used instead of a character substitution.</p> + * + * <p>More information about this API can be found in our + * <a href="http://icu-project.org/userguide/conversion.html">User's + * Guide</a>.</p> + */ + +#ifndef UCNV_H +#define UCNV_H + +#include "unicode/ucnv_err.h" +#include "unicode/uenum.h" + +#ifndef __USET_H__ + +/** + * USet is the C API type for Unicode sets. + * It is forward-declared here to avoid including the header file if related + * conversion APIs are not used. + * See unicode/uset.h + * + * @see ucnv_getUnicodeSet + * @stable ICU 2.6 + */ +struct USet; +/** @stable ICU 2.6 */ +typedef struct USet USet; + +#endif + +#if !UCONFIG_NO_CONVERSION + +U_CDECL_BEGIN + +/** Maximum length of a converter name including the terminating NULL @stable ICU 2.0 */ +#define UCNV_MAX_CONVERTER_NAME_LENGTH 60 +/** Maximum length of a converter name including path and terminating NULL @stable ICU 2.0 */ +#define UCNV_MAX_FULL_FILE_NAME_LENGTH (600+UCNV_MAX_CONVERTER_NAME_LENGTH) + +/** Shift in for EBDCDIC_STATEFUL and iso2022 states @stable ICU 2.0 */ +#define UCNV_SI 0x0F +/** Shift out for EBDCDIC_STATEFUL and iso2022 states @stable ICU 2.0 */ +#define UCNV_SO 0x0E + +/** + * Enum for specifying basic types of converters + * @see ucnv_getType + * @stable ICU 2.0 + */ +typedef enum { + UCNV_UNSUPPORTED_CONVERTER = -1, + UCNV_SBCS = 0, + UCNV_DBCS = 1, + UCNV_MBCS = 2, + UCNV_LATIN_1 = 3, + UCNV_UTF8 = 4, + UCNV_UTF16_BigEndian = 5, + UCNV_UTF16_LittleEndian = 6, + UCNV_UTF32_BigEndian = 7, + UCNV_UTF32_LittleEndian = 8, + UCNV_EBCDIC_STATEFUL = 9, + UCNV_ISO_2022 = 10, + + UCNV_LMBCS_1 = 11, + UCNV_LMBCS_2, + UCNV_LMBCS_3, + UCNV_LMBCS_4, + UCNV_LMBCS_5, + UCNV_LMBCS_6, + UCNV_LMBCS_8, + UCNV_LMBCS_11, + UCNV_LMBCS_16, + UCNV_LMBCS_17, + UCNV_LMBCS_18, + UCNV_LMBCS_19, + UCNV_LMBCS_LAST = UCNV_LMBCS_19, + UCNV_HZ, + UCNV_SCSU, + UCNV_ISCII, + UCNV_US_ASCII, + UCNV_UTF7, + UCNV_BOCU1, + UCNV_UTF16, + UCNV_UTF32, + UCNV_CESU8, + UCNV_IMAP_MAILBOX, + + /* Number of converter types for which we have conversion routines. */ + UCNV_NUMBER_OF_SUPPORTED_CONVERTER_TYPES + +} UConverterType; + +/** + * Enum for specifying which platform a converter ID refers to. + * The use of platform/CCSID is not recommended. See ucnv_openCCSID(). + * + * @see ucnv_getPlatform + * @see ucnv_openCCSID + * @see ucnv_getCCSID + * @stable ICU 2.0 + */ +typedef enum { + UCNV_UNKNOWN = -1, + UCNV_IBM = 0 +} UConverterPlatform; + +/** + * Function pointer for error callback in the codepage to unicode direction. + * Called when an error has occured in conversion to unicode, or on open/close of the callback (see reason). + * @param context Pointer to the callback's private data + * @param args Information about the conversion in progress + * @param codeUnits Points to 'length' bytes of the concerned codepage sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param reason Defines the reason the callback was invoked + * @param pErrorCode ICU error code in/out parameter. + * For converter callback functions, set to a conversion error + * before the call, and the callback may reset it to U_ZERO_ERROR. + * @see ucnv_setToUCallBack + * @see UConverterToUnicodeArgs + * @stable ICU 2.0 + */ +typedef void (U_EXPORT2 *UConverterToUCallback) ( + const void* context, + UConverterToUnicodeArgs *args, + const char *codeUnits, + int32_t length, + UConverterCallbackReason reason, + UErrorCode *pErrorCode); + +/** + * Function pointer for error callback in the unicode to codepage direction. + * Called when an error has occured in conversion from unicode, or on open/close of the callback (see reason). + * @param context Pointer to the callback's private data + * @param args Information about the conversion in progress + * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint. + * @param reason Defines the reason the callback was invoked + * @param pErrorCode ICU error code in/out parameter. + * For converter callback functions, set to a conversion error + * before the call, and the callback may reset it to U_ZERO_ERROR. + * @see ucnv_setFromUCallBack + * @stable ICU 2.0 + */ +typedef void (U_EXPORT2 *UConverterFromUCallback) ( + const void* context, + UConverterFromUnicodeArgs *args, + const UChar* codeUnits, + int32_t length, + UChar32 codePoint, + UConverterCallbackReason reason, + UErrorCode *pErrorCode); + +U_CDECL_END + +/** + * Character that separates converter names from options and options from each other. + * @see ucnv_open + * @stable ICU 2.0 + */ +#define UCNV_OPTION_SEP_CHAR ',' + +/** + * String version of UCNV_OPTION_SEP_CHAR. + * @see ucnv_open + * @stable ICU 2.0 + */ +#define UCNV_OPTION_SEP_STRING "," + +/** + * Character that separates a converter option from its value. + * @see ucnv_open + * @stable ICU 2.0 + */ +#define UCNV_VALUE_SEP_CHAR '=' + +/** + * String version of UCNV_VALUE_SEP_CHAR. + * @see ucnv_open + * @stable ICU 2.0 + */ +#define UCNV_VALUE_SEP_STRING "=" + +/** + * Converter option for specifying a locale. + * For example, ucnv_open("SCSU,locale=ja", &errorCode); + * See convrtrs.txt. + * + * @see ucnv_open + * @stable ICU 2.0 + */ +#define UCNV_LOCALE_OPTION_STRING ",locale=" + +/** + * Converter option for specifying a version selector (0..9) for some converters. + * For example, ucnv_open("UTF-7,version=1", &errorCode); + * See convrtrs.txt. + * + * @see ucnv_open + * @stable ICU 2.4 + */ +#define UCNV_VERSION_OPTION_STRING ",version=" + +/** + * Converter option for EBCDIC SBCS or mixed-SBCS/DBCS (stateful) codepages. + * Swaps Unicode mappings for EBCDIC LF and NL codes, as used on + * S/390 (z/OS) Unix System Services (Open Edition). + * For example, ucnv_open("ibm-1047,swaplfnl", &errorCode); + * See convrtrs.txt. + * + * @see ucnv_open + * @stable ICU 2.4 + */ +#define UCNV_SWAP_LFNL_OPTION_STRING ",swaplfnl" + +/** + * Do a fuzzy compare of two converter/alias names. + * The comparison is case-insensitive, ignores leading zeroes if they are not + * followed by further digits, and ignores all but letters and digits. + * Thus the strings "UTF-8", "utf_8", "u*T@f08" and "Utf 8" are exactly equivalent. + * See section 1.4, Charset Alias Matching in Unicode Technical Standard #22 + * at http://www.unicode.org/reports/tr22/ + * + * @param name1 a converter name or alias, zero-terminated + * @param name2 a converter name or alias, zero-terminated + * @return 0 if the names match, or a negative value if the name1 + * lexically precedes name2, or a positive value if the name1 + * lexically follows name2. + * @stable ICU 2.0 + */ +U_STABLE int U_EXPORT2 +ucnv_compareNames(const char *name1, const char *name2); + + +/** + * Creates a UConverter object with the name of a coded character set specified as a C string. + * The actual name will be resolved with the alias file + * using a case-insensitive string comparison that ignores + * leading zeroes and all non-alphanumeric characters. + * E.g., the names "UTF8", "utf-8", "u*T@f08" and "Utf 8" are all equivalent. + * (See also ucnv_compareNames().) + * If <code>NULL</code> is passed for the converter name, it will create one with the + * getDefaultName return value. + * + * <p>A converter name for ICU 1.5 and above may contain options + * like a locale specification to control the specific behavior of + * the newly instantiated converter. + * The meaning of the options depends on the particular converter. + * If an option is not defined for or recognized by a given converter, then it is ignored.</p> + * + * <p>Options are appended to the converter name string, with a + * <code>UCNV_OPTION_SEP_CHAR</code> between the name and the first option and + * also between adjacent options.</p> + * + * <p>If the alias is ambiguous, then the preferred converter is used + * and the status is set to U_AMBIGUOUS_ALIAS_WARNING.</p> + * + * <p>The conversion behavior and names can vary between platforms. ICU may + * convert some characters differently from other platforms. Details on this topic + * are in the <a href="http://icu-project.org/userguide/conversion.html">User's + * Guide</a>. Aliases starting with a "cp" prefix have no specific meaning + * other than its an alias starting with the letters "cp". Please do not + * associate any meaning to these aliases.</p> + * + * @param converterName Name of the coded character set table. + * This may have options appended to the string. + * IANA alias character set names, IBM CCSIDs starting with "ibm-", + * Windows codepage numbers starting with "windows-" are frequently + * used for this parameter. See ucnv_getAvailableName and + * ucnv_getAlias for a complete list that is available. + * If this parameter is NULL, the default converter will be used. + * @param err outgoing error status <TT>U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR</TT> + * @return the created Unicode converter object, or <TT>NULL</TT> if an error occured + * @see ucnv_openU + * @see ucnv_openCCSID + * @see ucnv_getAvailableName + * @see ucnv_getAlias + * @see ucnv_getDefaultName + * @see ucnv_close + * @see ucnv_compareNames + * @stable ICU 2.0 + */ +U_STABLE UConverter* U_EXPORT2 +ucnv_open(const char *converterName, UErrorCode *err); + + +/** + * Creates a Unicode converter with the names specified as unicode string. + * The name should be limited to the ASCII-7 alphanumerics range. + * The actual name will be resolved with the alias file + * using a case-insensitive string comparison that ignores + * leading zeroes and all non-alphanumeric characters. + * E.g., the names "UTF8", "utf-8", "u*T@f08" and "Utf 8" are all equivalent. + * (See also ucnv_compareNames().) + * If <TT>NULL</TT> is passed for the converter name, it will create + * one with the ucnv_getDefaultName() return value. + * If the alias is ambiguous, then the preferred converter is used + * and the status is set to U_AMBIGUOUS_ALIAS_WARNING. + * + * <p>See ucnv_open for the complete details</p> + * @param name Name of the UConverter table in a zero terminated + * Unicode string + * @param err outgoing error status <TT>U_MEMORY_ALLOCATION_ERROR, + * U_FILE_ACCESS_ERROR</TT> + * @return the created Unicode converter object, or <TT>NULL</TT> if an + * error occured + * @see ucnv_open + * @see ucnv_openCCSID + * @see ucnv_close + * @see ucnv_compareNames + * @stable ICU 2.0 + */ +U_STABLE UConverter* U_EXPORT2 +ucnv_openU(const UChar *name, + UErrorCode *err); + +/** + * Creates a UConverter object from a CCSID number and platform pair. + * Note that the usefulness of this function is limited to platforms with numeric + * encoding IDs. Only IBM and Microsoft platforms use numeric (16-bit) identifiers for + * encodings. + * + * In addition, IBM CCSIDs and Unicode conversion tables are not 1:1 related. + * For many IBM CCSIDs there are multiple (up to six) Unicode conversion tables, and + * for some Unicode conversion tables there are multiple CCSIDs. + * Some "alternate" Unicode conversion tables are provided by the + * IBM CDRA conversion table registry. + * The most prominent example of a systematic modification of conversion tables that is + * not provided in the form of conversion table files in the repository is + * that S/390 Unix System Services swaps the codes for Line Feed and New Line in all + * EBCDIC codepages, which requires such a swap in the Unicode conversion tables as well. + * + * Only IBM default conversion tables are accessible with ucnv_openCCSID(). + * ucnv_getCCSID() will return the same CCSID for all conversion tables that are associated + * with that CCSID. + * + * Currently, the only "platform" supported in the ICU converter API is UCNV_IBM. + * + * In summary, the use of CCSIDs and the associated API functions is not recommended. + * + * In order to open a converter with the default IBM CDRA Unicode conversion table, + * you can use this function or use the prefix "ibm-": + * \code + * char name[20]; + * sprintf(name, "ibm-%hu", ccsid); + * cnv=ucnv_open(name, &errorCode); + * \endcode + * + * In order to open a converter with the IBM S/390 Unix System Services variant + * of a Unicode/EBCDIC conversion table, + * you can use the prefix "ibm-" together with the option string UCNV_SWAP_LFNL_OPTION_STRING: + * \code + * char name[20]; + * sprintf(name, "ibm-%hu" UCNV_SWAP_LFNL_OPTION_STRING, ccsid); + * cnv=ucnv_open(name, &errorCode); + * \endcode + * + * In order to open a converter from a Microsoft codepage number, use the prefix "cp": + * \code + * char name[20]; + * sprintf(name, "cp%hu", codepageID); + * cnv=ucnv_open(name, &errorCode); + * \endcode + * + * If the alias is ambiguous, then the preferred converter is used + * and the status is set to U_AMBIGUOUS_ALIAS_WARNING. + * + * @param codepage codepage number to create + * @param platform the platform in which the codepage number exists + * @param err error status <TT>U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR</TT> + * @return the created Unicode converter object, or <TT>NULL</TT> if an error + * occured. + * @see ucnv_open + * @see ucnv_openU + * @see ucnv_close + * @see ucnv_getCCSID + * @see ucnv_getPlatform + * @see UConverterPlatform + * @stable ICU 2.0 + */ +U_STABLE UConverter* U_EXPORT2 +ucnv_openCCSID(int32_t codepage, + UConverterPlatform platform, + UErrorCode * err); + +/** + * <p>Creates a UConverter object specified from a packageName and a converterName.</p> + * + * <p>The packageName and converterName must point to an ICU udata object, as defined by + * <code> udata_open( packageName, "cnv", converterName, err) </code> or equivalent. + * Typically, packageName will refer to a (.dat) file, or to a package registered with + * udata_setAppData(). Using a full file or directory pathname for packageName is deprecated.</p> + * + * <p>The name will NOT be looked up in the alias mechanism, nor will the converter be + * stored in the converter cache or the alias table. The only way to open further converters + * is call this function multiple times, or use the ucnv_safeClone() function to clone a + * 'master' converter.</p> + * + * <p>A future version of ICU may add alias table lookups and/or caching + * to this function.</p> + * + * <p>Example Use: + * <code>cnv = ucnv_openPackage("myapp", "myconverter", &err);</code> + * </p> + * + * @param packageName name of the package (equivalent to 'path' in udata_open() call) + * @param converterName name of the data item to be used, without suffix. + * @param err outgoing error status <TT>U_MEMORY_ALLOCATION_ERROR, U_FILE_ACCESS_ERROR</TT> + * @return the created Unicode converter object, or <TT>NULL</TT> if an error occured + * @see udata_open + * @see ucnv_open + * @see ucnv_safeClone + * @see ucnv_close + * @stable ICU 2.2 + */ +U_STABLE UConverter* U_EXPORT2 +ucnv_openPackage(const char *packageName, const char *converterName, UErrorCode *err); + +/** + * Thread safe converter cloning operation. + * For most efficient operation, pass in a stackBuffer (and a *pBufferSize) + * with at least U_CNV_SAFECLONE_BUFFERSIZE bytes of space. + * If the buffer size is sufficient, then the clone will use the stack buffer; + * otherwise, it will be allocated, and *pBufferSize will indicate + * the actual size. (This should not occur with U_CNV_SAFECLONE_BUFFERSIZE.) + * + * You must ucnv_close() the clone in any case. + * + * If *pBufferSize==0, (regardless of whether stackBuffer==NULL or not) + * then *pBufferSize will be changed to a sufficient size + * for cloning this converter, + * without actually cloning the converter ("pure pre-flighting"). + * + * If *pBufferSize is greater than zero but not large enough for a stack-based + * clone, then the converter is cloned using newly allocated memory + * and *pBufferSize is changed to the necessary size. + * + * If the converter clone fits into the stack buffer but the stack buffer is not + * sufficiently aligned for the clone, then the clone will use an + * adjusted pointer and use an accordingly smaller buffer size. + * + * @param cnv converter to be cloned + * @param stackBuffer user allocated space for the new clone. If NULL new memory will be allocated. + * If buffer is not large enough, new memory will be allocated. + * Clients can use the U_CNV_SAFECLONE_BUFFERSIZE. This will probably be enough to avoid memory allocations. + * @param pBufferSize pointer to size of allocated space. pBufferSize must not be NULL. + * @param status to indicate whether the operation went on smoothly or there were errors + * An informational status value, U_SAFECLONE_ALLOCATED_WARNING, + * is used if any allocations were necessary. + * However, it is better to check if *pBufferSize grew for checking for + * allocations because warning codes can be overridden by subsequent + * function calls. + * @return pointer to the new clone + * @stable ICU 2.0 + */ +U_STABLE UConverter * U_EXPORT2 +ucnv_safeClone(const UConverter *cnv, + void *stackBuffer, + int32_t *pBufferSize, + UErrorCode *status); + +/** + * \def U_CNV_SAFECLONE_BUFFERSIZE + * Definition of a buffer size that is designed to be large enough for + * converters to be cloned with ucnv_safeClone(). + * @stable ICU 2.0 + */ +#define U_CNV_SAFECLONE_BUFFERSIZE 1024 + +/** + * Deletes the unicode converter and releases resources associated + * with just this instance. + * Does not free up shared converter tables. + * + * @param converter the converter object to be deleted + * @see ucnv_open + * @see ucnv_openU + * @see ucnv_openCCSID + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_close(UConverter * converter); + +/** + * Fills in the output parameter, subChars, with the substitution characters + * as multiple bytes. + * If ucnv_setSubstString() set a Unicode string because the converter is + * stateful, then subChars will be an empty string. + * + * @param converter the Unicode converter + * @param subChars the subsitution characters + * @param len on input the capacity of subChars, on output the number + * of bytes copied to it + * @param err the outgoing error status code. + * If the substitution character array is too small, an + * <TT>U_INDEX_OUTOFBOUNDS_ERROR</TT> will be returned. + * @see ucnv_setSubstString + * @see ucnv_setSubstChars + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_getSubstChars(const UConverter *converter, + char *subChars, + int8_t *len, + UErrorCode *err); + +/** + * Sets the substitution chars when converting from unicode to a codepage. The + * substitution is specified as a string of 1-4 bytes, and may contain + * <TT>NULL</TT> bytes. + * The subChars must represent a single character. The caller needs to know the + * byte sequence of a valid character in the converter's charset. + * For some converters, for example some ISO 2022 variants, only single-byte + * substitution characters may be supported. + * The newer ucnv_setSubstString() function relaxes these limitations. + * + * @param converter the Unicode converter + * @param subChars the substitution character byte sequence we want set + * @param len the number of bytes in subChars + * @param err the error status code. <TT>U_INDEX_OUTOFBOUNDS_ERROR </TT> if + * len is bigger than the maximum number of bytes allowed in subchars + * @see ucnv_setSubstString + * @see ucnv_getSubstChars + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_setSubstChars(UConverter *converter, + const char *subChars, + int8_t len, + UErrorCode *err); + +/** + * Set a substitution string for converting from Unicode to a charset. + * The caller need not know the charset byte sequence for each charset. + * + * Unlike ucnv_setSubstChars() which is designed to set a charset byte sequence + * for a single character, this function takes a Unicode string with + * zero, one or more characters, and immediately verifies that the string can be + * converted to the charset. + * If not, or if the result is too long (more than 32 bytes as of ICU 3.6), + * then the function returns with an error accordingly. + * + * Also unlike ucnv_setSubstChars(), this function works for stateful charsets + * by converting on the fly at the point of substitution rather than setting + * a fixed byte sequence. + * + * @param cnv The UConverter object. + * @param s The Unicode string. + * @param length The number of UChars in s, or -1 for a NUL-terminated string. + * @param err Pointer to a standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * + * @see ucnv_setSubstChars + * @see ucnv_getSubstChars + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +ucnv_setSubstString(UConverter *cnv, + const UChar *s, + int32_t length, + UErrorCode *err); + +/** + * Fills in the output parameter, errBytes, with the error characters from the + * last failing conversion. + * + * @param converter the Unicode converter + * @param errBytes the codepage bytes which were in error + * @param len on input the capacity of errBytes, on output the number of + * bytes which were copied to it + * @param err the error status code. + * If the substitution character array is too small, an + * <TT>U_INDEX_OUTOFBOUNDS_ERROR</TT> will be returned. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_getInvalidChars(const UConverter *converter, + char *errBytes, + int8_t *len, + UErrorCode *err); + +/** + * Fills in the output parameter, errChars, with the error characters from the + * last failing conversion. + * + * @param converter the Unicode converter + * @param errUChars the UChars which were in error + * @param len on input the capacity of errUChars, on output the number of + * UChars which were copied to it + * @param err the error status code. + * If the substitution character array is too small, an + * <TT>U_INDEX_OUTOFBOUNDS_ERROR</TT> will be returned. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_getInvalidUChars(const UConverter *converter, + UChar *errUChars, + int8_t *len, + UErrorCode *err); + +/** + * Resets the state of a converter to the default state. This is used + * in the case of an error, to restart a conversion from a known default state. + * It will also empty the internal output buffers. + * @param converter the Unicode converter + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_reset(UConverter *converter); + +/** + * Resets the to-Unicode part of a converter state to the default state. + * This is used in the case of an error to restart a conversion to + * Unicode to a known default state. It will also empty the internal + * output buffers used for the conversion to Unicode codepoints. + * @param converter the Unicode converter + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_resetToUnicode(UConverter *converter); + +/** + * Resets the from-Unicode part of a converter state to the default state. + * This is used in the case of an error to restart a conversion from + * Unicode to a known default state. It will also empty the internal output + * buffers used for the conversion from Unicode codepoints. + * @param converter the Unicode converter + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_resetFromUnicode(UConverter *converter); + +/** + * Returns the maximum number of bytes that are output per UChar in conversion + * from Unicode using this converter. + * The returned number can be used with UCNV_GET_MAX_BYTES_FOR_STRING + * to calculate the size of a target buffer for conversion from Unicode. + * + * Note: Before ICU 2.8, this function did not return reliable numbers for + * some stateful converters (EBCDIC_STATEFUL, ISO-2022) and LMBCS. + * + * This number may not be the same as the maximum number of bytes per + * "conversion unit". In other words, it may not be the intuitively expected + * number of bytes per character that would be published for a charset, + * and may not fulfill any other purpose than the allocation of an output + * buffer of guaranteed sufficient size for a given input length and converter. + * + * Examples for special cases that are taken into account: + * - Supplementary code points may convert to more bytes than BMP code points. + * This function returns bytes per UChar (UTF-16 code unit), not per + * Unicode code point, for efficient buffer allocation. + * - State-shifting output (SI/SO, escapes, etc.) from stateful converters. + * - When m input UChars are converted to n output bytes, then the maximum m/n + * is taken into account. + * + * The number returned here does not take into account + * (see UCNV_GET_MAX_BYTES_FOR_STRING): + * - callbacks which output more than one charset character sequence per call, + * like escape callbacks + * - initial and final non-character bytes that are output by some converters + * (automatic BOMs, initial escape sequence, final SI, etc.) + * + * Examples for returned values: + * - SBCS charsets: 1 + * - Shift-JIS: 2 + * - UTF-16: 2 (2 per BMP, 4 per surrogate _pair_, BOM not counted) + * - UTF-8: 3 (3 per BMP, 4 per surrogate _pair_) + * - EBCDIC_STATEFUL (EBCDIC mixed SBCS/DBCS): 3 (SO + DBCS) + * - ISO-2022: 3 (always outputs UTF-8) + * - ISO-2022-JP: 6 (4-byte escape sequences + DBCS) + * - ISO-2022-CN: 8 (4-byte designator sequences + 2-byte SS2/SS3 + DBCS) + * + * @param converter The Unicode converter. + * @return The maximum number of bytes per UChar that are output by ucnv_fromUnicode(), + * to be used together with UCNV_GET_MAX_BYTES_FOR_STRING for buffer allocation. + * + * @see UCNV_GET_MAX_BYTES_FOR_STRING + * @see ucnv_getMinCharSize + * @stable ICU 2.0 + */ +U_STABLE int8_t U_EXPORT2 +ucnv_getMaxCharSize(const UConverter *converter); + +/** + * Calculates the size of a buffer for conversion from Unicode to a charset. + * The calculated size is guaranteed to be sufficient for this conversion. + * + * It takes into account initial and final non-character bytes that are output + * by some converters. + * It does not take into account callbacks which output more than one charset + * character sequence per call, like escape callbacks. + * The default (substitution) callback only outputs one charset character sequence. + * + * @param length Number of UChars to be converted. + * @param maxCharSize Return value from ucnv_getMaxCharSize() for the converter + * that will be used. + * @return Size of a buffer that will be large enough to hold the output bytes of + * converting length UChars with the converter that returned the maxCharSize. + * + * @see ucnv_getMaxCharSize + * @stable ICU 2.8 + */ +#define UCNV_GET_MAX_BYTES_FOR_STRING(length, maxCharSize) \ + (((int32_t)(length)+10)*(int32_t)(maxCharSize)) + +/** + * Returns the minimum byte length for characters in this codepage. + * This is usually either 1 or 2. + * @param converter the Unicode converter + * @return the minimum number of bytes allowed by this particular converter + * @see ucnv_getMaxCharSize + * @stable ICU 2.0 + */ +U_STABLE int8_t U_EXPORT2 +ucnv_getMinCharSize(const UConverter *converter); + +/** + * Returns the display name of the converter passed in based on the Locale + * passed in. If the locale contains no display name, the internal ASCII + * name will be filled in. + * + * @param converter the Unicode converter. + * @param displayLocale is the specific Locale we want to localised for + * @param displayName user provided buffer to be filled in + * @param displayNameCapacity size of displayName Buffer + * @param err error status code + * @return displayNameLength number of UChar needed in displayName + * @see ucnv_getName + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_getDisplayName(const UConverter *converter, + const char *displayLocale, + UChar *displayName, + int32_t displayNameCapacity, + UErrorCode *err); + +/** + * Gets the internal, canonical name of the converter (zero-terminated). + * The lifetime of the returned string will be that of the converter + * passed to this function. + * @param converter the Unicode converter + * @param err UErrorCode status + * @return the internal name of the converter + * @see ucnv_getDisplayName + * @stable ICU 2.0 + */ +U_STABLE const char * U_EXPORT2 +ucnv_getName(const UConverter *converter, UErrorCode *err); + +/** + * Gets a codepage number associated with the converter. This is not guaranteed + * to be the one used to create the converter. Some converters do not represent + * platform registered codepages and return zero for the codepage number. + * The error code fill-in parameter indicates if the codepage number + * is available. + * Does not check if the converter is <TT>NULL</TT> or if converter's data + * table is <TT>NULL</TT>. + * + * Important: The use of CCSIDs is not recommended because it is limited + * to only two platforms in principle and only one (UCNV_IBM) in the current + * ICU converter API. + * Also, CCSIDs are insufficient to identify IBM Unicode conversion tables precisely. + * For more details see ucnv_openCCSID(). + * + * @param converter the Unicode converter + * @param err the error status code. + * @return If any error occurrs, -1 will be returned otherwise, the codepage number + * will be returned + * @see ucnv_openCCSID + * @see ucnv_getPlatform + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_getCCSID(const UConverter *converter, + UErrorCode *err); + +/** + * Gets a codepage platform associated with the converter. Currently, + * only <TT>UCNV_IBM</TT> will be returned. + * Does not test if the converter is <TT>NULL</TT> or if converter's data + * table is <TT>NULL</TT>. + * @param converter the Unicode converter + * @param err the error status code. + * @return The codepage platform + * @stable ICU 2.0 + */ +U_STABLE UConverterPlatform U_EXPORT2 +ucnv_getPlatform(const UConverter *converter, + UErrorCode *err); + +/** + * Gets the type of the converter + * e.g. SBCS, MBCS, DBCS, UTF8, UTF16_BE, UTF16_LE, ISO_2022, + * EBCDIC_STATEFUL, LATIN_1 + * @param converter a valid, opened converter + * @return the type of the converter + * @stable ICU 2.0 + */ +U_STABLE UConverterType U_EXPORT2 +ucnv_getType(const UConverter * converter); + +/** + * Gets the "starter" (lead) bytes for converters of type MBCS. + * Will fill in an <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> if converter passed in + * is not MBCS. Fills in an array of type UBool, with the value of the byte + * as offset to the array. For example, if (starters[0x20] == TRUE) at return, + * it means that the byte 0x20 is a starter byte in this converter. + * Context pointers are always owned by the caller. + * + * @param converter a valid, opened converter of type MBCS + * @param starters an array of size 256 to be filled in + * @param err error status, <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> if the + * converter is not a type which can return starters. + * @see ucnv_getType + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_getStarters(const UConverter* converter, + UBool starters[256], + UErrorCode* err); + + +/** + * Selectors for Unicode sets that can be returned by ucnv_getUnicodeSet(). + * @see ucnv_getUnicodeSet + * @stable ICU 2.6 + */ +typedef enum UConverterUnicodeSet { + /** Select the set of roundtrippable Unicode code points. @stable ICU 2.6 */ + UCNV_ROUNDTRIP_SET, + /** Select the set of Unicode code points with roundtrip or fallback mappings. @draft ICU 4.0 */ + UCNV_ROUNDTRIP_AND_FALLBACK_SET, + /** Number of UConverterUnicodeSet selectors. @stable ICU 2.6 */ + UCNV_SET_COUNT +} UConverterUnicodeSet; + + +/** + * Returns the set of Unicode code points that can be converted by an ICU converter. + * + * Returns one of several kinds of set: + * + * 1. UCNV_ROUNDTRIP_SET + * + * The set of all Unicode code points that can be roundtrip-converted + * (converted without any data loss) with the converter (ucnv_fromUnicode()). + * This set will not include code points that have fallback mappings + * or are only the result of reverse fallback mappings. + * This set will also not include PUA code points with fallbacks, although + * ucnv_fromUnicode() will always uses those mappings despite ucnv_setFallback(). + * See UTR #22 "Character Mapping Markup Language" + * at http://www.unicode.org/reports/tr22/ + * + * This is useful for example for + * - checking that a string or document can be roundtrip-converted with a converter, + * without/before actually performing the conversion + * - testing if a converter can be used for text for typical text for a certain locale, + * by comparing its roundtrip set with the set of ExemplarCharacters from + * ICU's locale data or other sources + * + * 2. UCNV_ROUNDTRIP_AND_FALLBACK_SET + * + * The set of all Unicode code points that can be converted with the converter (ucnv_fromUnicode()) + * when fallbacks are turned on (see ucnv_setFallback()). + * This set includes all code points with roundtrips and fallbacks (but not reverse fallbacks). + * + * In the future, there may be more UConverterUnicodeSet choices to select + * sets with different properties. + * + * @param cnv The converter for which a set is requested. + * @param setFillIn A valid USet *. It will be cleared by this function before + * the converter's specific set is filled into the USet. + * @param whichSet A UConverterUnicodeSet selector; + * currently UCNV_ROUNDTRIP_SET is the only supported value. + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * + * @see UConverterUnicodeSet + * @see uset_open + * @see uset_close + * @stable ICU 2.6 + */ +U_STABLE void U_EXPORT2 +ucnv_getUnicodeSet(const UConverter *cnv, + USet *setFillIn, + UConverterUnicodeSet whichSet, + UErrorCode *pErrorCode); + +/** + * Gets the current calback function used by the converter when an illegal + * or invalid codepage sequence is found. + * Context pointers are always owned by the caller. + * + * @param converter the unicode converter + * @param action fillin: returns the callback function pointer + * @param context fillin: returns the callback's private void* context + * @see ucnv_setToUCallBack + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_getToUCallBack (const UConverter * converter, + UConverterToUCallback *action, + const void **context); + +/** + * Gets the current callback function used by the converter when illegal + * or invalid Unicode sequence is found. + * Context pointers are always owned by the caller. + * + * @param converter the unicode converter + * @param action fillin: returns the callback function pointer + * @param context fillin: returns the callback's private void* context + * @see ucnv_setFromUCallBack + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_getFromUCallBack (const UConverter * converter, + UConverterFromUCallback *action, + const void **context); + +/** + * Changes the callback function used by the converter when + * an illegal or invalid sequence is found. + * Context pointers are always owned by the caller. + * Predefined actions and contexts can be found in the ucnv_err.h header. + * + * @param converter the unicode converter + * @param newAction the new callback function + * @param newContext the new toUnicode callback context pointer. This can be NULL. + * @param oldAction fillin: returns the old callback function pointer. This can be NULL. + * @param oldContext fillin: returns the old callback's private void* context. This can be NULL. + * @param err The error code status + * @see ucnv_getToUCallBack + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_setToUCallBack (UConverter * converter, + UConverterToUCallback newAction, + const void* newContext, + UConverterToUCallback *oldAction, + const void** oldContext, + UErrorCode * err); + +/** + * Changes the current callback function used by the converter when + * an illegal or invalid sequence is found. + * Context pointers are always owned by the caller. + * Predefined actions and contexts can be found in the ucnv_err.h header. + * + * @param converter the unicode converter + * @param newAction the new callback function + * @param newContext the new fromUnicode callback context pointer. This can be NULL. + * @param oldAction fillin: returns the old callback function pointer. This can be NULL. + * @param oldContext fillin: returns the old callback's private void* context. This can be NULL. + * @param err The error code status + * @see ucnv_getFromUCallBack + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_setFromUCallBack (UConverter * converter, + UConverterFromUCallback newAction, + const void *newContext, + UConverterFromUCallback *oldAction, + const void **oldContext, + UErrorCode * err); + +/** + * Converts an array of unicode characters to an array of codepage + * characters. This function is optimized for converting a continuous + * stream of data in buffer-sized chunks, where the entire source and + * target does not fit in available buffers. + * + * The source pointer is an in/out parameter. It starts out pointing where the + * conversion is to begin, and ends up pointing after the last UChar consumed. + * + * Target similarly starts out pointer at the first available byte in the output + * buffer, and ends up pointing after the last byte written to the output. + * + * The converter always attempts to consume the entire source buffer, unless + * (1.) the target buffer is full, or (2.) a failing error is returned from the + * current callback function. When a successful error status has been + * returned, it means that all of the source buffer has been + * consumed. At that point, the caller should reset the source and + * sourceLimit pointers to point to the next chunk. + * + * At the end of the stream (flush==TRUE), the input is completely consumed + * when *source==sourceLimit and no error code is set. + * The converter object is then automatically reset by this function. + * (This means that a converter need not be reset explicitly between data + * streams if it finishes the previous stream without errors.) + * + * This is a <I>stateful</I> conversion. Additionally, even when all source data has + * been consumed, some data may be in the converters' internal state. + * Call this function repeatedly, updating the target pointers with + * the next empty chunk of target in case of a + * <TT>U_BUFFER_OVERFLOW_ERROR</TT>, and updating the source pointers + * with the next chunk of source when a successful error status is + * returned, until there are no more chunks of source data. + * @param converter the Unicode converter + * @param target I/O parameter. Input : Points to the beginning of the buffer to copy + * codepage characters to. Output : points to after the last codepage character copied + * to <TT>target</TT>. + * @param targetLimit the pointer just after last of the <TT>target</TT> buffer + * @param source I/O parameter, pointer to pointer to the source Unicode character buffer. + * @param sourceLimit the pointer just after the last of the source buffer + * @param offsets if NULL is passed, nothing will happen to it, otherwise it needs to have the same number + * of allocated cells as <TT>target</TT>. Will fill in offsets from target to source pointer + * e.g: <TT>offsets[3]</TT> is equal to 6, it means that the <TT>target[3]</TT> was a result of transcoding <TT>source[6]</TT> + * For output data carried across calls, and other data without a specific source character + * (such as from escape sequences or callbacks) -1 will be placed for offsets. + * @param flush set to <TT>TRUE</TT> if the current source buffer is the last available + * chunk of the source, <TT>FALSE</TT> otherwise. Note that if a failing status is returned, + * this function may have to be called multiple times with flush set to <TT>TRUE</TT> until + * the source buffer is consumed. + * @param err the error status. <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> will be set if the + * converter is <TT>NULL</TT>. + * <code>U_BUFFER_OVERFLOW_ERROR</code> will be set if the target is full and there is + * still data to be written to the target. + * @see ucnv_fromUChars + * @see ucnv_convert + * @see ucnv_getMinCharSize + * @see ucnv_setToUCallBack + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_fromUnicode (UConverter * converter, + char **target, + const char *targetLimit, + const UChar ** source, + const UChar * sourceLimit, + int32_t* offsets, + UBool flush, + UErrorCode * err); + +/** + * Converts a buffer of codepage bytes into an array of unicode UChars + * characters. This function is optimized for converting a continuous + * stream of data in buffer-sized chunks, where the entire source and + * target does not fit in available buffers. + * + * The source pointer is an in/out parameter. It starts out pointing where the + * conversion is to begin, and ends up pointing after the last byte of source consumed. + * + * Target similarly starts out pointer at the first available UChar in the output + * buffer, and ends up pointing after the last UChar written to the output. + * It does NOT necessarily keep UChar sequences together. + * + * The converter always attempts to consume the entire source buffer, unless + * (1.) the target buffer is full, or (2.) a failing error is returned from the + * current callback function. When a successful error status has been + * returned, it means that all of the source buffer has been + * consumed. At that point, the caller should reset the source and + * sourceLimit pointers to point to the next chunk. + * + * At the end of the stream (flush==TRUE), the input is completely consumed + * when *source==sourceLimit and no error code is set + * The converter object is then automatically reset by this function. + * (This means that a converter need not be reset explicitly between data + * streams if it finishes the previous stream without errors.) + * + * This is a <I>stateful</I> conversion. Additionally, even when all source data has + * been consumed, some data may be in the converters' internal state. + * Call this function repeatedly, updating the target pointers with + * the next empty chunk of target in case of a + * <TT>U_BUFFER_OVERFLOW_ERROR</TT>, and updating the source pointers + * with the next chunk of source when a successful error status is + * returned, until there are no more chunks of source data. + * @param converter the Unicode converter + * @param target I/O parameter. Input : Points to the beginning of the buffer to copy + * UChars into. Output : points to after the last UChar copied. + * @param targetLimit the pointer just after the end of the <TT>target</TT> buffer + * @param source I/O parameter, pointer to pointer to the source codepage buffer. + * @param sourceLimit the pointer to the byte after the end of the source buffer + * @param offsets if NULL is passed, nothing will happen to it, otherwise it needs to have the same number + * of allocated cells as <TT>target</TT>. Will fill in offsets from target to source pointer + * e.g: <TT>offsets[3]</TT> is equal to 6, it means that the <TT>target[3]</TT> was a result of transcoding <TT>source[6]</TT> + * For output data carried across calls, and other data without a specific source character + * (such as from escape sequences or callbacks) -1 will be placed for offsets. + * @param flush set to <TT>TRUE</TT> if the current source buffer is the last available + * chunk of the source, <TT>FALSE</TT> otherwise. Note that if a failing status is returned, + * this function may have to be called multiple times with flush set to <TT>TRUE</TT> until + * the source buffer is consumed. + * @param err the error status. <TT>U_ILLEGAL_ARGUMENT_ERROR</TT> will be set if the + * converter is <TT>NULL</TT>. + * <code>U_BUFFER_OVERFLOW_ERROR</code> will be set if the target is full and there is + * still data to be written to the target. + * @see ucnv_fromUChars + * @see ucnv_convert + * @see ucnv_getMinCharSize + * @see ucnv_setFromUCallBack + * @see ucnv_getNextUChar + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_toUnicode(UConverter *converter, + UChar **target, + const UChar *targetLimit, + const char **source, + const char *sourceLimit, + int32_t *offsets, + UBool flush, + UErrorCode *err); + +/** + * Convert the Unicode string into a codepage string using an existing UConverter. + * The output string is NUL-terminated if possible. + * + * This function is a more convenient but less powerful version of ucnv_fromUnicode(). + * It is only useful for whole strings, not for streaming conversion. + * + * The maximum output buffer capacity required (barring output from callbacks) will be + * UCNV_GET_MAX_BYTES_FOR_STRING(srcLength, ucnv_getMaxCharSize(cnv)). + * + * @param cnv the converter object to be used (ucnv_resetFromUnicode() will be called) + * @param src the input Unicode string + * @param srcLength the input string length, or -1 if NUL-terminated + * @param dest destination string buffer, can be NULL if destCapacity==0 + * @param destCapacity the number of chars available at dest + * @param pErrorCode normal ICU error code; + * common error codes that may be set by this function include + * U_BUFFER_OVERFLOW_ERROR, U_STRING_NOT_TERMINATED_WARNING, + * U_ILLEGAL_ARGUMENT_ERROR, and conversion errors + * @return the length of the output string, not counting the terminating NUL; + * if the length is greater than destCapacity, then the string will not fit + * and a buffer of the indicated length would need to be passed in + * @see ucnv_fromUnicode + * @see ucnv_convert + * @see UCNV_GET_MAX_BYTES_FOR_STRING + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_fromUChars(UConverter *cnv, + char *dest, int32_t destCapacity, + const UChar *src, int32_t srcLength, + UErrorCode *pErrorCode); + +/** + * Convert the codepage string into a Unicode string using an existing UConverter. + * The output string is NUL-terminated if possible. + * + * This function is a more convenient but less powerful version of ucnv_toUnicode(). + * It is only useful for whole strings, not for streaming conversion. + * + * The maximum output buffer capacity required (barring output from callbacks) will be + * 2*srcLength (each char may be converted into a surrogate pair). + * + * @param cnv the converter object to be used (ucnv_resetToUnicode() will be called) + * @param src the input codepage string + * @param srcLength the input string length, or -1 if NUL-terminated + * @param dest destination string buffer, can be NULL if destCapacity==0 + * @param destCapacity the number of UChars available at dest + * @param pErrorCode normal ICU error code; + * common error codes that may be set by this function include + * U_BUFFER_OVERFLOW_ERROR, U_STRING_NOT_TERMINATED_WARNING, + * U_ILLEGAL_ARGUMENT_ERROR, and conversion errors + * @return the length of the output string, not counting the terminating NUL; + * if the length is greater than destCapacity, then the string will not fit + * and a buffer of the indicated length would need to be passed in + * @see ucnv_toUnicode + * @see ucnv_convert + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_toUChars(UConverter *cnv, + UChar *dest, int32_t destCapacity, + const char *src, int32_t srcLength, + UErrorCode *pErrorCode); + +/** + * Convert a codepage buffer into Unicode one character at a time. + * The input is completely consumed when the U_INDEX_OUTOFBOUNDS_ERROR is set. + * + * Advantage compared to ucnv_toUnicode() or ucnv_toUChars(): + * - Faster for small amounts of data, for most converters, e.g., + * US-ASCII, ISO-8859-1, UTF-8/16/32, and most "normal" charsets. + * (For complex converters, e.g., SCSU, UTF-7 and ISO 2022 variants, + * it uses ucnv_toUnicode() internally.) + * - Convenient. + * + * Limitations compared to ucnv_toUnicode(): + * - Always assumes flush=TRUE. + * This makes ucnv_getNextUChar() unsuitable for "streaming" conversion, + * that is, for where the input is supplied in multiple buffers, + * because ucnv_getNextUChar() will assume the end of the input at the end + * of the first buffer. + * - Does not provide offset output. + * + * It is possible to "mix" ucnv_getNextUChar() and ucnv_toUnicode() because + * ucnv_getNextUChar() uses the current state of the converter + * (unlike ucnv_toUChars() which always resets first). + * However, if ucnv_getNextUChar() is called after ucnv_toUnicode() + * stopped in the middle of a character sequence (with flush=FALSE), + * then ucnv_getNextUChar() will always use the slower ucnv_toUnicode() + * internally until the next character boundary. + * (This is new in ICU 2.6. In earlier releases, ucnv_getNextUChar() had to + * start at a character boundary.) + * + * Instead of using ucnv_getNextUChar(), it is recommended + * to convert using ucnv_toUnicode() or ucnv_toUChars() + * and then iterate over the text using U16_NEXT() or a UCharIterator (uiter.h) + * or a C++ CharacterIterator or similar. + * This allows streaming conversion and offset output, for example. + * + * <p>Handling of surrogate pairs and supplementary-plane code points:<br> + * There are two different kinds of codepages that provide mappings for surrogate characters: + * <ul> + * <li>Codepages like UTF-8, UTF-32, and GB 18030 provide direct representations for Unicode + * code points U+10000-U+10ffff as well as for single surrogates U+d800-U+dfff. + * Each valid sequence will result in exactly one returned code point. + * If a sequence results in a single surrogate, then that will be returned + * by itself, even if a neighboring sequence encodes the matching surrogate.</li> + * <li>Codepages like SCSU and LMBCS (and UTF-16) provide direct representations only for BMP code points + * including surrogates. Code points in supplementary planes are represented with + * two sequences, each encoding a surrogate. + * For these codepages, matching pairs of surrogates will be combined into single + * code points for returning from this function. + * (Note that SCSU is actually a mix of these codepage types.)</li> + * </ul></p> + * + * @param converter an open UConverter + * @param source the address of a pointer to the codepage buffer, will be + * updated to point after the bytes consumed in the conversion call. + * @param sourceLimit points to the end of the input buffer + * @param err fills in error status (see ucnv_toUnicode) + * <code>U_INDEX_OUTOFBOUNDS_ERROR</code> will be set if the input + * is empty or does not convert to any output (e.g.: pure state-change + * codes SI/SO, escape sequences for ISO 2022, + * or if the callback did not output anything, ...). + * This function will not set a <code>U_BUFFER_OVERFLOW_ERROR</code> because + * the "buffer" is the return code. However, there might be subsequent output + * stored in the converter object + * that will be returned in following calls to this function. + * @return a UChar32 resulting from the partial conversion of source + * @see ucnv_toUnicode + * @see ucnv_toUChars + * @see ucnv_convert + * @stable ICU 2.0 + */ +U_STABLE UChar32 U_EXPORT2 +ucnv_getNextUChar(UConverter * converter, + const char **source, + const char * sourceLimit, + UErrorCode * err); + +/** + * Convert from one external charset to another using two existing UConverters. + * Internally, two conversions - ucnv_toUnicode() and ucnv_fromUnicode() - + * are used, "pivoting" through 16-bit Unicode. + * + * Important: For streaming conversion (multiple function calls for successive + * parts of a text stream), the caller must provide a pivot buffer explicitly, + * and must preserve the pivot buffer and associated pointers from one + * call to another. (The buffer may be moved if its contents and the relative + * pointer positions are preserved.) + * + * There is a similar function, ucnv_convert(), + * which has the following limitations: + * - it takes charset names, not converter objects, so that + * - two converters are opened for each call + * - only single-string conversion is possible, not streaming operation + * - it does not provide enough information to find out, + * in case of failure, whether the toUnicode or + * the fromUnicode conversion failed + * + * By contrast, ucnv_convertEx() + * - takes UConverter parameters instead of charset names + * - fully exposes the pivot buffer for streaming conversion and complete error handling + * + * ucnv_convertEx() also provides further convenience: + * - an option to reset the converters at the beginning + * (if reset==TRUE, see parameters; + * also sets *pivotTarget=*pivotSource=pivotStart) + * - allow NUL-terminated input + * (only a single NUL byte, will not work for charsets with multi-byte NULs) + * (if sourceLimit==NULL, see parameters) + * - terminate with a NUL on output + * (only a single NUL byte, not useful for charsets with multi-byte NULs), + * or set U_STRING_NOT_TERMINATED_WARNING if the output exactly fills + * the target buffer + * - the pivot buffer can be provided internally; + * possible only for whole-string conversion, not streaming conversion; + * in this case, the caller will not be able to get details about where an + * error occurred + * (if pivotStart==NULL, see below) + * + * The function returns when one of the following is true: + * - the entire source text has been converted successfully to the target buffer + * - a target buffer overflow occurred (U_BUFFER_OVERFLOW_ERROR) + * - a conversion error occurred + * (other U_FAILURE(), see description of pErrorCode) + * + * Limitation compared to the direct use of + * ucnv_fromUnicode() and ucnv_toUnicode(): + * ucnv_convertEx() does not provide offset information. + * + * Limitation compared to ucnv_fromUChars() and ucnv_toUChars(): + * ucnv_convertEx() does not support preflighting directly. + * + * Sample code for converting a single string from + * one external charset to UTF-8, ignoring the location of errors: + * + * \code + * int32_t + * myToUTF8(UConverter *cnv, + * const char *s, int32_t length, + * char *u8, int32_t capacity, + * UErrorCode *pErrorCode) { + * UConverter *utf8Cnv; + * char *target; + * + * if(U_FAILURE(*pErrorCode)) { + * return 0; + * } + * + * utf8Cnv=myGetCachedUTF8Converter(pErrorCode); + * if(U_FAILURE(*pErrorCode)) { + * return 0; + * } + * + * if(length<0) { + * length=strlen(s); + * } + * target=u8; + * ucnv_convertEx(cnv, utf8Cnv, + * &target, u8+capacity, + * &s, s+length, + * NULL, NULL, NULL, NULL, + * TRUE, TRUE, + * pErrorCode); + * + * myReleaseCachedUTF8Converter(utf8Cnv); + * + * // return the output string length, but without preflighting + * return (int32_t)(target-u8); + * } + * \endcode + * + * @param targetCnv Output converter, used to convert from the UTF-16 pivot + * to the target using ucnv_fromUnicode(). + * @param sourceCnv Input converter, used to convert from the source to + * the UTF-16 pivot using ucnv_toUnicode(). + * @param target I/O parameter, same as for ucnv_fromUChars(). + * Input: *target points to the beginning of the target buffer. + * Output: *target points to the first unit after the last char written. + * @param targetLimit Pointer to the first unit after the target buffer. + * @param source I/O parameter, same as for ucnv_toUChars(). + * Input: *source points to the beginning of the source buffer. + * Output: *source points to the first unit after the last char read. + * @param sourceLimit Pointer to the first unit after the source buffer. + * @param pivotStart Pointer to the UTF-16 pivot buffer. If pivotStart==NULL, + * then an internal buffer is used and the other pivot + * arguments are ignored and can be NULL as well. + * @param pivotSource I/O parameter, same as source in ucnv_fromUChars() for + * conversion from the pivot buffer to the target buffer. + * @param pivotTarget I/O parameter, same as target in ucnv_toUChars() for + * conversion from the source buffer to the pivot buffer. + * It must be pivotStart<=*pivotSource<=*pivotTarget<=pivotLimit + * and pivotStart<pivotLimit (unless pivotStart==NULL). + * @param pivotLimit Pointer to the first unit after the pivot buffer. + * @param reset If TRUE, then ucnv_resetToUnicode(sourceCnv) and + * ucnv_resetFromUnicode(targetCnv) are called, and the + * pivot pointers are reset (*pivotTarget=*pivotSource=pivotStart). + * @param flush If true, indicates the end of the input. + * Passed directly to ucnv_toUnicode(), and carried over to + * ucnv_fromUnicode() when the source is empty as well. + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * U_BUFFER_OVERFLOW_ERROR always refers to the target buffer + * because overflows into the pivot buffer are handled internally. + * Other conversion errors are from the source-to-pivot + * conversion if *pivotSource==pivotStart, otherwise from + * the pivot-to-target conversion. + * + * @see ucnv_convert + * @see ucnv_fromAlgorithmic + * @see ucnv_toAlgorithmic + * @see ucnv_fromUnicode + * @see ucnv_toUnicode + * @see ucnv_fromUChars + * @see ucnv_toUChars + * @stable ICU 2.6 + */ +U_STABLE void U_EXPORT2 +ucnv_convertEx(UConverter *targetCnv, UConverter *sourceCnv, + char **target, const char *targetLimit, + const char **source, const char *sourceLimit, + UChar *pivotStart, UChar **pivotSource, + UChar **pivotTarget, const UChar *pivotLimit, + UBool reset, UBool flush, + UErrorCode *pErrorCode); + +/** + * Convert from one external charset to another. + * Internally, two converters are opened according to the name arguments, + * then the text is converted to and from the 16-bit Unicode "pivot" + * using ucnv_convertEx(), then the converters are closed again. + * + * This is a convenience function, not an efficient way to convert a lot of text: + * ucnv_convert() + * - takes charset names, not converter objects, so that + * - two converters are opened for each call + * - only single-string conversion is possible, not streaming operation + * - does not provide enough information to find out, + * in case of failure, whether the toUnicode or + * the fromUnicode conversion failed + * - allows NUL-terminated input + * (only a single NUL byte, will not work for charsets with multi-byte NULs) + * (if sourceLength==-1, see parameters) + * - terminate with a NUL on output + * (only a single NUL byte, not useful for charsets with multi-byte NULs), + * or set U_STRING_NOT_TERMINATED_WARNING if the output exactly fills + * the target buffer + * - a pivot buffer is provided internally + * + * The function returns when one of the following is true: + * - the entire source text has been converted successfully to the target buffer + * and either the target buffer is terminated with a single NUL byte + * or the error code is set to U_STRING_NOT_TERMINATED_WARNING + * - a target buffer overflow occurred (U_BUFFER_OVERFLOW_ERROR) + * and the full output string length is returned ("preflighting") + * - a conversion error occurred + * (other U_FAILURE(), see description of pErrorCode) + * + * @param toConverterName The name of the converter that is used to convert + * from the UTF-16 pivot buffer to the target. + * @param fromConverterName The name of the converter that is used to convert + * from the source to the UTF-16 pivot buffer. + * @param target Pointer to the output buffer. + * @param targetCapacity Capacity of the target, in bytes. + * @param source Pointer to the input buffer. + * @param sourceLength Length of the input text, in bytes, or -1 for NUL-terminated input. + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Length of the complete output text in bytes, even if it exceeds the targetCapacity + * and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see ucnv_convertEx + * @see ucnv_fromAlgorithmic + * @see ucnv_toAlgorithmic + * @see ucnv_fromUnicode + * @see ucnv_toUnicode + * @see ucnv_fromUChars + * @see ucnv_toUChars + * @see ucnv_getNextUChar + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_convert(const char *toConverterName, + const char *fromConverterName, + char *target, + int32_t targetCapacity, + const char *source, + int32_t sourceLength, + UErrorCode *pErrorCode); + +/** + * Convert from one external charset to another. + * Internally, the text is converted to and from the 16-bit Unicode "pivot" + * using ucnv_convertEx(). ucnv_toAlgorithmic() works exactly like ucnv_convert() + * except that the two converters need not be looked up and opened completely. + * + * The source-to-pivot conversion uses the cnv converter parameter. + * The pivot-to-target conversion uses a purely algorithmic converter + * according to the specified type, e.g., UCNV_UTF8 for a UTF-8 converter. + * + * Internally, the algorithmic converter is opened and closed for each + * function call, which is more efficient than using the public ucnv_open() + * but somewhat less efficient than only resetting an existing converter + * and using ucnv_convertEx(). + * + * This function is more convenient than ucnv_convertEx() for single-string + * conversions, especially when "preflighting" is desired (returning the length + * of the complete output even if it does not fit into the target buffer; + * see the User Guide Strings chapter). See ucnv_convert() for details. + * + * @param algorithmicType UConverterType constant identifying the desired target + * charset as a purely algorithmic converter. + * Those are converters for Unicode charsets like + * UTF-8, BOCU-1, SCSU, UTF-7, IMAP-mailbox-name, etc., + * as well as US-ASCII and ISO-8859-1. + * @param cnv The converter that is used to convert + * from the source to the UTF-16 pivot buffer. + * @param target Pointer to the output buffer. + * @param targetCapacity Capacity of the target, in bytes. + * @param source Pointer to the input buffer. + * @param sourceLength Length of the input text, in bytes + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Length of the complete output text in bytes, even if it exceeds the targetCapacity + * and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see ucnv_fromAlgorithmic + * @see ucnv_convert + * @see ucnv_convertEx + * @see ucnv_fromUnicode + * @see ucnv_toUnicode + * @see ucnv_fromUChars + * @see ucnv_toUChars + * @stable ICU 2.6 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_toAlgorithmic(UConverterType algorithmicType, + UConverter *cnv, + char *target, int32_t targetCapacity, + const char *source, int32_t sourceLength, + UErrorCode *pErrorCode); + +/** + * Convert from one external charset to another. + * Internally, the text is converted to and from the 16-bit Unicode "pivot" + * using ucnv_convertEx(). ucnv_fromAlgorithmic() works exactly like ucnv_convert() + * except that the two converters need not be looked up and opened completely. + * + * The source-to-pivot conversion uses a purely algorithmic converter + * according to the specified type, e.g., UCNV_UTF8 for a UTF-8 converter. + * The pivot-to-target conversion uses the cnv converter parameter. + * + * Internally, the algorithmic converter is opened and closed for each + * function call, which is more efficient than using the public ucnv_open() + * but somewhat less efficient than only resetting an existing converter + * and using ucnv_convertEx(). + * + * This function is more convenient than ucnv_convertEx() for single-string + * conversions, especially when "preflighting" is desired (returning the length + * of the complete output even if it does not fit into the target buffer; + * see the User Guide Strings chapter). See ucnv_convert() for details. + * + * @param cnv The converter that is used to convert + * from the UTF-16 pivot buffer to the target. + * @param algorithmicType UConverterType constant identifying the desired source + * charset as a purely algorithmic converter. + * Those are converters for Unicode charsets like + * UTF-8, BOCU-1, SCSU, UTF-7, IMAP-mailbox-name, etc., + * as well as US-ASCII and ISO-8859-1. + * @param target Pointer to the output buffer. + * @param targetCapacity Capacity of the target, in bytes. + * @param source Pointer to the input buffer. + * @param sourceLength Length of the input text, in bytes + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Length of the complete output text in bytes, even if it exceeds the targetCapacity + * and a U_BUFFER_OVERFLOW_ERROR is set. + * + * @see ucnv_fromAlgorithmic + * @see ucnv_convert + * @see ucnv_convertEx + * @see ucnv_fromUnicode + * @see ucnv_toUnicode + * @see ucnv_fromUChars + * @see ucnv_toUChars + * @stable ICU 2.6 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_fromAlgorithmic(UConverter *cnv, + UConverterType algorithmicType, + char *target, int32_t targetCapacity, + const char *source, int32_t sourceLength, + UErrorCode *pErrorCode); + +/** + * Frees up memory occupied by unused, cached converter shared data. + * + * @return the number of cached converters successfully deleted + * @see ucnv_close + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_flushCache(void); + +/** + * Returns the number of available converters, as per the alias file. + * + * @return the number of available converters + * @see ucnv_getAvailableName + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_countAvailable(void); + +/** + * Gets the canonical converter name of the specified converter from a list of + * all available converters contaied in the alias file. All converters + * in this list can be opened. + * + * @param n the index to a converter available on the system (in the range <TT>[0..ucnv_countAvaiable()]</TT>) + * @return a pointer a string (library owned), or <TT>NULL</TT> if the index is out of bounds. + * @see ucnv_countAvailable + * @stable ICU 2.0 + */ +U_STABLE const char* U_EXPORT2 +ucnv_getAvailableName(int32_t n); + +/** + * Returns a UEnumeration to enumerate all of the canonical converter + * names, as per the alias file, regardless of the ability to open each + * converter. + * + * @return A UEnumeration object for getting all the recognized canonical + * converter names. + * @see ucnv_getAvailableName + * @see uenum_close + * @see uenum_next + * @stable ICU 2.4 + */ +U_STABLE UEnumeration * U_EXPORT2 +ucnv_openAllNames(UErrorCode *pErrorCode); + +/** + * Gives the number of aliases for a given converter or alias name. + * If the alias is ambiguous, then the preferred converter is used + * and the status is set to U_AMBIGUOUS_ALIAS_WARNING. + * This method only enumerates the listed entries in the alias file. + * @param alias alias name + * @param pErrorCode error status + * @return number of names on alias list for given alias + * @stable ICU 2.0 + */ +U_STABLE uint16_t U_EXPORT2 +ucnv_countAliases(const char *alias, UErrorCode *pErrorCode); + +/** + * Gives the name of the alias at given index of alias list. + * This method only enumerates the listed entries in the alias file. + * If the alias is ambiguous, then the preferred converter is used + * and the status is set to U_AMBIGUOUS_ALIAS_WARNING. + * @param alias alias name + * @param n index in alias list + * @param pErrorCode result of operation + * @return returns the name of the alias at given index + * @see ucnv_countAliases + * @stable ICU 2.0 + */ +U_STABLE const char * U_EXPORT2 +ucnv_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode); + +/** + * Fill-up the list of alias names for the given alias. + * This method only enumerates the listed entries in the alias file. + * If the alias is ambiguous, then the preferred converter is used + * and the status is set to U_AMBIGUOUS_ALIAS_WARNING. + * @param alias alias name + * @param aliases fill-in list, aliases is a pointer to an array of + * <code>ucnv_countAliases()</code> string-pointers + * (<code>const char *</code>) that will be filled in. + * The strings themselves are owned by the library. + * @param pErrorCode result of operation + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_getAliases(const char *alias, const char **aliases, UErrorCode *pErrorCode); + +/** + * Return a new UEnumeration object for enumerating all the + * alias names for a given converter that are recognized by a standard. + * This method only enumerates the listed entries in the alias file. + * The convrtrs.txt file can be modified to change the results of + * this function. + * The first result in this list is the same result given by + * <code>ucnv_getStandardName</code>, which is the default alias for + * the specified standard name. The returned object must be closed with + * <code>uenum_close</code> when you are done with the object. + * + * @param convName original converter name + * @param standard name of the standard governing the names; MIME and IANA + * are such standards + * @param pErrorCode The error code + * @return A UEnumeration object for getting all aliases that are recognized + * by a standard. If any of the parameters are invalid, NULL + * is returned. + * @see ucnv_getStandardName + * @see uenum_close + * @see uenum_next + * @stable ICU 2.2 + */ +U_STABLE UEnumeration * U_EXPORT2 +ucnv_openStandardNames(const char *convName, + const char *standard, + UErrorCode *pErrorCode); + +/** + * Gives the number of standards associated to converter names. + * @return number of standards + * @stable ICU 2.0 + */ +U_STABLE uint16_t U_EXPORT2 +ucnv_countStandards(void); + +/** + * Gives the name of the standard at given index of standard list. + * @param n index in standard list + * @param pErrorCode result of operation + * @return returns the name of the standard at given index. Owned by the library. + * @stable ICU 2.0 + */ +U_STABLE const char * U_EXPORT2 +ucnv_getStandard(uint16_t n, UErrorCode *pErrorCode); + +/** + * Returns a standard name for a given converter name. + * <p> + * Example alias table:<br> + * conv alias1 { STANDARD1 } alias2 { STANDARD1* } + * <p> + * Result of ucnv_getStandardName("conv", "STANDARD1") from example + * alias table:<br> + * <b>"alias2"</b> + * + * @param name original converter name + * @param standard name of the standard governing the names; MIME and IANA + * are such standards + * @param pErrorCode result of operation + * @return returns the standard converter name; + * if a standard converter name cannot be determined, + * then <code>NULL</code> is returned. Owned by the library. + * @stable ICU 2.0 + */ +U_STABLE const char * U_EXPORT2 +ucnv_getStandardName(const char *name, const char *standard, UErrorCode *pErrorCode); + +/** + * This function will return the internal canonical converter name of the + * tagged alias. This is the opposite of ucnv_openStandardNames, which + * returns the tagged alias given the canonical name. + * <p> + * Example alias table:<br> + * conv alias1 { STANDARD1 } alias2 { STANDARD1* } + * <p> + * Result of ucnv_getStandardName("alias1", "STANDARD1") from example + * alias table:<br> + * <b>"conv"</b> + * + * @return returns the canonical converter name; + * if a standard or alias name cannot be determined, + * then <code>NULL</code> is returned. The returned string is + * owned by the library. + * @see ucnv_getStandardName + * @stable ICU 2.4 + */ +U_STABLE const char * U_EXPORT2 +ucnv_getCanonicalName(const char *alias, const char *standard, UErrorCode *pErrorCode); + +/** + * Returns the current default converter name. If you want to open + * a default converter, you do not need to use this function. + * It is faster if you pass a NULL argument to ucnv_open the + * default converter. + * + * @return returns the current default converter name. + * Storage owned by the library + * @see ucnv_setDefaultName + * @stable ICU 2.0 + */ +U_STABLE const char * U_EXPORT2 +ucnv_getDefaultName(void); + +/** + * This function is not thread safe. DO NOT call this function when ANY ICU + * function is being used from more than one thread! This function sets the + * current default converter name. If this function needs to be called, it + * should be called during application initialization. Most of the time, the + * results from ucnv_getDefaultName() or ucnv_open with a NULL string argument + * is sufficient for your application. + * @param name the converter name to be the default (must be known by ICU). + * @see ucnv_getDefaultName + * @system + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_setDefaultName(const char *name); + +/** + * Fixes the backslash character mismapping. For example, in SJIS, the backslash + * character in the ASCII portion is also used to represent the yen currency sign. + * When mapping from Unicode character 0x005C, it's unclear whether to map the + * character back to yen or backslash in SJIS. This function will take the input + * buffer and replace all the yen sign characters with backslash. This is necessary + * when the user tries to open a file with the input buffer on Windows. + * This function will test the converter to see whether such mapping is + * required. You can sometimes avoid using this function by using the correct version + * of Shift-JIS. + * + * @param cnv The converter representing the target codepage. + * @param source the input buffer to be fixed + * @param sourceLen the length of the input buffer + * @see ucnv_isAmbiguous + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_fixFileSeparator(const UConverter *cnv, UChar *source, int32_t sourceLen); + +/** + * Determines if the converter contains ambiguous mappings of the same + * character or not. + * @param cnv the converter to be tested + * @return TRUE if the converter contains ambiguous mapping of the same + * character, FALSE otherwise. + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +ucnv_isAmbiguous(const UConverter *cnv); + +/** + * Sets the converter to use fallback mappings or not. + * Regardless of this flag, the converter will always use + * fallbacks from Unicode Private Use code points, as well as + * reverse fallbacks (to Unicode). + * For details see ".ucm File Format" + * in the Conversion Data chapter of the ICU User Guide: + * http://www.icu-project.org/userguide/conversion-data.html#ucmformat + * + * @param cnv The converter to set the fallback mapping usage on. + * @param usesFallback TRUE if the user wants the converter to take advantage of the fallback + * mapping, FALSE otherwise. + * @stable ICU 2.0 + * @see ucnv_usesFallback + */ +U_STABLE void U_EXPORT2 +ucnv_setFallback(UConverter *cnv, UBool usesFallback); + +/** + * Determines if the converter uses fallback mappings or not. + * This flag has restrictions, see ucnv_setFallback(). + * + * @param cnv The converter to be tested + * @return TRUE if the converter uses fallback, FALSE otherwise. + * @stable ICU 2.0 + * @see ucnv_setFallback + */ +U_STABLE UBool U_EXPORT2 +ucnv_usesFallback(const UConverter *cnv); + +/** + * Detects Unicode signature byte sequences at the start of the byte stream + * and returns the charset name of the indicated Unicode charset. + * NULL is returned when no Unicode signature is recognized. + * The number of bytes in the signature is output as well. + * + * The caller can ucnv_open() a converter using the charset name. + * The first code unit (UChar) from the start of the stream will be U+FEFF + * (the Unicode BOM/signature character) and can usually be ignored. + * + * For most Unicode charsets it is also possible to ignore the indicated + * number of initial stream bytes and start converting after them. + * However, there are stateful Unicode charsets (UTF-7 and BOCU-1) for which + * this will not work. Therefore, it is best to ignore the first output UChar + * instead of the input signature bytes. + * <p> + * Usage: + * @code + * UErrorCode err = U_ZERO_ERROR; + * char input[] = { '\xEF','\xBB', '\xBF','\x41','\x42','\x43' }; + * int32_t signatureLength = 0; + * char *encoding = ucnv_detectUnicodeSignature(input,sizeof(input),&signatureLength,&err); + * UConverter *conv = NULL; + * UChar output[100]; + * UChar *target = output, *out; + * char *source = input; + * if(encoding!=NULL && U_SUCCESS(err)){ + * // should signature be discarded ? + * conv = ucnv_open(encoding, &err); + * // do the conversion + * ucnv_toUnicode(conv, + * target, output + sizeof(output)/U_SIZEOF_UCHAR, + * source, input + sizeof(input), + * NULL, TRUE, &err); + * out = output; + * if (discardSignature){ + * ++out; // ignore initial U+FEFF + * } + * while(out != target) { + * printf("%04x ", *out++); + * } + * puts(""); + * } + * + * @endcode + * + * @param source The source string in which the signature should be detected. + * @param sourceLength Length of the input string, or -1 if terminated with a NUL byte. + * @param signatureLength A pointer to int32_t to receive the number of bytes that make up the signature + * of the detected UTF. 0 if not detected. + * Can be a NULL pointer. + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return The name of the encoding detected. NULL if encoding is not detected. + * @stable ICU 2.4 + */ +U_STABLE const char* U_EXPORT2 +ucnv_detectUnicodeSignature(const char* source, + int32_t sourceLength, + int32_t *signatureLength, + UErrorCode *pErrorCode); + +/** + * Returns the number of UChars held in the converter's internal state + * because more input is needed for completing the conversion. This function is + * useful for mapping semantics of ICU's converter interface to those of iconv, + * and this information is not needed for normal conversion. + * @param cnv The converter in which the input is held + * @param status ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return The number of UChars in the state. -1 if an error is encountered. + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_fromUCountPending(const UConverter* cnv, UErrorCode* status); + +/** + * Returns the number of chars held in the converter's internal state + * because more input is needed for completing the conversion. This function is + * useful for mapping semantics of ICU's converter interface to those of iconv, + * and this information is not needed for normal conversion. + * @param cnv The converter in which the input is held as internal state + * @param status ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return The number of chars in the state. -1 if an error is encountered. + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +ucnv_toUCountPending(const UConverter* cnv, UErrorCode* status); + +#endif + +#endif +/*_UCNV*/ diff --git a/utils/openttd/unicode/ucnv_cb.h b/utils/openttd/unicode/ucnv_cb.h new file mode 100644 index 00000000000..f0e67ba11e0 --- /dev/null +++ b/utils/openttd/unicode/ucnv_cb.h @@ -0,0 +1,162 @@ +/* +********************************************************************** +* Copyright (C) 2000-2004, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** + * ucnv_cb.h: + * External APIs for the ICU's codeset conversion library + * Helena Shih + * + * Modification History: + * + * Date Name Description + */ + +/** + * \file + * \brief C UConverter functions to aid the writers of callbacks + * + * <h2> Callback API for UConverter </h2> + * + * These functions are provided here for the convenience of the callback + * writer. If you are just looking for callback functions to use, please + * see ucnv_err.h. DO NOT call these functions directly when you are + * working with converters, unless your code has been called as a callback + * via ucnv_setFromUCallback or ucnv_setToUCallback !! + * + * A note about error codes and overflow. Unlike other ICU functions, + * these functions do not expect the error status to be U_ZERO_ERROR. + * Callbacks must be much more careful about their error codes. + * The error codes used here are in/out parameters, which should be passed + * back in the callback's error parameter. + * + * For example, if you call ucnv_cbfromUWriteBytes to write data out + * to the output codepage, it may return U_BUFFER_OVERFLOW_ERROR if + * the data did not fit in the target. But this isn't a failing error, + * in fact, ucnv_cbfromUWriteBytes may be called AGAIN with the error + * status still U_BUFFER_OVERFLOW_ERROR to attempt to write further bytes, + * which will also go into the internal overflow buffers. + * + * Concerning offsets, the 'offset' parameters here are relative to the start + * of SOURCE. For example, Suppose the string "ABCD" was being converted + * from Unicode into a codepage which doesn't have a mapping for 'B'. + * 'A' will be written out correctly, but + * The FromU Callback will be called on an unassigned character for 'B'. + * At this point, this is the state of the world: + * Target: A [..] [points after A] + * Source: A B [C] D [points to C - B has been consumed] + * 0 1 2 3 + * codePoint = "B" [the unassigned codepoint] + * + * Now, suppose a callback wants to write the substitution character '?' to + * the target. It calls ucnv_cbFromUWriteBytes() to write the ?. + * It should pass ZERO as the offset, because the offset as far as the + * callback is concerned is relative to the SOURCE pointer [which points + * before 'C'.] If the callback goes into the args and consumes 'C' also, + * it would call FromUWriteBytes with an offset of 1 (and advance the source + * pointer). + * + */ + +#ifndef UCNV_CB_H +#define UCNV_CB_H + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_CONVERSION + +#include "unicode/ucnv.h" +#include "unicode/ucnv_err.h" + +/** + * ONLY used by FromU callback functions. + * Writes out the specified byte output bytes to the target byte buffer or to converter internal buffers. + * + * @param args callback fromUnicode arguments + * @param source source bytes to write + * @param length length of bytes to write + * @param offsetIndex the relative offset index from callback. + * @param err error status. If <TT>U_BUFFER_OVERFLOW</TT> is returned, then U_BUFFER_OVERFLOW <STRONG>must</STRONG> + * be returned to the user, because it means that not all data could be written into the target buffer, and some is + * in the converter error buffer. + * @see ucnv_cbFromUWriteSub + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_cbFromUWriteBytes (UConverterFromUnicodeArgs *args, + const char* source, + int32_t length, + int32_t offsetIndex, + UErrorCode * err); + +/** + * ONLY used by FromU callback functions. + * This function will write out the correct substitution character sequence + * to the target. + * + * @param args callback fromUnicode arguments + * @param offsetIndex the relative offset index from the current source pointer to be used + * @param err error status. If <TT>U_BUFFER_OVERFLOW</TT> is returned, then U_BUFFER_OVERFLOW <STRONG>must</STRONG> + * be returned to the user, because it means that not all data could be written into the target buffer, and some is + * in the converter error buffer. + * @see ucnv_cbFromUWriteBytes + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ucnv_cbFromUWriteSub (UConverterFromUnicodeArgs *args, + int32_t offsetIndex, + UErrorCode * err); + +/** + * ONLY used by fromU callback functions. + * This function will write out the error character(s) to the target UChar buffer. + * + * @param args callback fromUnicode arguments + * @param source pointer to pointer to first UChar to write [on exit: 1 after last UChar processed] + * @param sourceLimit pointer after last UChar to write + * @param offsetIndex the relative offset index from callback which will be set + * @param err error status <TT>U_BUFFER_OVERFLOW</TT> + * @see ucnv_cbToUWriteSub + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 ucnv_cbFromUWriteUChars(UConverterFromUnicodeArgs *args, + const UChar** source, + const UChar* sourceLimit, + int32_t offsetIndex, + UErrorCode * err); + +/** + * ONLY used by ToU callback functions. + * This function will write out the specified characters to the target + * UChar buffer. + * + * @param args callback toUnicode arguments + * @param source source string to write + * @param length the length of source string + * @param offsetIndex the relative offset index which will be written. + * @param err error status <TT>U_BUFFER_OVERFLOW</TT> + * @see ucnv_cbToUWriteSub + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 ucnv_cbToUWriteUChars (UConverterToUnicodeArgs *args, + const UChar* source, + int32_t length, + int32_t offsetIndex, + UErrorCode * err); + +/** + * ONLY used by ToU callback functions. + * This function will write out the Unicode substitution character (U+FFFD). + * + * @param args callback fromUnicode arguments + * @param offsetIndex the relative offset index from callback. + * @param err error status <TT>U_BUFFER_OVERFLOW</TT> + * @see ucnv_cbToUWriteUChars + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 ucnv_cbToUWriteSub (UConverterToUnicodeArgs *args, + int32_t offsetIndex, + UErrorCode * err); +#endif + +#endif diff --git a/utils/openttd/unicode/ucnv_err.h b/utils/openttd/unicode/ucnv_err.h new file mode 100644 index 00000000000..6fde6966cdb --- /dev/null +++ b/utils/openttd/unicode/ucnv_err.h @@ -0,0 +1,463 @@ +/* +********************************************************************** +* Copyright (C) 1999-2007, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** + * + * + * ucnv_err.h: + */ + +/** + * \file + * \brief C UConverter predefined error callbacks + * + * <h2>Error Behaviour Functions</h2> + * Defines some error behaviour functions called by ucnv_{from,to}Unicode + * These are provided as part of ICU and many are stable, but they + * can also be considered only as an example of what can be done with + * callbacks. You may of course write your own. + * + * If you want to write your own, you may also find the functions from + * ucnv_cb.h useful when writing your own callbacks. + * + * These functions, although public, should NEVER be called directly. + * They should be used as parameters to the ucnv_setFromUCallback + * and ucnv_setToUCallback functions, to set the behaviour of a converter + * when it encounters ILLEGAL/UNMAPPED/INVALID sequences. + * + * usage example: 'STOP' doesn't need any context, but newContext + * could be set to something other than 'NULL' if needed. The available + * contexts in this header can modify the default behavior of the callback. + * + * \code + * UErrorCode err = U_ZERO_ERROR; + * UConverter *myConverter = ucnv_open("ibm-949", &err); + * const void *oldContext; + * UConverterFromUCallback oldAction; + * + * + * if (U_SUCCESS(err)) + * { + * ucnv_setFromUCallBack(myConverter, + * UCNV_FROM_U_CALLBACK_STOP, + * NULL, + * &oldAction, + * &oldContext, + * &status); + * } + * \endcode + * + * The code above tells "myConverter" to stop when it encounters an + * ILLEGAL/TRUNCATED/INVALID sequences when it is used to convert from + * Unicode -> Codepage. The behavior from Codepage to Unicode is not changed, + * and ucnv_setToUCallBack would need to be called in order to change + * that behavior too. + * + * Here is an example with a context: + * + * \code + * UErrorCode err = U_ZERO_ERROR; + * UConverter *myConverter = ucnv_open("ibm-949", &err); + * const void *oldContext; + * UConverterFromUCallback oldAction; + * + * + * if (U_SUCCESS(err)) + * { + * ucnv_setToUCallBack(myConverter, + * UCNV_TO_U_CALLBACK_SUBSTITUTE, + * UCNV_SUB_STOP_ON_ILLEGAL, + * &oldAction, + * &oldContext, + * &status); + * } + * \endcode + * + * The code above tells "myConverter" to stop when it encounters an + * ILLEGAL/TRUNCATED/INVALID sequences when it is used to convert from + * Codepage -> Unicode. Any unmapped and legal characters will be + * substituted to be the default substitution character. + */ + +#ifndef UCNV_ERR_H +#define UCNV_ERR_H + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_CONVERSION + +/** Forward declaring the UConverter structure. @stable ICU 2.0 */ +struct UConverter; + +/** @stable ICU 2.0 */ +typedef struct UConverter UConverter; + +/** + * FROM_U, TO_U context options for sub callback + * @stable ICU 2.0 + */ +#define UCNV_SUB_STOP_ON_ILLEGAL "i" + +/** + * FROM_U, TO_U context options for skip callback + * @stable ICU 2.0 + */ +#define UCNV_SKIP_STOP_ON_ILLEGAL "i" + +/** + * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to ICU (%UXXXX) + * @stable ICU 2.0 + */ +#define UCNV_ESCAPE_ICU NULL +/** + * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to JAVA (\\uXXXX) + * @stable ICU 2.0 + */ +#define UCNV_ESCAPE_JAVA "J" +/** + * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to C (\\uXXXX \\UXXXXXXXX) + * TO_U_CALLBACK_ESCAPE option to escape the character value accoding to C (\\xXXXX) + * @stable ICU 2.0 + */ +#define UCNV_ESCAPE_C "C" +/** + * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Decimal escape \htmlonly(&#DDDD;)\endhtmlonly + * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Decimal escape \htmlonly(&#DDDD;)\endhtmlonly + * @stable ICU 2.0 + */ +#define UCNV_ESCAPE_XML_DEC "D" +/** + * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Hex escape \htmlonly(&#xXXXX;)\endhtmlonly + * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Hex escape \htmlonly(&#xXXXX;)\endhtmlonly + * @stable ICU 2.0 + */ +#define UCNV_ESCAPE_XML_HEX "X" +/** + * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to Unicode (U+XXXXX) + * @stable ICU 2.0 + */ +#define UCNV_ESCAPE_UNICODE "U" + +/** + * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to CSS2 conventions (\\HH..H<space>, that is, + * a backslash, 1..6 hex digits, and a space) + * @draft ICU 4.0 + */ +#define UCNV_ESCAPE_CSS2 "S" + +/** + * The process condition code to be used with the callbacks. + * Codes which are greater than UCNV_IRREGULAR should be + * passed on to any chained callbacks. + * @stable ICU 2.0 + */ +typedef enum { + UCNV_UNASSIGNED = 0, /**< The code point is unassigned. + The error code U_INVALID_CHAR_FOUND will be set. */ + UCNV_ILLEGAL = 1, /**< The code point is illegal. For example, + \\x81\\x2E is illegal in SJIS because \\x2E + is not a valid trail byte for the \\x81 + lead byte. + Also, starting with Unicode 3.0.1, non-shortest byte sequences + in UTF-8 (like \\xC1\\xA1 instead of \\x61 for U+0061) + are also illegal, not just irregular. + The error code U_ILLEGAL_CHAR_FOUND will be set. */ + UCNV_IRREGULAR = 2, /**< The codepoint is not a regular sequence in + the encoding. For example, \\xED\\xA0\\x80..\\xED\\xBF\\xBF + are irregular UTF-8 byte sequences for single surrogate + code points. + The error code U_INVALID_CHAR_FOUND will be set. */ + UCNV_RESET = 3, /**< The callback is called with this reason when a + 'reset' has occured. Callback should reset all + state. */ + UCNV_CLOSE = 4, /**< Called when the converter is closed. The + callback should release any allocated memory.*/ + UCNV_CLONE = 5 /**< Called when ucnv_safeClone() is called on the + converter. the pointer available as the + 'context' is an alias to the original converters' + context pointer. If the context must be owned + by the new converter, the callback must clone + the data and call ucnv_setFromUCallback + (or setToUCallback) with the correct pointer. + @stable ICU 2.2 + */ +} UConverterCallbackReason; + + +/** + * The structure for the fromUnicode callback function parameter. + * @stable ICU 2.0 + */ +typedef struct { + uint16_t size; /**< The size of this struct. @stable ICU 2.0 */ + UBool flush; /**< The internal state of converter will be reset and data flushed if set to TRUE. @stable ICU 2.0 */ + UConverter *converter; /**< Pointer to the converter that is opened and to which this struct is passed as an argument. @stable ICU 2.0 */ + const UChar *source; /**< Pointer to the source source buffer. @stable ICU 2.0 */ + const UChar *sourceLimit; /**< Pointer to the limit (end + 1) of source buffer. @stable ICU 2.0 */ + char *target; /**< Pointer to the target buffer. @stable ICU 2.0 */ + const char *targetLimit; /**< Pointer to the limit (end + 1) of target buffer. @stable ICU 2.0 */ + int32_t *offsets; /**< Pointer to the buffer that recieves the offsets. *offset = blah ; offset++;. @stable ICU 2.0 */ +} UConverterFromUnicodeArgs; + + +/** + * The structure for the toUnicode callback function parameter. + * @stable ICU 2.0 + */ +typedef struct { + uint16_t size; /**< The size of this struct @stable ICU 2.0 */ + UBool flush; /**< The internal state of converter will be reset and data flushed if set to TRUE. @stable ICU 2.0 */ + UConverter *converter; /**< Pointer to the converter that is opened and to which this struct is passed as an argument. @stable ICU 2.0 */ + const char *source; /**< Pointer to the source source buffer. @stable ICU 2.0 */ + const char *sourceLimit; /**< Pointer to the limit (end + 1) of source buffer. @stable ICU 2.0 */ + UChar *target; /**< Pointer to the target buffer. @stable ICU 2.0 */ + const UChar *targetLimit; /**< Pointer to the limit (end + 1) of target buffer. @stable ICU 2.0 */ + int32_t *offsets; /**< Pointer to the buffer that recieves the offsets. *offset = blah ; offset++;. @stable ICU 2.0 */ +} UConverterToUnicodeArgs; + + +/** + * DO NOT CALL THIS FUNCTION DIRECTLY! + * This From Unicode callback STOPS at the ILLEGAL_SEQUENCE, + * returning the error code back to the caller immediately. + * + * @param context Pointer to the callback's private data + * @param fromUArgs Information about the conversion in progress + * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint. + * @param reason Defines the reason the callback was invoked + * @param err This should always be set to a failure status prior to calling. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_STOP ( + const void *context, + UConverterFromUnicodeArgs *fromUArgs, + const UChar* codeUnits, + int32_t length, + UChar32 codePoint, + UConverterCallbackReason reason, + UErrorCode * err); + + + +/** + * DO NOT CALL THIS FUNCTION DIRECTLY! + * This To Unicode callback STOPS at the ILLEGAL_SEQUENCE, + * returning the error code back to the caller immediately. + * + * @param context Pointer to the callback's private data + * @param toUArgs Information about the conversion in progress + * @param codeUnits Points to 'length' bytes of the concerned codepage sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param reason Defines the reason the callback was invoked + * @param err This should always be set to a failure status prior to calling. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_STOP ( + const void *context, + UConverterToUnicodeArgs *toUArgs, + const char* codeUnits, + int32_t length, + UConverterCallbackReason reason, + UErrorCode * err); + +/** + * DO NOT CALL THIS FUNCTION DIRECTLY! + * This From Unicode callback skips any ILLEGAL_SEQUENCE, or + * skips only UNASSINGED_SEQUENCE depending on the context parameter + * simply ignoring those characters. + * + * @param context The function currently recognizes the callback options: + * UCNV_SKIP_STOP_ON_ILLEGAL: STOPS at the ILLEGAL_SEQUENCE, + * returning the error code back to the caller immediately. + * NULL: Skips any ILLEGAL_SEQUENCE + * @param fromUArgs Information about the conversion in progress + * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint. + * @param reason Defines the reason the callback was invoked + * @param err Return value will be set to success if the callback was handled, + * otherwise this value will be set to a failure status. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_SKIP ( + const void *context, + UConverterFromUnicodeArgs *fromUArgs, + const UChar* codeUnits, + int32_t length, + UChar32 codePoint, + UConverterCallbackReason reason, + UErrorCode * err); + +/** + * DO NOT CALL THIS FUNCTION DIRECTLY! + * This From Unicode callback will Substitute the ILLEGAL SEQUENCE, or + * UNASSIGNED_SEQUENCE depending on context parameter, with the + * current substitution string for the converter. This is the default + * callback. + * + * @param context The function currently recognizes the callback options: + * UCNV_SUB_STOP_ON_ILLEGAL: STOPS at the ILLEGAL_SEQUENCE, + * returning the error code back to the caller immediately. + * NULL: Substitutes any ILLEGAL_SEQUENCE + * @param fromUArgs Information about the conversion in progress + * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint. + * @param reason Defines the reason the callback was invoked + * @param err Return value will be set to success if the callback was handled, + * otherwise this value will be set to a failure status. + * @see ucnv_setSubstChars + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_SUBSTITUTE ( + const void *context, + UConverterFromUnicodeArgs *fromUArgs, + const UChar* codeUnits, + int32_t length, + UChar32 codePoint, + UConverterCallbackReason reason, + UErrorCode * err); + +/** + * DO NOT CALL THIS FUNCTION DIRECTLY! + * This From Unicode callback will Substitute the ILLEGAL SEQUENCE with the + * hexadecimal representation of the illegal codepoints + * + * @param context The function currently recognizes the callback options: + * <ul> + * <li>UCNV_ESCAPE_ICU: Substitues the ILLEGAL SEQUENCE with the hexadecimal + * representation in the format %UXXXX, e.g. "%uFFFE%u00AC%uC8FE"). + * In the Event the converter doesn't support the characters {%,U}[A-F][0-9], + * it will substitute the illegal sequence with the substitution characters. + * Note that codeUnit(32bit int eg: unit of a surrogate pair) is represented as + * %UD84D%UDC56</li> + * <li>UCNV_ESCAPE_JAVA: Substitues the ILLEGAL SEQUENCE with the hexadecimal + * representation in the format \\uXXXX, e.g. "\\uFFFE\\u00AC\\uC8FE"). + * In the Event the converter doesn't support the characters {\,u}[A-F][0-9], + * it will substitute the illegal sequence with the substitution characters. + * Note that codeUnit(32bit int eg: unit of a surrogate pair) is represented as + * \\uD84D\\uDC56</li> + * <li>UCNV_ESCAPE_C: Substitues the ILLEGAL SEQUENCE with the hexadecimal + * representation in the format \\uXXXX, e.g. "\\uFFFE\\u00AC\\uC8FE"). + * In the Event the converter doesn't support the characters {\,u,U}[A-F][0-9], + * it will substitute the illegal sequence with the substitution characters. + * Note that codeUnit(32bit int eg: unit of a surrogate pair) is represented as + * \\U00023456</li> + * <li>UCNV_ESCAPE_XML_DEC: Substitues the ILLEGAL SEQUENCE with the decimal + * representation in the format \htmlonly&#DDDDDDDD;, e.g. "&#65534;&#172;&#51454;")\endhtmlonly. + * In the Event the converter doesn't support the characters {&,#}[0-9], + * it will substitute the illegal sequence with the substitution characters. + * Note that codeUnit(32bit int eg: unit of a surrogate pair) is represented as + * &#144470; and Zero padding is ignored.</li> + * <li>UCNV_ESCAPE_XML_HEX:Substitues the ILLEGAL SEQUENCE with the decimal + * representation in the format \htmlonly&#xXXXX; e.g. "&#xFFFE;&#x00AC;&#xC8FE;")\endhtmlonly. + * In the Event the converter doesn't support the characters {&,#,x}[0-9], + * it will substitute the illegal sequence with the substitution characters. + * Note that codeUnit(32bit int eg: unit of a surrogate pair) is represented as + * \htmlonly&#x23456;\endhtmlonly</li> + * </ul> + * @param fromUArgs Information about the conversion in progress + * @param codeUnits Points to 'length' UChars of the concerned Unicode sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param codePoint Single UChar32 (UTF-32) containing the concerend Unicode codepoint. + * @param reason Defines the reason the callback was invoked + * @param err Return value will be set to success if the callback was handled, + * otherwise this value will be set to a failure status. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 UCNV_FROM_U_CALLBACK_ESCAPE ( + const void *context, + UConverterFromUnicodeArgs *fromUArgs, + const UChar* codeUnits, + int32_t length, + UChar32 codePoint, + UConverterCallbackReason reason, + UErrorCode * err); + + +/** + * DO NOT CALL THIS FUNCTION DIRECTLY! + * This To Unicode callback skips any ILLEGAL_SEQUENCE, or + * skips only UNASSINGED_SEQUENCE depending on the context parameter + * simply ignoring those characters. + * + * @param context The function currently recognizes the callback options: + * UCNV_SKIP_STOP_ON_ILLEGAL: STOPS at the ILLEGAL_SEQUENCE, + * returning the error code back to the caller immediately. + * NULL: Skips any ILLEGAL_SEQUENCE + * @param toUArgs Information about the conversion in progress + * @param codeUnits Points to 'length' bytes of the concerned codepage sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param reason Defines the reason the callback was invoked + * @param err Return value will be set to success if the callback was handled, + * otherwise this value will be set to a failure status. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_SKIP ( + const void *context, + UConverterToUnicodeArgs *toUArgs, + const char* codeUnits, + int32_t length, + UConverterCallbackReason reason, + UErrorCode * err); + +/** + * DO NOT CALL THIS FUNCTION DIRECTLY! + * This To Unicode callback will Substitute the ILLEGAL SEQUENCE,or + * UNASSIGNED_SEQUENCE depending on context parameter, with the + * Unicode substitution character, U+FFFD. + * + * @param context The function currently recognizes the callback options: + * UCNV_SUB_STOP_ON_ILLEGAL: STOPS at the ILLEGAL_SEQUENCE, + * returning the error code back to the caller immediately. + * NULL: Substitutes any ILLEGAL_SEQUENCE + * @param toUArgs Information about the conversion in progress + * @param codeUnits Points to 'length' bytes of the concerned codepage sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param reason Defines the reason the callback was invoked + * @param err Return value will be set to success if the callback was handled, + * otherwise this value will be set to a failure status. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_SUBSTITUTE ( + const void *context, + UConverterToUnicodeArgs *toUArgs, + const char* codeUnits, + int32_t length, + UConverterCallbackReason reason, + UErrorCode * err); + +/** + * DO NOT CALL THIS FUNCTION DIRECTLY! + * This To Unicode callback will Substitute the ILLEGAL SEQUENCE with the + * hexadecimal representation of the illegal bytes + * (in the format %XNN, e.g. "%XFF%X0A%XC8%X03"). + * + * @param context This function currently recognizes the callback options: + * UCNV_ESCAPE_ICU, UCNV_ESCAPE_JAVA, UCNV_ESCAPE_C, UCNV_ESCAPE_XML_DEC, + * UCNV_ESCAPE_XML_HEX and UCNV_ESCAPE_UNICODE. + * @param toUArgs Information about the conversion in progress + * @param codeUnits Points to 'length' bytes of the concerned codepage sequence + * @param length Size (in bytes) of the concerned codepage sequence + * @param reason Defines the reason the callback was invoked + * @param err Return value will be set to success if the callback was handled, + * otherwise this value will be set to a failure status. + * @stable ICU 2.0 + */ + +U_STABLE void U_EXPORT2 UCNV_TO_U_CALLBACK_ESCAPE ( + const void *context, + UConverterToUnicodeArgs *toUArgs, + const char* codeUnits, + int32_t length, + UConverterCallbackReason reason, + UErrorCode * err); + +#endif + +#endif + +/*UCNV_ERR_H*/ diff --git a/utils/openttd/unicode/uconfig.h b/utils/openttd/unicode/uconfig.h new file mode 100644 index 00000000000..8006ea2434c --- /dev/null +++ b/utils/openttd/unicode/uconfig.h @@ -0,0 +1,228 @@ +/* +********************************************************************** +* Copyright (C) 2002-2008, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* file name: uconfig.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2002sep19 +* created by: Markus W. Scherer +*/ + +#ifndef __UCONFIG_H__ +#define __UCONFIG_H__ + + +/*! + * \file + * \brief Switches for excluding parts of ICU library code modules. + * + * Allows to build partial, smaller libraries for special purposes. + * By default, all modules are built. + * The switches are fairly coarse, controlling large modules. + * Basic services cannot be turned off. + * + * Building with any of these options does not guarantee that the + * ICU build process will completely work. It is recommended that + * the ICU libraries and data be built using the normal build. + * At that time you should remove the data used by those services. + * After building the ICU data library, you should rebuild the ICU + * libraries with these switches customized to your needs. + * + * @stable ICU 2.4 + */ + +/** + * \def UCONFIG_USE_LOCAL + * If this switch is defined, ICU will attempt to load a header file named "uconfig_local.h" + * prior to determining default settings for uconfig variables. + * + * @internal ICU 4.0 + * + */ +#if defined(UCONFIG_USE_LOCAL) +#include "uconfig_local.h" +#endif + +/** + * \def UCONFIG_ONLY_COLLATION + * This switch turns off modules that are not needed for collation. + * + * It does not turn off legacy conversion because that is necessary + * for ICU to work on EBCDIC platforms (for the default converter). + * If you want "only collation" and do not build for EBCDIC, + * then you can define UCONFIG_NO_LEGACY_CONVERSION 1 as well. + * + * @stable ICU 2.4 + */ +#ifndef UCONFIG_ONLY_COLLATION +# define UCONFIG_ONLY_COLLATION 0 +#endif + +#if UCONFIG_ONLY_COLLATION + /* common library */ +# define UCONFIG_NO_BREAK_ITERATION 1 +# define UCONFIG_NO_IDNA 1 + + /* i18n library */ +# if UCONFIG_NO_COLLATION +# error Contradictory collation switches in uconfig.h. +# endif +# define UCONFIG_NO_FORMATTING 1 +# define UCONFIG_NO_TRANSLITERATION 1 +# define UCONFIG_NO_REGULAR_EXPRESSIONS 1 +#endif + +/* common library switches -------------------------------------------------- */ + +/** + * \def UCONFIG_NO_FILE_IO + * This switch turns off all file access in the common library + * where file access is only used for data loading. + * ICU data must then be provided in the form of a data DLL (or with an + * equivalent way to link to the data residing in an executable, + * as in building a combined library with both the common library's code and + * the data), or via udata_setCommonData(). + * Application data must be provided via udata_setAppData() or by using + * "open" functions that take pointers to data, for example ucol_openBinary(). + * + * File access is not used at all in the i18n library. + * + * File access cannot be turned off for the icuio library or for the ICU + * test suites and ICU tools. + * + * @stable ICU 3.6 + */ +#ifndef UCONFIG_NO_FILE_IO +# define UCONFIG_NO_FILE_IO 0 +#endif + +/** + * \def UCONFIG_NO_CONVERSION + * ICU will not completely build with this switch turned on. + * This switch turns off all converters. + * + * @stable ICU 3.2 + */ +#ifndef UCONFIG_NO_CONVERSION +# define UCONFIG_NO_CONVERSION 0 +#endif + +#if UCONFIG_NO_CONVERSION +# define UCONFIG_NO_LEGACY_CONVERSION 1 +#endif + +/** + * \def UCONFIG_NO_LEGACY_CONVERSION + * This switch turns off all converters except for + * - Unicode charsets (UTF-7/8/16/32, CESU-8, SCSU, BOCU-1) + * - US-ASCII + * - ISO-8859-1 + * + * Turning off legacy conversion is not possible on EBCDIC platforms + * because they need ibm-37 or ibm-1047 default converters. + * + * @stable ICU 2.4 + */ +#ifndef UCONFIG_NO_LEGACY_CONVERSION +# define UCONFIG_NO_LEGACY_CONVERSION 0 +#endif + +/** + * \def UCONFIG_NO_NORMALIZATION + * This switch turns off normalization. + * It implies turning off several other services as well, for example + * collation and IDNA. + * + * @stable ICU 2.6 + */ +#ifndef UCONFIG_NO_NORMALIZATION +# define UCONFIG_NO_NORMALIZATION 0 +#elif UCONFIG_NO_NORMALIZATION + /* common library */ +# define UCONFIG_NO_IDNA 1 + + /* i18n library */ +# if UCONFIG_ONLY_COLLATION +# error Contradictory collation switches in uconfig.h. +# endif +# define UCONFIG_NO_COLLATION 1 +# define UCONFIG_NO_TRANSLITERATION 1 +#endif + +/** + * \def UCONFIG_NO_BREAK_ITERATION + * This switch turns off break iteration. + * + * @stable ICU 2.4 + */ +#ifndef UCONFIG_NO_BREAK_ITERATION +# define UCONFIG_NO_BREAK_ITERATION 0 +#endif + +/** + * \def UCONFIG_NO_IDNA + * This switch turns off IDNA. + * + * @stable ICU 2.6 + */ +#ifndef UCONFIG_NO_IDNA +# define UCONFIG_NO_IDNA 0 +#endif + +/* i18n library switches ---------------------------------------------------- */ + +/** + * \def UCONFIG_NO_COLLATION + * This switch turns off collation and collation-based string search. + * + * @stable ICU 2.4 + */ +#ifndef UCONFIG_NO_COLLATION +# define UCONFIG_NO_COLLATION 0 +#endif + +/** + * \def UCONFIG_NO_FORMATTING + * This switch turns off formatting and calendar/timezone services. + * + * @stable ICU 2.4 + */ +#ifndef UCONFIG_NO_FORMATTING +# define UCONFIG_NO_FORMATTING 0 +#endif + +/** + * \def UCONFIG_NO_TRANSLITERATION + * This switch turns off transliteration. + * + * @stable ICU 2.4 + */ +#ifndef UCONFIG_NO_TRANSLITERATION +# define UCONFIG_NO_TRANSLITERATION 0 +#endif + +/** + * \def UCONFIG_NO_REGULAR_EXPRESSIONS + * This switch turns off regular expressions. + * + * @stable ICU 2.4 + */ +#ifndef UCONFIG_NO_REGULAR_EXPRESSIONS +# define UCONFIG_NO_REGULAR_EXPRESSIONS 0 +#endif + +/** + * \def UCONFIG_NO_SERVICE + * This switch turns off service registration. + * + * @stable ICU 3.2 + */ +#ifndef UCONFIG_NO_SERVICE +# define UCONFIG_NO_SERVICE 0 +#endif + +#endif diff --git a/utils/openttd/unicode/udata.h b/utils/openttd/unicode/udata.h new file mode 100644 index 00000000000..84046d5f9cd --- /dev/null +++ b/utils/openttd/unicode/udata.h @@ -0,0 +1,389 @@ +/* +****************************************************************************** +* +* Copyright (C) 1999-2008, International Business Machines +* Corporation and others. All Rights Reserved. +* +****************************************************************************** +* file name: udata.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 1999oct25 +* created by: Markus W. Scherer +*/ + +#ifndef __UDATA_H__ +#define __UDATA_H__ + +#include "unicode/utypes.h" + +U_CDECL_BEGIN + +/** + * \file + * \brief C API: Data loading interface + * + * <h2>Information about data loading interface</h2> + * + * This API is used to find and efficiently load data for ICU and applications + * using ICU. It provides an abstract interface that specifies a data type and + * name to find and load the data. Normally this API is used by other ICU APIs + * to load required data out of the ICU data library, but it can be used to + * load data out of other places. + * + * See the User Guide Data Management chapter. + */ + +#ifndef U_HIDE_INTERNAL_API +/** + * Character used to separate package names from tree names + * @internal ICU 3.0 + */ +#define U_TREE_SEPARATOR '-' + +/** + * String used to separate package names from tree names + * @internal ICU 3.0 + */ +#define U_TREE_SEPARATOR_STRING "-" + +/** + * Character used to separate parts of entry names + * @internal ICU 3.0 + */ +#define U_TREE_ENTRY_SEP_CHAR '/' + +/** + * String used to separate parts of entry names + * @internal ICU 3.0 + */ +#define U_TREE_ENTRY_SEP_STRING "/" + +/** + * Alias for standard ICU data + * @internal ICU 3.0 + */ +#define U_ICUDATA_ALIAS "ICUDATA" + +#endif /* U_HIDE_INTERNAL_API */ + +/** + * UDataInfo contains the properties about the requested data. + * This is meta data. + * + * <p>This structure may grow in the future, indicated by the + * <code>size</code> field.</p> + * + * <p>The platform data property fields help determine if a data + * file can be efficiently used on a given machine. + * The particular fields are of importance only if the data + * is affected by the properties - if there is integer data + * with word sizes > 1 byte, char* text, or UChar* text.</p> + * + * <p>The implementation for the <code>udata_open[Choice]()</code> + * functions may reject data based on the value in <code>isBigEndian</code>. + * No other field is used by the <code>udata</code> API implementation.</p> + * + * <p>The <code>dataFormat</code> may be used to identify + * the kind of data, e.g. a converter table.</p> + * + * <p>The <code>formatVersion</code> field should be used to + * make sure that the format can be interpreted. + * I may be a good idea to check only for the one or two highest + * of the version elements to allow the data memory to + * get more or somewhat rearranged contents, for as long + * as the using code can still interpret the older contents.</p> + * + * <p>The <code>dataVersion</code> field is intended to be a + * common place to store the source version of the data; + * for data from the Unicode character database, this could + * reflect the Unicode version.</p> + * @stable ICU 2.0 + */ +typedef struct { + /** sizeof(UDataInfo) + * @stable ICU 2.0 */ + uint16_t size; + + /** unused, set to 0 + * @stable ICU 2.0*/ + uint16_t reservedWord; + + /* platform data properties */ + /** 0 for little-endian machine, 1 for big-endian + * @stable ICU 2.0 */ + uint8_t isBigEndian; + + /** see U_CHARSET_FAMILY values in utypes.h + * @stable ICU 2.0*/ + uint8_t charsetFamily; + + /** sizeof(UChar), one of { 1, 2, 4 } + * @stable ICU 2.0*/ + uint8_t sizeofUChar; + + /** unused, set to 0 + * @stable ICU 2.0*/ + uint8_t reservedByte; + + /** data format identifier + * @stable ICU 2.0*/ + uint8_t dataFormat[4]; + + /** versions: [0] major [1] minor [2] milli [3] micro + * @stable ICU 2.0*/ + uint8_t formatVersion[4]; + + /** versions: [0] major [1] minor [2] milli [3] micro + * @stable ICU 2.0*/ + uint8_t dataVersion[4]; +} UDataInfo; + +/* API for reading data -----------------------------------------------------*/ + +/** + * Forward declaration of the data memory type. + * @stable ICU 2.0 + */ +typedef struct UDataMemory UDataMemory; + +/** + * Callback function for udata_openChoice(). + * @param context parameter passed into <code>udata_openChoice()</code>. + * @param type The type of the data as passed into <code>udata_openChoice()</code>. + * It may be <code>NULL</code>. + * @param name The name of the data as passed into <code>udata_openChoice()</code>. + * @param pInfo A pointer to the <code>UDataInfo</code> structure + * of data that has been loaded and will be returned + * by <code>udata_openChoice()</code> if this function + * returns <code>TRUE</code>. + * @return TRUE if the current data memory is acceptable + * @stable ICU 2.0 + */ +typedef UBool U_CALLCONV +UDataMemoryIsAcceptable(void *context, + const char *type, const char *name, + const UDataInfo *pInfo); + + +/** + * Convenience function. + * This function works the same as <code>udata_openChoice</code> + * except that any data that matches the type and name + * is assumed to be acceptable. + * @param path Specifies an absolute path and/or a basename for the + * finding of the data in the file system. + * <code>NULL</code> for ICU data. + * @param type A string that specifies the type of data to be loaded. + * For example, resource bundles are loaded with type "res", + * conversion tables with type "cnv". + * This may be <code>NULL</code> or empty. + * @param name A string that specifies the name of the data. + * @param pErrorCode An ICU UErrorCode parameter. It must not be <code>NULL</code>. + * @return A pointer (handle) to a data memory object, or <code>NULL</code> + * if an error occurs. Call <code>udata_getMemory()</code> + * to get a pointer to the actual data. + * + * @see udata_openChoice + * @stable ICU 2.0 + */ +U_STABLE UDataMemory * U_EXPORT2 +udata_open(const char *path, const char *type, const char *name, + UErrorCode *pErrorCode); + +/** + * Data loading function. + * This function is used to find and load efficiently data for + * ICU and applications using ICU. + * It provides an abstract interface that allows to specify a data + * type and name to find and load the data. + * + * <p>The implementation depends on platform properties and user preferences + * and may involve loading shared libraries (DLLs), mapping + * files into memory, or fopen()/fread() files. + * It may also involve using static memory or database queries etc. + * Several or all data items may be combined into one entity + * (DLL, memory-mappable file).</p> + * + * <p>The data is always preceded by a header that includes + * a <code>UDataInfo</code> structure. + * The caller's <code>isAcceptable()</code> function is called to make + * sure that the data is useful. It may be called several times if it + * rejects the data and there is more than one location with data + * matching the type and name.</p> + * + * <p>If <code>path==NULL</code>, then ICU data is loaded. + * Otherwise, it is separated into a basename and a basename-less directory string. + * The basename is used as the data package name, and the directory is + * logically prepended to the ICU data directory string.</p> + * + * <p>For details about ICU data loading see the User Guide + * Data Management chapter. (http://icu-project.org/userguide/icudata.html)</p> + * + * @param path Specifies an absolute path and/or a basename for the + * finding of the data in the file system. + * <code>NULL</code> for ICU data. + * @param type A string that specifies the type of data to be loaded. + * For example, resource bundles are loaded with type "res", + * conversion tables with type "cnv". + * This may be <code>NULL</code> or empty. + * @param name A string that specifies the name of the data. + * @param isAcceptable This function is called to verify that loaded data + * is useful for the client code. If it returns FALSE + * for all data items, then <code>udata_openChoice()</code> + * will return with an error. + * @param context Arbitrary parameter to be passed into isAcceptable. + * @param pErrorCode An ICU UErrorCode parameter. It must not be <code>NULL</code>. + * @return A pointer (handle) to a data memory object, or <code>NULL</code> + * if an error occurs. Call <code>udata_getMemory()</code> + * to get a pointer to the actual data. + * @stable ICU 2.0 + */ +U_STABLE UDataMemory * U_EXPORT2 +udata_openChoice(const char *path, const char *type, const char *name, + UDataMemoryIsAcceptable *isAcceptable, void *context, + UErrorCode *pErrorCode); + +/** + * Close the data memory. + * This function must be called to allow the system to + * release resources associated with this data memory. + * @param pData The pointer to data memory object + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +udata_close(UDataMemory *pData); + +/** + * Get the pointer to the actual data inside the data memory. + * The data is read-only. + * @param pData The pointer to data memory object + * @stable ICU 2.0 + */ +U_STABLE const void * U_EXPORT2 +udata_getMemory(UDataMemory *pData); + +/** + * Get the information from the data memory header. + * This allows to get access to the header containing + * platform data properties etc. which is not part of + * the data itself and can therefore not be accessed + * via the pointer that <code>udata_getMemory()</code> returns. + * + * @param pData pointer to the data memory object + * @param pInfo pointer to a UDataInfo object; + * its <code>size</code> field must be set correctly, + * typically to <code>sizeof(UDataInfo)</code>. + * + * <code>*pInfo</code> will be filled with the UDataInfo structure + * in the data memory object. If this structure is smaller than + * <code>pInfo->size</code>, then the <code>size</code> will be + * adjusted and only part of the structure will be filled. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +udata_getInfo(UDataMemory *pData, UDataInfo *pInfo); + +/** + * This function bypasses the normal ICU data loading process and + * allows you to force ICU's system data to come out of a user-specified + * area in memory. + * + * The format of this data is that of the icu common data file, as is + * generated by the pkgdata tool with mode=common or mode=dll. + * You can read in a whole common mode file and pass the address to the start of the + * data, or (with the appropriate link options) pass in the pointer to + * the data that has been loaded from a dll by the operating system, + * as shown in this code: + * + * extern const char U_IMPORT U_ICUDATA_ENTRY_POINT []; + * // U_ICUDATA_ENTRY_POINT is same as entry point specified to pkgdata tool + * UErrorCode status = U_ZERO_ERROR; + * + * udata_setCommonData(&U_ICUDATA_ENTRY_POINT, &status); + * + * Warning: ICU must NOT have even attempted to access its data yet + * when this call is made, or U_USING_DEFAULT_WARNING code will + * be returned. Be careful of UnicodeStrings in static initialization which + * may attempt to load a converter (use the UNICODE_STRING(x) macro instead). + * + * Also note that it is important that the declaration be as above. The entry point + * must not be declared as an extern void*. + * + * This function has no effect on application (non ICU) data. See udata_setAppData() + * for similar functionality for application data. + * + * @param data pointer to ICU common data + * @param err outgoing error status <code>U_USING_DEFAULT_WARNING, U_UNSUPPORTED_ERROR</code> + * @stable ICU 2.0 + */ + +U_STABLE void U_EXPORT2 +udata_setCommonData(const void *data, UErrorCode *err); + + +/** + * This function bypasses the normal ICU data loading process for application-specific + * data and allows you to force the it to come out of a user-specified + * pointer. + * + * The format of this data is that of the icu common data file, like 'icudt26l.dat' + * or the corresponding shared library (DLL) file. + * The application must read in or otherwise construct an image of the data and then + * pass the address of it to this function. + * + * + * Warning: setAppData will set a U_USING_DEFAULT_WARNING code if + * data with the specifed path that has already been opened, or + * if setAppData with the same path has already been called. + * Any such calls to setAppData will have no effect. + * + * + * @param packageName the package name by which the application will refer + * to (open) this data + * @param data pointer to the data + * @param err outgoing error status <code>U_USING_DEFAULT_WARNING, U_UNSUPPORTED_ERROR</code> + * @see udata_setCommonData + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +udata_setAppData(const char *packageName, const void *data, UErrorCode *err); + +/** + * Possible settings for udata_setFileAccess() + * @see udata_setFileAccess + * @stable ICU 3.4 + */ +typedef enum UDataFileAccess { + /** ICU looks for data in single files first, then in packages. (default) */ + UDATA_FILES_FIRST, + /** ICU only loads data from packages, not from single files. */ + UDATA_ONLY_PACKAGES, + /** ICU loads data from packages first, and only from single files + if the data cannot be found in a package. */ + UDATA_PACKAGES_FIRST, + /** ICU does not access the file system for data loading. */ + UDATA_NO_FILES, + /** An alias for the default access mode. */ + UDATA_DEFAULT_ACCESS = UDATA_FILES_FIRST, + UDATA_FILE_ACCESS_COUNT +} UDataFileAccess; + +/** + * This function may be called to control how ICU loads data. It must be called + * before any ICU data is loaded, including application data loaded with ures/ResourceBundle or + * udata APIs. It should be called before u_init. This function is not multithread safe. + * The results of calling it while other threads are loading data are undefined. + * @param access The type of file access to be used + * @param status Error code. + * @see UDataFileAccess + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +udata_setFileAccess(UDataFileAccess access, UErrorCode *status); + +U_CDECL_END + +#endif diff --git a/utils/openttd/unicode/udeprctd.h b/utils/openttd/unicode/udeprctd.h new file mode 100644 index 00000000000..9bf45f372b6 --- /dev/null +++ b/utils/openttd/unicode/udeprctd.h @@ -0,0 +1,50 @@ +/* +******************************************************************************* +* Copyright (C) 2004-2008, International Business Machines +* Corporation and others. All Rights Reserved. +******************************************************************************* +* +* file name: +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* Created by: genheaders.pl, a perl script written by Ram Viswanadha +* +* Contains data for commenting out APIs. +* Gets included by umachine.h +* +* THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT +* YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN! +*/ + +#ifndef UDEPRCTD_H +#define UDEPRCTD_H + +#ifdef U_HIDE_DEPRECATED_API + +# if U_DISABLE_RENAMING +# define ucol_getContractions ucol_getContractions_DEPRECATED_API_DO_NOT_USE +# define ucol_getLocale ucol_getLocale_DEPRECATED_API_DO_NOT_USE +# define ures_countArrayItems ures_countArrayItems_DEPRECATED_API_DO_NOT_USE +# define ures_getLocale ures_getLocale_DEPRECATED_API_DO_NOT_USE +# define ures_getVersionNumber ures_getVersionNumber_DEPRECATED_API_DO_NOT_USE +# define utrans_getAvailableID utrans_getAvailableID_DEPRECATED_API_DO_NOT_USE +# define utrans_getID utrans_getID_DEPRECATED_API_DO_NOT_USE +# define utrans_open utrans_open_DEPRECATED_API_DO_NOT_USE +# define utrans_unregister utrans_unregister_DEPRECATED_API_DO_NOT_USE +# else +# define ucol_getContractions_4_0 ucol_getContractions_DEPRECATED_API_DO_NOT_USE +# define ucol_getLocale_4_0 ucol_getLocale_DEPRECATED_API_DO_NOT_USE +# define ures_countArrayItems_4_0 ures_countArrayItems_DEPRECATED_API_DO_NOT_USE +# define ures_getLocale_4_0 ures_getLocale_DEPRECATED_API_DO_NOT_USE +# define ures_getVersionNumber_4_0 ures_getVersionNumber_DEPRECATED_API_DO_NOT_USE +# define utrans_getAvailableID_4_0 utrans_getAvailableID_DEPRECATED_API_DO_NOT_USE +# define utrans_getID_4_0 utrans_getID_DEPRECATED_API_DO_NOT_USE +# define utrans_open_4_0 utrans_open_DEPRECATED_API_DO_NOT_USE +# define utrans_unregister_4_0 utrans_unregister_DEPRECATED_API_DO_NOT_USE +# endif /* U_DISABLE_RENAMING */ + +#endif /* U_HIDE_DEPRECATED_API */ +#endif /* UDEPRCTD_H */ + diff --git a/utils/openttd/unicode/udraft.h b/utils/openttd/unicode/udraft.h new file mode 100644 index 00000000000..5426adf0f27 --- /dev/null +++ b/utils/openttd/unicode/udraft.h @@ -0,0 +1,166 @@ +/* +******************************************************************************* +* Copyright (C) 2004-2008, International Business Machines +* Corporation and others. All Rights Reserved. +******************************************************************************* +* +* file name: +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* Created by: genheaders.pl, a perl script written by Ram Viswanadha +* +* Contains data for commenting out APIs. +* Gets included by umachine.h +* +* THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT +* YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN! +*/ + +#ifndef UDRAFT_H +#define UDRAFT_H + +#ifdef U_HIDE_DRAFT_API + +# if U_DISABLE_RENAMING +# define afkLanguageCode afkLanguageCode_DRAFT_API_DO_NOT_USE +# define armiScriptCode armiScriptCode_DRAFT_API_DO_NOT_USE +# define u_fclose u_fclose_DRAFT_API_DO_NOT_USE +# define u_feof u_feof_DRAFT_API_DO_NOT_USE +# define u_fflush u_fflush_DRAFT_API_DO_NOT_USE +# define u_fgetConverter u_fgetConverter_DRAFT_API_DO_NOT_USE +# define u_fgetc u_fgetc_DRAFT_API_DO_NOT_USE +# define u_fgetcodepage u_fgetcodepage_DRAFT_API_DO_NOT_USE +# define u_fgetcx u_fgetcx_DRAFT_API_DO_NOT_USE +# define u_fgetfile u_fgetfile_DRAFT_API_DO_NOT_USE +# define u_fgetlocale u_fgetlocale_DRAFT_API_DO_NOT_USE +# define u_fgets u_fgets_DRAFT_API_DO_NOT_USE +# define u_file_read u_file_read_DRAFT_API_DO_NOT_USE +# define u_file_write u_file_write_DRAFT_API_DO_NOT_USE +# define u_finit u_finit_DRAFT_API_DO_NOT_USE +# define u_fopen u_fopen_DRAFT_API_DO_NOT_USE +# define u_fprintf u_fprintf_DRAFT_API_DO_NOT_USE +# define u_fprintf_u u_fprintf_u_DRAFT_API_DO_NOT_USE +# define u_fputc u_fputc_DRAFT_API_DO_NOT_USE +# define u_fputs u_fputs_DRAFT_API_DO_NOT_USE +# define u_frewind u_frewind_DRAFT_API_DO_NOT_USE +# define u_fscanf u_fscanf_DRAFT_API_DO_NOT_USE +# define u_fscanf_u u_fscanf_u_DRAFT_API_DO_NOT_USE +# define u_fsetcodepage u_fsetcodepage_DRAFT_API_DO_NOT_USE +# define u_fsetlocale u_fsetlocale_DRAFT_API_DO_NOT_USE +# define u_fsettransliterator u_fsettransliterator_DRAFT_API_DO_NOT_USE +# define u_fstropen u_fstropen_DRAFT_API_DO_NOT_USE +# define u_fungetc u_fungetc_DRAFT_API_DO_NOT_USE +# define u_snprintf u_snprintf_DRAFT_API_DO_NOT_USE +# define u_snprintf_u u_snprintf_u_DRAFT_API_DO_NOT_USE +# define u_sprintf u_sprintf_DRAFT_API_DO_NOT_USE +# define u_sprintf_u u_sprintf_u_DRAFT_API_DO_NOT_USE +# define u_sscanf u_sscanf_DRAFT_API_DO_NOT_USE +# define u_sscanf_u u_sscanf_u_DRAFT_API_DO_NOT_USE +# define u_vfprintf u_vfprintf_DRAFT_API_DO_NOT_USE +# define u_vfprintf_u u_vfprintf_u_DRAFT_API_DO_NOT_USE +# define u_vfscanf u_vfscanf_DRAFT_API_DO_NOT_USE +# define u_vfscanf_u u_vfscanf_u_DRAFT_API_DO_NOT_USE +# define u_vsnprintf u_vsnprintf_DRAFT_API_DO_NOT_USE +# define u_vsnprintf_u u_vsnprintf_u_DRAFT_API_DO_NOT_USE +# define u_vsprintf u_vsprintf_DRAFT_API_DO_NOT_USE +# define u_vsprintf_u u_vsprintf_u_DRAFT_API_DO_NOT_USE +# define u_vsscanf u_vsscanf_DRAFT_API_DO_NOT_USE +# define u_vsscanf_u u_vsscanf_u_DRAFT_API_DO_NOT_USE +# define ucal_clone ucal_clone_DRAFT_API_DO_NOT_USE +# define ucal_getCanonicalTimeZoneID ucal_getCanonicalTimeZoneID_DRAFT_API_DO_NOT_USE +# define ucurr_countCurrencies ucurr_countCurrencies_DRAFT_API_DO_NOT_USE +# define ucurr_forLocaleAndDate ucurr_forLocaleAndDate_DRAFT_API_DO_NOT_USE +# define uloc_addLikelySubtags uloc_addLikelySubtags_DRAFT_API_DO_NOT_USE +# define uloc_getCharacterOrientation uloc_getCharacterOrientation_DRAFT_API_DO_NOT_USE +# define uloc_getLineOrientation uloc_getLineOrientation_DRAFT_API_DO_NOT_USE +# define uloc_minimizeSubtags uloc_minimizeSubtags_DRAFT_API_DO_NOT_USE +# define uregex_getMatchCallback uregex_getMatchCallback_DRAFT_API_DO_NOT_USE +# define uregex_getStackLimit uregex_getStackLimit_DRAFT_API_DO_NOT_USE +# define uregex_getTimeLimit uregex_getTimeLimit_DRAFT_API_DO_NOT_USE +# define uregex_hasAnchoringBounds uregex_hasAnchoringBounds_DRAFT_API_DO_NOT_USE +# define uregex_hasTransparentBounds uregex_hasTransparentBounds_DRAFT_API_DO_NOT_USE +# define uregex_hitEnd uregex_hitEnd_DRAFT_API_DO_NOT_USE +# define uregex_regionEnd uregex_regionEnd_DRAFT_API_DO_NOT_USE +# define uregex_regionStart uregex_regionStart_DRAFT_API_DO_NOT_USE +# define uregex_requireEnd uregex_requireEnd_DRAFT_API_DO_NOT_USE +# define uregex_setMatchCallback uregex_setMatchCallback_DRAFT_API_DO_NOT_USE +# define uregex_setRegion uregex_setRegion_DRAFT_API_DO_NOT_USE +# define uregex_setStackLimit uregex_setStackLimit_DRAFT_API_DO_NOT_USE +# define uregex_setTimeLimit uregex_setTimeLimit_DRAFT_API_DO_NOT_USE +# define uregex_useAnchoringBounds uregex_useAnchoringBounds_DRAFT_API_DO_NOT_USE +# define uregex_useTransparentBounds uregex_useTransparentBounds_DRAFT_API_DO_NOT_USE +# else +# define afkLanguageCode_4_0 afkLanguageCode_DRAFT_API_DO_NOT_USE +# define armiScriptCode_4_0 armiScriptCode_DRAFT_API_DO_NOT_USE +# define u_fclose_4_0 u_fclose_DRAFT_API_DO_NOT_USE +# define u_feof_4_0 u_feof_DRAFT_API_DO_NOT_USE +# define u_fflush_4_0 u_fflush_DRAFT_API_DO_NOT_USE +# define u_fgetConverter_4_0 u_fgetConverter_DRAFT_API_DO_NOT_USE +# define u_fgetc_4_0 u_fgetc_DRAFT_API_DO_NOT_USE +# define u_fgetcodepage_4_0 u_fgetcodepage_DRAFT_API_DO_NOT_USE +# define u_fgetcx_4_0 u_fgetcx_DRAFT_API_DO_NOT_USE +# define u_fgetfile_4_0 u_fgetfile_DRAFT_API_DO_NOT_USE +# define u_fgetlocale_4_0 u_fgetlocale_DRAFT_API_DO_NOT_USE +# define u_fgets_4_0 u_fgets_DRAFT_API_DO_NOT_USE +# define u_file_read_4_0 u_file_read_DRAFT_API_DO_NOT_USE +# define u_file_write_4_0 u_file_write_DRAFT_API_DO_NOT_USE +# define u_finit_4_0 u_finit_DRAFT_API_DO_NOT_USE +# define u_fopen_4_0 u_fopen_DRAFT_API_DO_NOT_USE +# define u_fprintf_4_0 u_fprintf_DRAFT_API_DO_NOT_USE +# define u_fprintf_u_4_0 u_fprintf_u_DRAFT_API_DO_NOT_USE +# define u_fputc_4_0 u_fputc_DRAFT_API_DO_NOT_USE +# define u_fputs_4_0 u_fputs_DRAFT_API_DO_NOT_USE +# define u_frewind_4_0 u_frewind_DRAFT_API_DO_NOT_USE +# define u_fscanf_4_0 u_fscanf_DRAFT_API_DO_NOT_USE +# define u_fscanf_u_4_0 u_fscanf_u_DRAFT_API_DO_NOT_USE +# define u_fsetcodepage_4_0 u_fsetcodepage_DRAFT_API_DO_NOT_USE +# define u_fsetlocale_4_0 u_fsetlocale_DRAFT_API_DO_NOT_USE +# define u_fsettransliterator_4_0 u_fsettransliterator_DRAFT_API_DO_NOT_USE +# define u_fstropen_4_0 u_fstropen_DRAFT_API_DO_NOT_USE +# define u_fungetc_4_0 u_fungetc_DRAFT_API_DO_NOT_USE +# define u_snprintf_4_0 u_snprintf_DRAFT_API_DO_NOT_USE +# define u_snprintf_u_4_0 u_snprintf_u_DRAFT_API_DO_NOT_USE +# define u_sprintf_4_0 u_sprintf_DRAFT_API_DO_NOT_USE +# define u_sprintf_u_4_0 u_sprintf_u_DRAFT_API_DO_NOT_USE +# define u_sscanf_4_0 u_sscanf_DRAFT_API_DO_NOT_USE +# define u_sscanf_u_4_0 u_sscanf_u_DRAFT_API_DO_NOT_USE +# define u_vfprintf_4_0 u_vfprintf_DRAFT_API_DO_NOT_USE +# define u_vfprintf_u_4_0 u_vfprintf_u_DRAFT_API_DO_NOT_USE +# define u_vfscanf_4_0 u_vfscanf_DRAFT_API_DO_NOT_USE +# define u_vfscanf_u_4_0 u_vfscanf_u_DRAFT_API_DO_NOT_USE +# define u_vsnprintf_4_0 u_vsnprintf_DRAFT_API_DO_NOT_USE +# define u_vsnprintf_u_4_0 u_vsnprintf_u_DRAFT_API_DO_NOT_USE +# define u_vsprintf_4_0 u_vsprintf_DRAFT_API_DO_NOT_USE +# define u_vsprintf_u_4_0 u_vsprintf_u_DRAFT_API_DO_NOT_USE +# define u_vsscanf_4_0 u_vsscanf_DRAFT_API_DO_NOT_USE +# define u_vsscanf_u_4_0 u_vsscanf_u_DRAFT_API_DO_NOT_USE +# define ucal_clone_4_0 ucal_clone_DRAFT_API_DO_NOT_USE +# define ucal_getCanonicalTimeZoneID_4_0 ucal_getCanonicalTimeZoneID_DRAFT_API_DO_NOT_USE +# define ucurr_countCurrencies_4_0 ucurr_countCurrencies_DRAFT_API_DO_NOT_USE +# define ucurr_forLocaleAndDate_4_0 ucurr_forLocaleAndDate_DRAFT_API_DO_NOT_USE +# define uloc_addLikelySubtags_4_0 uloc_addLikelySubtags_DRAFT_API_DO_NOT_USE +# define uloc_getCharacterOrientation_4_0 uloc_getCharacterOrientation_DRAFT_API_DO_NOT_USE +# define uloc_getLineOrientation_4_0 uloc_getLineOrientation_DRAFT_API_DO_NOT_USE +# define uloc_minimizeSubtags_4_0 uloc_minimizeSubtags_DRAFT_API_DO_NOT_USE +# define uregex_getMatchCallback_4_0 uregex_getMatchCallback_DRAFT_API_DO_NOT_USE +# define uregex_getStackLimit_4_0 uregex_getStackLimit_DRAFT_API_DO_NOT_USE +# define uregex_getTimeLimit_4_0 uregex_getTimeLimit_DRAFT_API_DO_NOT_USE +# define uregex_hasAnchoringBounds_4_0 uregex_hasAnchoringBounds_DRAFT_API_DO_NOT_USE +# define uregex_hasTransparentBounds_4_0 uregex_hasTransparentBounds_DRAFT_API_DO_NOT_USE +# define uregex_hitEnd_4_0 uregex_hitEnd_DRAFT_API_DO_NOT_USE +# define uregex_regionEnd_4_0 uregex_regionEnd_DRAFT_API_DO_NOT_USE +# define uregex_regionStart_4_0 uregex_regionStart_DRAFT_API_DO_NOT_USE +# define uregex_requireEnd_4_0 uregex_requireEnd_DRAFT_API_DO_NOT_USE +# define uregex_setMatchCallback_4_0 uregex_setMatchCallback_DRAFT_API_DO_NOT_USE +# define uregex_setRegion_4_0 uregex_setRegion_DRAFT_API_DO_NOT_USE +# define uregex_setStackLimit_4_0 uregex_setStackLimit_DRAFT_API_DO_NOT_USE +# define uregex_setTimeLimit_4_0 uregex_setTimeLimit_DRAFT_API_DO_NOT_USE +# define uregex_useAnchoringBounds_4_0 uregex_useAnchoringBounds_DRAFT_API_DO_NOT_USE +# define uregex_useTransparentBounds_4_0 uregex_useTransparentBounds_DRAFT_API_DO_NOT_USE +# endif /* U_DISABLE_RENAMING */ + +#endif /* U_HIDE_DRAFT_API */ +#endif /* UDRAFT_H */ + diff --git a/utils/openttd/unicode/uenum.h b/utils/openttd/unicode/uenum.h new file mode 100644 index 00000000000..ff9b29997e9 --- /dev/null +++ b/utils/openttd/unicode/uenum.h @@ -0,0 +1,134 @@ +/* +******************************************************************************* +* +* Copyright (C) 2002-2005, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: uenum.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:2 +* +* created on: 2002jul08 +* created by: Vladimir Weinstein +*/ + +#ifndef __UENUM_H +#define __UENUM_H + +#include "unicode/utypes.h" + +/** + * \file + * \brief C API: String Enumeration + */ + +/** + * An enumeration object. + * For usage in C programs. + * @stable ICU 2.2 + */ +struct UEnumeration; +/** structure representing an enumeration object instance @stable ICU 2.2 */ +typedef struct UEnumeration UEnumeration; + +/** + * Disposes of resources in use by the iterator. If en is NULL, + * does nothing. After this call, any char* or UChar* pointer + * returned by uenum_unext() or uenum_next() is invalid. + * @param en UEnumeration structure pointer + * @stable ICU 2.2 + */ +U_STABLE void U_EXPORT2 +uenum_close(UEnumeration* en); + +/** + * Returns the number of elements that the iterator traverses. If + * the iterator is out-of-sync with its service, status is set to + * U_ENUM_OUT_OF_SYNC_ERROR. + * This is a convenience function. It can end up being very + * expensive as all the items might have to be pre-fetched (depending + * on the type of data being traversed). Use with caution and only + * when necessary. + * @param en UEnumeration structure pointer + * @param status error code, can be U_ENUM_OUT_OF_SYNC_ERROR if the + * iterator is out of sync. + * @return number of elements in the iterator + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +uenum_count(UEnumeration* en, UErrorCode* status); + +/** + * Returns the next element in the iterator's list. If there are + * no more elements, returns NULL. If the iterator is out-of-sync + * with its service, status is set to U_ENUM_OUT_OF_SYNC_ERROR and + * NULL is returned. If the native service string is a char* string, + * it is converted to UChar* with the invariant converter. + * The result is terminated by (UChar)0. + * @param en the iterator object + * @param resultLength pointer to receive the length of the result + * (not including the terminating \\0). + * If the pointer is NULL it is ignored. + * @param status the error code, set to U_ENUM_OUT_OF_SYNC_ERROR if + * the iterator is out of sync with its service. + * @return a pointer to the string. The string will be + * zero-terminated. The return pointer is owned by this iterator + * and must not be deleted by the caller. The pointer is valid + * until the next call to any uenum_... method, including + * uenum_next() or uenum_unext(). When all strings have been + * traversed, returns NULL. + * @stable ICU 2.2 + */ +U_STABLE const UChar* U_EXPORT2 +uenum_unext(UEnumeration* en, + int32_t* resultLength, + UErrorCode* status); + +/** + * Returns the next element in the iterator's list. If there are + * no more elements, returns NULL. If the iterator is out-of-sync + * with its service, status is set to U_ENUM_OUT_OF_SYNC_ERROR and + * NULL is returned. If the native service string is a UChar* + * string, it is converted to char* with the invariant converter. + * The result is terminated by (char)0. If the conversion fails + * (because a character cannot be converted) then status is set to + * U_INVARIANT_CONVERSION_ERROR and the return value is undefined + * (but non-NULL). + * @param en the iterator object + * @param resultLength pointer to receive the length of the result + * (not including the terminating \\0). + * If the pointer is NULL it is ignored. + * @param status the error code, set to U_ENUM_OUT_OF_SYNC_ERROR if + * the iterator is out of sync with its service. Set to + * U_INVARIANT_CONVERSION_ERROR if the underlying native string is + * UChar* and conversion to char* with the invariant converter + * fails. This error pertains only to current string, so iteration + * might be able to continue successfully. + * @return a pointer to the string. The string will be + * zero-terminated. The return pointer is owned by this iterator + * and must not be deleted by the caller. The pointer is valid + * until the next call to any uenum_... method, including + * uenum_next() or uenum_unext(). When all strings have been + * traversed, returns NULL. + * @stable ICU 2.2 + */ +U_STABLE const char* U_EXPORT2 +uenum_next(UEnumeration* en, + int32_t* resultLength, + UErrorCode* status); + +/** + * Resets the iterator to the current list of service IDs. This + * re-establishes sync with the service and rewinds the iterator + * to start at the first element. + * @param en the iterator object + * @param status the error code, set to U_ENUM_OUT_OF_SYNC_ERROR if + * the iterator is out of sync with its service. + * @stable ICU 2.2 + */ +U_STABLE void U_EXPORT2 +uenum_reset(UEnumeration* en, UErrorCode* status); + +#endif diff --git a/utils/openttd/unicode/uidna.h b/utils/openttd/unicode/uidna.h new file mode 100644 index 00000000000..52aa6e9104e --- /dev/null +++ b/utils/openttd/unicode/uidna.h @@ -0,0 +1,312 @@ +/* + ******************************************************************************* + * + * Copyright (C) 2003-2007, International Business Machines + * Corporation and others. All Rights Reserved. + * + ******************************************************************************* + * file name: uidna.h + * encoding: US-ASCII + * tab size: 8 (not used) + * indentation:4 + * + * created on: 2003feb1 + * created by: Ram Viswanadha + */ + +#ifndef __UIDNA_H__ +#define __UIDNA_H__ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_IDNA + +#include "unicode/parseerr.h" + +/** + * \file + * \brief C API: Internationalized Domain Names in Applications Tranformation + * + * UIDNA API implements the IDNA protocol as defined in the IDNA RFC + * (http://www.ietf.org/rfc/rfc3490.txt). + * The RFC defines 2 operations: ToASCII and ToUnicode. Domain labels + * containing non-ASCII code points are required to be processed by + * ToASCII operation before passing it to resolver libraries. Domain names + * that are obtained from resolver libraries are required to be processed by + * ToUnicode operation before displaying the domain name to the user. + * IDNA requires that implementations process input strings with Nameprep + * (http://www.ietf.org/rfc/rfc3491.txt), + * which is a profile of Stringprep (http://www.ietf.org/rfc/rfc3454.txt), + * and then with Punycode (http://www.ietf.org/rfc/rfc3492.txt). + * Implementations of IDNA MUST fully implement Nameprep and Punycode; + * neither Nameprep nor Punycode are optional. + * The input and output of ToASCII and ToUnicode operations are Unicode + * and are designed to be chainable, i.e., applying ToASCII or ToUnicode operations + * multiple times to an input string will yield the same result as applying the operation + * once. + * ToUnicode(ToUnicode(ToUnicode...(ToUnicode(string)))) == ToUnicode(string) + * ToASCII(ToASCII(ToASCII...(ToASCII(string))) == ToASCII(string). + * + */ + +/** + * Option to prohibit processing of unassigned codepoints in the input and + * do not check if the input conforms to STD-3 ASCII rules. + * + * @see uidna_toASCII uidna_toUnicode + * @stable ICU 2.6 + */ +#define UIDNA_DEFAULT 0x0000 +/** + * Option to allow processing of unassigned codepoints in the input + * + * @see uidna_toASCII uidna_toUnicode + * @stable ICU 2.6 + */ +#define UIDNA_ALLOW_UNASSIGNED 0x0001 +/** + * Option to check if input conforms to STD-3 ASCII rules + * + * @see uidna_toASCII uidna_toUnicode + * @stable ICU 2.6 + */ +#define UIDNA_USE_STD3_RULES 0x0002 + +/** + * This function implements the ToASCII operation as defined in the IDNA RFC. + * This operation is done on <b>single labels</b> before sending it to something that expects + * ASCII names. A label is an individual part of a domain name. Labels are usually + * separated by dots; e.g." "www.example.com" is composed of 3 labels + * "www","example", and "com". + * + * + * @param src Input UChar array containing label in Unicode. + * @param srcLength Number of UChars in src, or -1 if NUL-terminated. + * @param dest Output UChar array with ASCII (ACE encoded) label. + * @param destCapacity Size of dest. + * @param options A bit set of options: + * + * - UIDNA_DEFAULT Use default options, i.e., do not process unassigned code points + * and do not use STD3 ASCII rules + * If unassigned code points are found the operation fails with + * U_UNASSIGNED_ERROR error code. + * + * - UIDNA_ALLOW_UNASSIGNED Unassigned values can be converted to ASCII for query operations + * If this option is set, the unassigned code points are in the input + * are treated as normal Unicode code points. + * + * - UIDNA_USE_STD3_RULES Use STD3 ASCII rules for host name syntax restrictions + * If this option is set and the input does not satisfy STD3 rules, + * the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR + * + * @param parseError Pointer to UParseError struct to receive information on position + * of error if an error is encountered. Can be NULL. + * @param status ICU in/out error code parameter. + * U_INVALID_CHAR_FOUND if src contains + * unmatched single surrogates. + * U_INDEX_OUTOFBOUNDS_ERROR if src contains + * too many code points. + * U_BUFFER_OVERFLOW_ERROR if destCapacity is not enough + * @return The length of the result string, if successful - or in case of a buffer overflow, + * in which case it will be greater than destCapacity. + * @stable ICU 2.6 + */ +U_STABLE int32_t U_EXPORT2 +uidna_toASCII(const UChar* src, int32_t srcLength, + UChar* dest, int32_t destCapacity, + int32_t options, + UParseError* parseError, + UErrorCode* status); + + +/** + * This function implements the ToUnicode operation as defined in the IDNA RFC. + * This operation is done on <b>single labels</b> before sending it to something that expects + * Unicode names. A label is an individual part of a domain name. Labels are usually + * separated by dots; for e.g." "www.example.com" is composed of 3 labels + * "www","example", and "com". + * + * @param src Input UChar array containing ASCII (ACE encoded) label. + * @param srcLength Number of UChars in src, or -1 if NUL-terminated. + * @param dest Output Converted UChar array containing Unicode equivalent of label. + * @param destCapacity Size of dest. + * @param options A bit set of options: + * + * - UIDNA_DEFAULT Use default options, i.e., do not process unassigned code points + * and do not use STD3 ASCII rules + * If unassigned code points are found the operation fails with + * U_UNASSIGNED_ERROR error code. + * + * - UIDNA_ALLOW_UNASSIGNED Unassigned values can be converted to ASCII for query operations + * If this option is set, the unassigned code points are in the input + * are treated as normal Unicode code points. <b> Note: </b> This option is + * required on toUnicode operation because the RFC mandates + * verification of decoded ACE input by applying toASCII and comparing + * its output with source + * + * + * + * - UIDNA_USE_STD3_RULES Use STD3 ASCII rules for host name syntax restrictions + * If this option is set and the input does not satisfy STD3 rules, + * the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR + * + * @param parseError Pointer to UParseError struct to receive information on position + * of error if an error is encountered. Can be NULL. + * @param status ICU in/out error code parameter. + * U_INVALID_CHAR_FOUND if src contains + * unmatched single surrogates. + * U_INDEX_OUTOFBOUNDS_ERROR if src contains + * too many code points. + * U_BUFFER_OVERFLOW_ERROR if destCapacity is not enough + * @return The length of the result string, if successful - or in case of a buffer overflow, + * in which case it will be greater than destCapacity. + * @stable ICU 2.6 + */ +U_STABLE int32_t U_EXPORT2 +uidna_toUnicode(const UChar* src, int32_t srcLength, + UChar* dest, int32_t destCapacity, + int32_t options, + UParseError* parseError, + UErrorCode* status); + + +/** + * Convenience function that implements the IDNToASCII operation as defined in the IDNA RFC. + * This operation is done on complete domain names, e.g: "www.example.com". + * It is important to note that this operation can fail. If it fails, then the input + * domain name cannot be used as an Internationalized Domain Name and the application + * should have methods defined to deal with the failure. + * + * <b>Note:</b> IDNA RFC specifies that a conformant application should divide a domain name + * into separate labels, decide whether to apply allowUnassigned and useSTD3ASCIIRules on each, + * and then convert. This function does not offer that level of granularity. The options once + * set will apply to all labels in the domain name + * + * @param src Input UChar array containing IDN in Unicode. + * @param srcLength Number of UChars in src, or -1 if NUL-terminated. + * @param dest Output UChar array with ASCII (ACE encoded) IDN. + * @param destCapacity Size of dest. + * @param options A bit set of options: + * + * - UIDNA_DEFAULT Use default options, i.e., do not process unassigned code points + * and do not use STD3 ASCII rules + * If unassigned code points are found the operation fails with + * U_UNASSIGNED_CODE_POINT_FOUND error code. + * + * - UIDNA_ALLOW_UNASSIGNED Unassigned values can be converted to ASCII for query operations + * If this option is set, the unassigned code points are in the input + * are treated as normal Unicode code points. + * + * - UIDNA_USE_STD3_RULES Use STD3 ASCII rules for host name syntax restrictions + * If this option is set and the input does not satisfy STD3 rules, + * the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR + * + * @param parseError Pointer to UParseError struct to receive information on position + * of error if an error is encountered. Can be NULL. + * @param status ICU in/out error code parameter. + * U_INVALID_CHAR_FOUND if src contains + * unmatched single surrogates. + * U_INDEX_OUTOFBOUNDS_ERROR if src contains + * too many code points. + * U_BUFFER_OVERFLOW_ERROR if destCapacity is not enough + * @return The length of the result string, if successful - or in case of a buffer overflow, + * in which case it will be greater than destCapacity. + * @stable ICU 2.6 + */ +U_STABLE int32_t U_EXPORT2 +uidna_IDNToASCII( const UChar* src, int32_t srcLength, + UChar* dest, int32_t destCapacity, + int32_t options, + UParseError* parseError, + UErrorCode* status); + +/** + * Convenience function that implements the IDNToUnicode operation as defined in the IDNA RFC. + * This operation is done on complete domain names, e.g: "www.example.com". + * + * <b>Note:</b> IDNA RFC specifies that a conformant application should divide a domain name + * into separate labels, decide whether to apply allowUnassigned and useSTD3ASCIIRules on each, + * and then convert. This function does not offer that level of granularity. The options once + * set will apply to all labels in the domain name + * + * @param src Input UChar array containing IDN in ASCII (ACE encoded) form. + * @param srcLength Number of UChars in src, or -1 if NUL-terminated. + * @param dest Output UChar array containing Unicode equivalent of source IDN. + * @param destCapacity Size of dest. + * @param options A bit set of options: + * + * - UIDNA_DEFAULT Use default options, i.e., do not process unassigned code points + * and do not use STD3 ASCII rules + * If unassigned code points are found the operation fails with + * U_UNASSIGNED_CODE_POINT_FOUND error code. + * + * - UIDNA_ALLOW_UNASSIGNED Unassigned values can be converted to ASCII for query operations + * If this option is set, the unassigned code points are in the input + * are treated as normal Unicode code points. + * + * - UIDNA_USE_STD3_RULES Use STD3 ASCII rules for host name syntax restrictions + * If this option is set and the input does not satisfy STD3 rules, + * the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR + * + * @param parseError Pointer to UParseError struct to receive information on position + * of error if an error is encountered. Can be NULL. + * @param status ICU in/out error code parameter. + * U_INVALID_CHAR_FOUND if src contains + * unmatched single surrogates. + * U_INDEX_OUTOFBOUNDS_ERROR if src contains + * too many code points. + * U_BUFFER_OVERFLOW_ERROR if destCapacity is not enough + * @return The length of the result string, if successful - or in case of a buffer overflow, + * in which case it will be greater than destCapacity. + * @stable ICU 2.6 + */ +U_STABLE int32_t U_EXPORT2 +uidna_IDNToUnicode( const UChar* src, int32_t srcLength, + UChar* dest, int32_t destCapacity, + int32_t options, + UParseError* parseError, + UErrorCode* status); + +/** + * Compare two IDN strings for equivalence. + * This function splits the domain names into labels and compares them. + * According to IDN RFC, whenever two labels are compared, they are + * considered equal if and only if their ASCII forms (obtained by + * applying toASCII) match using an case-insensitive ASCII comparison. + * Two domain names are considered a match if and only if all labels + * match regardless of whether label separators match. + * + * @param s1 First source string. + * @param length1 Length of first source string, or -1 if NUL-terminated. + * + * @param s2 Second source string. + * @param length2 Length of second source string, or -1 if NUL-terminated. + * @param options A bit set of options: + * + * - UIDNA_DEFAULT Use default options, i.e., do not process unassigned code points + * and do not use STD3 ASCII rules + * If unassigned code points are found the operation fails with + * U_UNASSIGNED_CODE_POINT_FOUND error code. + * + * - UIDNA_ALLOW_UNASSIGNED Unassigned values can be converted to ASCII for query operations + * If this option is set, the unassigned code points are in the input + * are treated as normal Unicode code points. + * + * - UIDNA_USE_STD3_RULES Use STD3 ASCII rules for host name syntax restrictions + * If this option is set and the input does not satisfy STD3 rules, + * the operation will fail with U_IDNA_STD3_ASCII_RULES_ERROR + * + * @param status ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return <0 or 0 or >0 as usual for string comparisons + * @stable ICU 2.6 + */ +U_STABLE int32_t U_EXPORT2 +uidna_compare( const UChar *s1, int32_t length1, + const UChar *s2, int32_t length2, + int32_t options, + UErrorCode* status); + +#endif /* #if !UCONFIG_NO_IDNA */ + +#endif diff --git a/utils/openttd/unicode/uintrnal.h b/utils/openttd/unicode/uintrnal.h new file mode 100644 index 00000000000..6a01f6b0c2a --- /dev/null +++ b/utils/openttd/unicode/uintrnal.h @@ -0,0 +1,180 @@ +/* +******************************************************************************* +* Copyright (C) 2004-2008, International Business Machines +* Corporation and others. All Rights Reserved. +******************************************************************************* +* +* file name: +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* Created by: genheaders.pl, a perl script written by Ram Viswanadha +* +* Contains data for commenting out APIs. +* Gets included by umachine.h +* +* THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT +* YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN! +*/ + +#ifndef UINTRNAL_H +#define UINTRNAL_H + +#ifdef U_HIDE_INTERNAL_API + +# if U_DISABLE_RENAMING +# define RegexPatternDump RegexPatternDump_INTERNAL_API_DO_NOT_USE +# define pl_addFontRun pl_addFontRun_INTERNAL_API_DO_NOT_USE +# define pl_addLocaleRun pl_addLocaleRun_INTERNAL_API_DO_NOT_USE +# define pl_addValueRun pl_addValueRun_INTERNAL_API_DO_NOT_USE +# define pl_close pl_close_INTERNAL_API_DO_NOT_USE +# define pl_closeFontRuns pl_closeFontRuns_INTERNAL_API_DO_NOT_USE +# define pl_closeLine pl_closeLine_INTERNAL_API_DO_NOT_USE +# define pl_closeLocaleRuns pl_closeLocaleRuns_INTERNAL_API_DO_NOT_USE +# define pl_closeValueRuns pl_closeValueRuns_INTERNAL_API_DO_NOT_USE +# define pl_countLineRuns pl_countLineRuns_INTERNAL_API_DO_NOT_USE +# define pl_create pl_create_INTERNAL_API_DO_NOT_USE +# define pl_getAscent pl_getAscent_INTERNAL_API_DO_NOT_USE +# define pl_getDescent pl_getDescent_INTERNAL_API_DO_NOT_USE +# define pl_getFontRunCount pl_getFontRunCount_INTERNAL_API_DO_NOT_USE +# define pl_getFontRunFont pl_getFontRunFont_INTERNAL_API_DO_NOT_USE +# define pl_getFontRunLastLimit pl_getFontRunLastLimit_INTERNAL_API_DO_NOT_USE +# define pl_getFontRunLimit pl_getFontRunLimit_INTERNAL_API_DO_NOT_USE +# define pl_getLeading pl_getLeading_INTERNAL_API_DO_NOT_USE +# define pl_getLineAscent pl_getLineAscent_INTERNAL_API_DO_NOT_USE +# define pl_getLineDescent pl_getLineDescent_INTERNAL_API_DO_NOT_USE +# define pl_getLineLeading pl_getLineLeading_INTERNAL_API_DO_NOT_USE +# define pl_getLineVisualRun pl_getLineVisualRun_INTERNAL_API_DO_NOT_USE +# define pl_getLineWidth pl_getLineWidth_INTERNAL_API_DO_NOT_USE +# define pl_getLocaleRunCount pl_getLocaleRunCount_INTERNAL_API_DO_NOT_USE +# define pl_getLocaleRunLastLimit pl_getLocaleRunLastLimit_INTERNAL_API_DO_NOT_USE +# define pl_getLocaleRunLimit pl_getLocaleRunLimit_INTERNAL_API_DO_NOT_USE +# define pl_getLocaleRunLocale pl_getLocaleRunLocale_INTERNAL_API_DO_NOT_USE +# define pl_getParagraphLevel pl_getParagraphLevel_INTERNAL_API_DO_NOT_USE +# define pl_getTextDirection pl_getTextDirection_INTERNAL_API_DO_NOT_USE +# define pl_getValueRunCount pl_getValueRunCount_INTERNAL_API_DO_NOT_USE +# define pl_getValueRunLastLimit pl_getValueRunLastLimit_INTERNAL_API_DO_NOT_USE +# define pl_getValueRunLimit pl_getValueRunLimit_INTERNAL_API_DO_NOT_USE +# define pl_getValueRunValue pl_getValueRunValue_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunAscent pl_getVisualRunAscent_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunDescent pl_getVisualRunDescent_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunDirection pl_getVisualRunDirection_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunFont pl_getVisualRunFont_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunGlyphCount pl_getVisualRunGlyphCount_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunGlyphToCharMap pl_getVisualRunGlyphToCharMap_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunGlyphs pl_getVisualRunGlyphs_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunLeading pl_getVisualRunLeading_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunPositions pl_getVisualRunPositions_INTERNAL_API_DO_NOT_USE +# define pl_isComplex pl_isComplex_INTERNAL_API_DO_NOT_USE +# define pl_line pl_line_INTERNAL_API_DO_NOT_USE +# define pl_nextLine pl_nextLine_INTERNAL_API_DO_NOT_USE +# define pl_openEmptyFontRuns pl_openEmptyFontRuns_INTERNAL_API_DO_NOT_USE +# define pl_openEmptyLocaleRuns pl_openEmptyLocaleRuns_INTERNAL_API_DO_NOT_USE +# define pl_openEmptyValueRuns pl_openEmptyValueRuns_INTERNAL_API_DO_NOT_USE +# define pl_openFontRuns pl_openFontRuns_INTERNAL_API_DO_NOT_USE +# define pl_openLocaleRuns pl_openLocaleRuns_INTERNAL_API_DO_NOT_USE +# define pl_openValueRuns pl_openValueRuns_INTERNAL_API_DO_NOT_USE +# define pl_paragraph pl_paragraph_INTERNAL_API_DO_NOT_USE +# define pl_reflow pl_reflow_INTERNAL_API_DO_NOT_USE +# define pl_resetFontRuns pl_resetFontRuns_INTERNAL_API_DO_NOT_USE +# define pl_resetLocaleRuns pl_resetLocaleRuns_INTERNAL_API_DO_NOT_USE +# define pl_resetValueRuns pl_resetValueRuns_INTERNAL_API_DO_NOT_USE +# define pl_visualRun pl_visualRun_INTERNAL_API_DO_NOT_USE +# define ucol_equals ucol_equals_INTERNAL_API_DO_NOT_USE +# define ucol_forgetUCA ucol_forgetUCA_INTERNAL_API_DO_NOT_USE +# define ucol_getAttributeOrDefault ucol_getAttributeOrDefault_INTERNAL_API_DO_NOT_USE +# define ucol_getUnsafeSet ucol_getUnsafeSet_INTERNAL_API_DO_NOT_USE +# define ucol_nextProcessed ucol_nextProcessed_INTERNAL_API_DO_NOT_USE +# define ucol_prepareShortStringOpen ucol_prepareShortStringOpen_INTERNAL_API_DO_NOT_USE +# define ucol_previousProcessed ucol_previousProcessed_INTERNAL_API_DO_NOT_USE +# define uprv_getDefaultCodepage uprv_getDefaultCodepage_INTERNAL_API_DO_NOT_USE +# define uprv_getDefaultLocaleID uprv_getDefaultLocaleID_INTERNAL_API_DO_NOT_USE +# define ures_openFillIn ures_openFillIn_INTERNAL_API_DO_NOT_USE +# define usearch_search usearch_search_INTERNAL_API_DO_NOT_USE +# define usearch_searchBackwards usearch_searchBackwards_INTERNAL_API_DO_NOT_USE +# define utf8_appendCharSafeBody utf8_appendCharSafeBody_INTERNAL_API_DO_NOT_USE +# define utf8_back1SafeBody utf8_back1SafeBody_INTERNAL_API_DO_NOT_USE +# define utf8_countTrailBytes utf8_countTrailBytes_INTERNAL_API_DO_NOT_USE +# define utf8_nextCharSafeBody utf8_nextCharSafeBody_INTERNAL_API_DO_NOT_USE +# define utf8_prevCharSafeBody utf8_prevCharSafeBody_INTERNAL_API_DO_NOT_USE +# else +# define RegexPatternDump_4_0 RegexPatternDump_INTERNAL_API_DO_NOT_USE +# define pl_addFontRun_4_0 pl_addFontRun_INTERNAL_API_DO_NOT_USE +# define pl_addLocaleRun_4_0 pl_addLocaleRun_INTERNAL_API_DO_NOT_USE +# define pl_addValueRun_4_0 pl_addValueRun_INTERNAL_API_DO_NOT_USE +# define pl_closeFontRuns_4_0 pl_closeFontRuns_INTERNAL_API_DO_NOT_USE +# define pl_closeLine_4_0 pl_closeLine_INTERNAL_API_DO_NOT_USE +# define pl_closeLocaleRuns_4_0 pl_closeLocaleRuns_INTERNAL_API_DO_NOT_USE +# define pl_closeValueRuns_4_0 pl_closeValueRuns_INTERNAL_API_DO_NOT_USE +# define pl_close_4_0 pl_close_INTERNAL_API_DO_NOT_USE +# define pl_countLineRuns_4_0 pl_countLineRuns_INTERNAL_API_DO_NOT_USE +# define pl_create_4_0 pl_create_INTERNAL_API_DO_NOT_USE +# define pl_getAscent_4_0 pl_getAscent_INTERNAL_API_DO_NOT_USE +# define pl_getDescent_4_0 pl_getDescent_INTERNAL_API_DO_NOT_USE +# define pl_getFontRunCount_4_0 pl_getFontRunCount_INTERNAL_API_DO_NOT_USE +# define pl_getFontRunFont_4_0 pl_getFontRunFont_INTERNAL_API_DO_NOT_USE +# define pl_getFontRunLastLimit_4_0 pl_getFontRunLastLimit_INTERNAL_API_DO_NOT_USE +# define pl_getFontRunLimit_4_0 pl_getFontRunLimit_INTERNAL_API_DO_NOT_USE +# define pl_getLeading_4_0 pl_getLeading_INTERNAL_API_DO_NOT_USE +# define pl_getLineAscent_4_0 pl_getLineAscent_INTERNAL_API_DO_NOT_USE +# define pl_getLineDescent_4_0 pl_getLineDescent_INTERNAL_API_DO_NOT_USE +# define pl_getLineLeading_4_0 pl_getLineLeading_INTERNAL_API_DO_NOT_USE +# define pl_getLineVisualRun_4_0 pl_getLineVisualRun_INTERNAL_API_DO_NOT_USE +# define pl_getLineWidth_4_0 pl_getLineWidth_INTERNAL_API_DO_NOT_USE +# define pl_getLocaleRunCount_4_0 pl_getLocaleRunCount_INTERNAL_API_DO_NOT_USE +# define pl_getLocaleRunLastLimit_4_0 pl_getLocaleRunLastLimit_INTERNAL_API_DO_NOT_USE +# define pl_getLocaleRunLimit_4_0 pl_getLocaleRunLimit_INTERNAL_API_DO_NOT_USE +# define pl_getLocaleRunLocale_4_0 pl_getLocaleRunLocale_INTERNAL_API_DO_NOT_USE +# define pl_getParagraphLevel_4_0 pl_getParagraphLevel_INTERNAL_API_DO_NOT_USE +# define pl_getTextDirection_4_0 pl_getTextDirection_INTERNAL_API_DO_NOT_USE +# define pl_getValueRunCount_4_0 pl_getValueRunCount_INTERNAL_API_DO_NOT_USE +# define pl_getValueRunLastLimit_4_0 pl_getValueRunLastLimit_INTERNAL_API_DO_NOT_USE +# define pl_getValueRunLimit_4_0 pl_getValueRunLimit_INTERNAL_API_DO_NOT_USE +# define pl_getValueRunValue_4_0 pl_getValueRunValue_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunAscent_4_0 pl_getVisualRunAscent_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunDescent_4_0 pl_getVisualRunDescent_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunDirection_4_0 pl_getVisualRunDirection_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunFont_4_0 pl_getVisualRunFont_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunGlyphCount_4_0 pl_getVisualRunGlyphCount_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunGlyphToCharMap_4_0 pl_getVisualRunGlyphToCharMap_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunGlyphs_4_0 pl_getVisualRunGlyphs_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunLeading_4_0 pl_getVisualRunLeading_INTERNAL_API_DO_NOT_USE +# define pl_getVisualRunPositions_4_0 pl_getVisualRunPositions_INTERNAL_API_DO_NOT_USE +# define pl_isComplex_4_0 pl_isComplex_INTERNAL_API_DO_NOT_USE +# define pl_line_4_0 pl_line_INTERNAL_API_DO_NOT_USE +# define pl_nextLine_4_0 pl_nextLine_INTERNAL_API_DO_NOT_USE +# define pl_openEmptyFontRuns_4_0 pl_openEmptyFontRuns_INTERNAL_API_DO_NOT_USE +# define pl_openEmptyLocaleRuns_4_0 pl_openEmptyLocaleRuns_INTERNAL_API_DO_NOT_USE +# define pl_openEmptyValueRuns_4_0 pl_openEmptyValueRuns_INTERNAL_API_DO_NOT_USE +# define pl_openFontRuns_4_0 pl_openFontRuns_INTERNAL_API_DO_NOT_USE +# define pl_openLocaleRuns_4_0 pl_openLocaleRuns_INTERNAL_API_DO_NOT_USE +# define pl_openValueRuns_4_0 pl_openValueRuns_INTERNAL_API_DO_NOT_USE +# define pl_paragraph_4_0 pl_paragraph_INTERNAL_API_DO_NOT_USE +# define pl_reflow_4_0 pl_reflow_INTERNAL_API_DO_NOT_USE +# define pl_resetFontRuns_4_0 pl_resetFontRuns_INTERNAL_API_DO_NOT_USE +# define pl_resetLocaleRuns_4_0 pl_resetLocaleRuns_INTERNAL_API_DO_NOT_USE +# define pl_resetValueRuns_4_0 pl_resetValueRuns_INTERNAL_API_DO_NOT_USE +# define pl_visualRun_4_0 pl_visualRun_INTERNAL_API_DO_NOT_USE +# define ucol_equals_4_0 ucol_equals_INTERNAL_API_DO_NOT_USE +# define ucol_forgetUCA_4_0 ucol_forgetUCA_INTERNAL_API_DO_NOT_USE +# define ucol_getAttributeOrDefault_4_0 ucol_getAttributeOrDefault_INTERNAL_API_DO_NOT_USE +# define ucol_getUnsafeSet_4_0 ucol_getUnsafeSet_INTERNAL_API_DO_NOT_USE +# define ucol_nextProcessed_4_0 ucol_nextProcessed_INTERNAL_API_DO_NOT_USE +# define ucol_prepareShortStringOpen_4_0 ucol_prepareShortStringOpen_INTERNAL_API_DO_NOT_USE +# define ucol_previousProcessed_4_0 ucol_previousProcessed_INTERNAL_API_DO_NOT_USE +# define uprv_getDefaultCodepage_4_0 uprv_getDefaultCodepage_INTERNAL_API_DO_NOT_USE +# define uprv_getDefaultLocaleID_4_0 uprv_getDefaultLocaleID_INTERNAL_API_DO_NOT_USE +# define ures_openFillIn_4_0 ures_openFillIn_INTERNAL_API_DO_NOT_USE +# define usearch_searchBackwards_4_0 usearch_searchBackwards_INTERNAL_API_DO_NOT_USE +# define usearch_search_4_0 usearch_search_INTERNAL_API_DO_NOT_USE +# define utf8_appendCharSafeBody_4_0 utf8_appendCharSafeBody_INTERNAL_API_DO_NOT_USE +# define utf8_back1SafeBody_4_0 utf8_back1SafeBody_INTERNAL_API_DO_NOT_USE +# define utf8_countTrailBytes_4_0 utf8_countTrailBytes_INTERNAL_API_DO_NOT_USE +# define utf8_nextCharSafeBody_4_0 utf8_nextCharSafeBody_INTERNAL_API_DO_NOT_USE +# define utf8_prevCharSafeBody_4_0 utf8_prevCharSafeBody_INTERNAL_API_DO_NOT_USE +# endif /* U_DISABLE_RENAMING */ + +#endif /* U_HIDE_INTERNAL_API */ +#endif /* UINTRNAL_H */ + diff --git a/utils/openttd/unicode/uiter.h b/utils/openttd/unicode/uiter.h new file mode 100644 index 00000000000..9409f01ee9a --- /dev/null +++ b/utils/openttd/unicode/uiter.h @@ -0,0 +1,707 @@ +/* +******************************************************************************* +* +* Copyright (C) 2002-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: uiter.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2002jan18 +* created by: Markus W. Scherer +*/ + +#ifndef __UITER_H__ +#define __UITER_H__ + +/** + * \file + * \brief C API: Unicode Character Iteration + * + * @see UCharIterator + */ + +#include "unicode/utypes.h" + +#ifdef XP_CPLUSPLUS + U_NAMESPACE_BEGIN + + class CharacterIterator; + class Replaceable; + + U_NAMESPACE_END +#endif + +U_CDECL_BEGIN + +struct UCharIterator; +typedef struct UCharIterator UCharIterator; /**< C typedef for struct UCharIterator. @stable ICU 2.1 */ + +/** + * Origin constants for UCharIterator.getIndex() and UCharIterator.move(). + * @see UCharIteratorMove + * @see UCharIterator + * @stable ICU 2.1 + */ +typedef enum UCharIteratorOrigin { + UITER_START, UITER_CURRENT, UITER_LIMIT, UITER_ZERO, UITER_LENGTH +} UCharIteratorOrigin; + +/** Constants for UCharIterator. @stable ICU 2.6 */ +enum { + /** + * Constant value that may be returned by UCharIteratorMove + * indicating that the final UTF-16 index is not known, but that the move succeeded. + * This can occur when moving relative to limit or length, or + * when moving relative to the current index after a setState() + * when the current UTF-16 index is not known. + * + * It would be very inefficient to have to count from the beginning of the text + * just to get the current/limit/length index after moving relative to it. + * The actual index can be determined with getIndex(UITER_CURRENT) + * which will count the UChars if necessary. + * + * @stable ICU 2.6 + */ + UITER_UNKNOWN_INDEX=-2 +}; + + +/** + * Constant for UCharIterator getState() indicating an error or + * an unknown state. + * Returned by uiter_getState()/UCharIteratorGetState + * when an error occurs. + * Also, some UCharIterator implementations may not be able to return + * a valid state for each position. This will be clearly documented + * for each such iterator (none of the public ones here). + * + * @stable ICU 2.6 + */ +#define UITER_NO_STATE ((uint32_t)0xffffffff) + +/** + * Function type declaration for UCharIterator.getIndex(). + * + * Gets the current position, or the start or limit of the + * iteration range. + * + * This function may perform slowly for UITER_CURRENT after setState() was called, + * or for UITER_LENGTH, because an iterator implementation may have to count + * UChars if the underlying storage is not UTF-16. + * + * @param iter the UCharIterator structure ("this pointer") + * @param origin get the 0, start, limit, length, or current index + * @return the requested index, or U_SENTINEL in an error condition + * + * @see UCharIteratorOrigin + * @see UCharIterator + * @stable ICU 2.1 + */ +typedef int32_t U_CALLCONV +UCharIteratorGetIndex(UCharIterator *iter, UCharIteratorOrigin origin); + +/** + * Function type declaration for UCharIterator.move(). + * + * Use iter->move(iter, index, UITER_ZERO) like CharacterIterator::setIndex(index). + * + * Moves the current position relative to the start or limit of the + * iteration range, or relative to the current position itself. + * The movement is expressed in numbers of code units forward + * or backward by specifying a positive or negative delta. + * Out of bounds movement will be pinned to the start or limit. + * + * This function may perform slowly for moving relative to UITER_LENGTH + * because an iterator implementation may have to count the rest of the + * UChars if the native storage is not UTF-16. + * + * When moving relative to the limit or length, or + * relative to the current position after setState() was called, + * move() may return UITER_UNKNOWN_INDEX (-2) to avoid an inefficient + * determination of the actual UTF-16 index. + * The actual index can be determined with getIndex(UITER_CURRENT) + * which will count the UChars if necessary. + * See UITER_UNKNOWN_INDEX for details. + * + * @param iter the UCharIterator structure ("this pointer") + * @param delta can be positive, zero, or negative + * @param origin move relative to the 0, start, limit, length, or current index + * @return the new index, or U_SENTINEL on an error condition, + * or UITER_UNKNOWN_INDEX when the index is not known. + * + * @see UCharIteratorOrigin + * @see UCharIterator + * @see UITER_UNKNOWN_INDEX + * @stable ICU 2.1 + */ +typedef int32_t U_CALLCONV +UCharIteratorMove(UCharIterator *iter, int32_t delta, UCharIteratorOrigin origin); + +/** + * Function type declaration for UCharIterator.hasNext(). + * + * Check if current() and next() can still + * return another code unit. + * + * @param iter the UCharIterator structure ("this pointer") + * @return boolean value for whether current() and next() can still return another code unit + * + * @see UCharIterator + * @stable ICU 2.1 + */ +typedef UBool U_CALLCONV +UCharIteratorHasNext(UCharIterator *iter); + +/** + * Function type declaration for UCharIterator.hasPrevious(). + * + * Check if previous() can still return another code unit. + * + * @param iter the UCharIterator structure ("this pointer") + * @return boolean value for whether previous() can still return another code unit + * + * @see UCharIterator + * @stable ICU 2.1 + */ +typedef UBool U_CALLCONV +UCharIteratorHasPrevious(UCharIterator *iter); + +/** + * Function type declaration for UCharIterator.current(). + * + * Return the code unit at the current position, + * or U_SENTINEL if there is none (index is at the limit). + * + * @param iter the UCharIterator structure ("this pointer") + * @return the current code unit + * + * @see UCharIterator + * @stable ICU 2.1 + */ +typedef UChar32 U_CALLCONV +UCharIteratorCurrent(UCharIterator *iter); + +/** + * Function type declaration for UCharIterator.next(). + * + * Return the code unit at the current index and increment + * the index (post-increment, like s[i++]), + * or return U_SENTINEL if there is none (index is at the limit). + * + * @param iter the UCharIterator structure ("this pointer") + * @return the current code unit (and post-increment the current index) + * + * @see UCharIterator + * @stable ICU 2.1 + */ +typedef UChar32 U_CALLCONV +UCharIteratorNext(UCharIterator *iter); + +/** + * Function type declaration for UCharIterator.previous(). + * + * Decrement the index and return the code unit from there + * (pre-decrement, like s[--i]), + * or return U_SENTINEL if there is none (index is at the start). + * + * @param iter the UCharIterator structure ("this pointer") + * @return the previous code unit (after pre-decrementing the current index) + * + * @see UCharIterator + * @stable ICU 2.1 + */ +typedef UChar32 U_CALLCONV +UCharIteratorPrevious(UCharIterator *iter); + +/** + * Function type declaration for UCharIterator.reservedFn(). + * Reserved for future use. + * + * @param iter the UCharIterator structure ("this pointer") + * @param something some integer argument + * @return some integer + * + * @see UCharIterator + * @stable ICU 2.1 + */ +typedef int32_t U_CALLCONV +UCharIteratorReserved(UCharIterator *iter, int32_t something); + +/** + * Function type declaration for UCharIterator.getState(). + * + * Get the "state" of the iterator in the form of a single 32-bit word. + * It is recommended that the state value be calculated to be as small as + * is feasible. For strings with limited lengths, fewer than 32 bits may + * be sufficient. + * + * This is used together with setState()/UCharIteratorSetState + * to save and restore the iterator position more efficiently than with + * getIndex()/move(). + * + * The iterator state is defined as a uint32_t value because it is designed + * for use in ucol_nextSortKeyPart() which provides 32 bits to store the state + * of the character iterator. + * + * With some UCharIterator implementations (e.g., UTF-8), + * getting and setting the UTF-16 index with existing functions + * (getIndex(UITER_CURRENT) followed by move(pos, UITER_ZERO)) is possible but + * relatively slow because the iterator has to "walk" from a known index + * to the requested one. + * This takes more time the farther it needs to go. + * + * An opaque state value allows an iterator implementation to provide + * an internal index (UTF-8: the source byte array index) for + * fast, constant-time restoration. + * + * After calling setState(), a getIndex(UITER_CURRENT) may be slow because + * the UTF-16 index may not be restored as well, but the iterator can deliver + * the correct text contents and move relative to the current position + * without performance degradation. + * + * Some UCharIterator implementations may not be able to return + * a valid state for each position, in which case they return UITER_NO_STATE instead. + * This will be clearly documented for each such iterator (none of the public ones here). + * + * @param iter the UCharIterator structure ("this pointer") + * @return the state word + * + * @see UCharIterator + * @see UCharIteratorSetState + * @see UITER_NO_STATE + * @stable ICU 2.6 + */ +typedef uint32_t U_CALLCONV +UCharIteratorGetState(const UCharIterator *iter); + +/** + * Function type declaration for UCharIterator.setState(). + * + * Restore the "state" of the iterator using a state word from a getState() call. + * The iterator object need not be the same one as for which getState() was called, + * but it must be of the same type (set up using the same uiter_setXYZ function) + * and it must iterate over the same string + * (binary identical regardless of memory address). + * For more about the state word see UCharIteratorGetState. + * + * After calling setState(), a getIndex(UITER_CURRENT) may be slow because + * the UTF-16 index may not be restored as well, but the iterator can deliver + * the correct text contents and move relative to the current position + * without performance degradation. + * + * @param iter the UCharIterator structure ("this pointer") + * @param state the state word from a getState() call + * on a same-type, same-string iterator + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * + * @see UCharIterator + * @see UCharIteratorGetState + * @stable ICU 2.6 + */ +typedef void U_CALLCONV +UCharIteratorSetState(UCharIterator *iter, uint32_t state, UErrorCode *pErrorCode); + + +/** + * C API for code unit iteration. + * This can be used as a C wrapper around + * CharacterIterator, Replaceable, or implemented using simple strings, etc. + * + * There are two roles for using UCharIterator: + * + * A "provider" sets the necessary function pointers and controls the "protected" + * fields of the UCharIterator structure. A "provider" passes a UCharIterator + * into C APIs that need a UCharIterator as an abstract, flexible string interface. + * + * Implementations of such C APIs are "callers" of UCharIterator functions; + * they only use the "public" function pointers and never access the "protected" + * fields directly. + * + * The current() and next() functions only check the current index against the + * limit, and previous() only checks the current index against the start, + * to see if the iterator already reached the end of the iteration range. + * + * The assumption - in all iterators - is that the index is moved via the API, + * which means it won't go out of bounds, or the index is modified by + * user code that knows enough about the iterator implementation to set valid + * index values. + * + * UCharIterator functions return code unit values 0..0xffff, + * or U_SENTINEL if the iteration bounds are reached. + * + * @stable ICU 2.1 + */ +struct UCharIterator { + /** + * (protected) Pointer to string or wrapped object or similar. + * Not used by caller. + * @stable ICU 2.1 + */ + const void *context; + + /** + * (protected) Length of string or similar. + * Not used by caller. + * @stable ICU 2.1 + */ + int32_t length; + + /** + * (protected) Start index or similar. + * Not used by caller. + * @stable ICU 2.1 + */ + int32_t start; + + /** + * (protected) Current index or similar. + * Not used by caller. + * @stable ICU 2.1 + */ + int32_t index; + + /** + * (protected) Limit index or similar. + * Not used by caller. + * @stable ICU 2.1 + */ + int32_t limit; + + /** + * (protected) Used by UTF-8 iterators and possibly others. + * @stable ICU 2.1 + */ + int32_t reservedField; + + /** + * (public) Returns the current position or the + * start or limit index of the iteration range. + * + * @see UCharIteratorGetIndex + * @stable ICU 2.1 + */ + UCharIteratorGetIndex *getIndex; + + /** + * (public) Moves the current position relative to the start or limit of the + * iteration range, or relative to the current position itself. + * The movement is expressed in numbers of code units forward + * or backward by specifying a positive or negative delta. + * + * @see UCharIteratorMove + * @stable ICU 2.1 + */ + UCharIteratorMove *move; + + /** + * (public) Check if current() and next() can still + * return another code unit. + * + * @see UCharIteratorHasNext + * @stable ICU 2.1 + */ + UCharIteratorHasNext *hasNext; + + /** + * (public) Check if previous() can still return another code unit. + * + * @see UCharIteratorHasPrevious + * @stable ICU 2.1 + */ + UCharIteratorHasPrevious *hasPrevious; + + /** + * (public) Return the code unit at the current position, + * or U_SENTINEL if there is none (index is at the limit). + * + * @see UCharIteratorCurrent + * @stable ICU 2.1 + */ + UCharIteratorCurrent *current; + + /** + * (public) Return the code unit at the current index and increment + * the index (post-increment, like s[i++]), + * or return U_SENTINEL if there is none (index is at the limit). + * + * @see UCharIteratorNext + * @stable ICU 2.1 + */ + UCharIteratorNext *next; + + /** + * (public) Decrement the index and return the code unit from there + * (pre-decrement, like s[--i]), + * or return U_SENTINEL if there is none (index is at the start). + * + * @see UCharIteratorPrevious + * @stable ICU 2.1 + */ + UCharIteratorPrevious *previous; + + /** + * (public) Reserved for future use. Currently NULL. + * + * @see UCharIteratorReserved + * @stable ICU 2.1 + */ + UCharIteratorReserved *reservedFn; + + /** + * (public) Return the state of the iterator, to be restored later with setState(). + * This function pointer is NULL if the iterator does not implement it. + * + * @see UCharIteratorGet + * @stable ICU 2.6 + */ + UCharIteratorGetState *getState; + + /** + * (public) Restore the iterator state from the state word from a call + * to getState(). + * This function pointer is NULL if the iterator does not implement it. + * + * @see UCharIteratorSet + * @stable ICU 2.6 + */ + UCharIteratorSetState *setState; +}; + +/** + * Helper function for UCharIterator to get the code point + * at the current index. + * + * Return the code point that includes the code unit at the current position, + * or U_SENTINEL if there is none (index is at the limit). + * If the current code unit is a lead or trail surrogate, + * then the following or preceding surrogate is used to form + * the code point value. + * + * @param iter the UCharIterator structure ("this pointer") + * @return the current code point + * + * @see UCharIterator + * @see U16_GET + * @see UnicodeString::char32At() + * @stable ICU 2.1 + */ +U_STABLE UChar32 U_EXPORT2 +uiter_current32(UCharIterator *iter); + +/** + * Helper function for UCharIterator to get the next code point. + * + * Return the code point at the current index and increment + * the index (post-increment, like s[i++]), + * or return U_SENTINEL if there is none (index is at the limit). + * + * @param iter the UCharIterator structure ("this pointer") + * @return the current code point (and post-increment the current index) + * + * @see UCharIterator + * @see U16_NEXT + * @stable ICU 2.1 + */ +U_STABLE UChar32 U_EXPORT2 +uiter_next32(UCharIterator *iter); + +/** + * Helper function for UCharIterator to get the previous code point. + * + * Decrement the index and return the code point from there + * (pre-decrement, like s[--i]), + * or return U_SENTINEL if there is none (index is at the start). + * + * @param iter the UCharIterator structure ("this pointer") + * @return the previous code point (after pre-decrementing the current index) + * + * @see UCharIterator + * @see U16_PREV + * @stable ICU 2.1 + */ +U_STABLE UChar32 U_EXPORT2 +uiter_previous32(UCharIterator *iter); + +/** + * Get the "state" of the iterator in the form of a single 32-bit word. + * This is a convenience function that calls iter->getState(iter) + * if iter->getState is not NULL; + * if it is NULL or any other error occurs, then UITER_NO_STATE is returned. + * + * Some UCharIterator implementations may not be able to return + * a valid state for each position, in which case they return UITER_NO_STATE instead. + * This will be clearly documented for each such iterator (none of the public ones here). + * + * @param iter the UCharIterator structure ("this pointer") + * @return the state word + * + * @see UCharIterator + * @see UCharIteratorGetState + * @see UITER_NO_STATE + * @stable ICU 2.6 + */ +U_STABLE uint32_t U_EXPORT2 +uiter_getState(const UCharIterator *iter); + +/** + * Restore the "state" of the iterator using a state word from a getState() call. + * This is a convenience function that calls iter->setState(iter, state, pErrorCode) + * if iter->setState is not NULL; if it is NULL, then U_UNSUPPORTED_ERROR is set. + * + * @param iter the UCharIterator structure ("this pointer") + * @param state the state word from a getState() call + * on a same-type, same-string iterator + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * + * @see UCharIterator + * @see UCharIteratorSetState + * @stable ICU 2.6 + */ +U_STABLE void U_EXPORT2 +uiter_setState(UCharIterator *iter, uint32_t state, UErrorCode *pErrorCode); + +/** + * Set up a UCharIterator to iterate over a string. + * + * Sets the UCharIterator function pointers for iteration over the string s + * with iteration boundaries start=index=0 and length=limit=string length. + * The "provider" may set the start, index, and limit values at any time + * within the range 0..length. + * The length field will be ignored. + * + * The string pointer s is set into UCharIterator.context without copying + * or reallocating the string contents. + * + * getState() simply returns the current index. + * move() will always return the final index. + * + * @param iter UCharIterator structure to be set for iteration + * @param s String to iterate over + * @param length Length of s, or -1 if NUL-terminated + * + * @see UCharIterator + * @stable ICU 2.1 + */ +U_STABLE void U_EXPORT2 +uiter_setString(UCharIterator *iter, const UChar *s, int32_t length); + +/** + * Set up a UCharIterator to iterate over a UTF-16BE string + * (byte vector with a big-endian pair of bytes per UChar). + * + * Everything works just like with a normal UChar iterator (uiter_setString), + * except that UChars are assembled from byte pairs, + * and that the length argument here indicates an even number of bytes. + * + * getState() simply returns the current index. + * move() will always return the final index. + * + * @param iter UCharIterator structure to be set for iteration + * @param s UTF-16BE string to iterate over + * @param length Length of s as an even number of bytes, or -1 if NUL-terminated + * (NUL means pair of 0 bytes at even index from s) + * + * @see UCharIterator + * @see uiter_setString + * @stable ICU 2.6 + */ +U_STABLE void U_EXPORT2 +uiter_setUTF16BE(UCharIterator *iter, const char *s, int32_t length); + +/** + * Set up a UCharIterator to iterate over a UTF-8 string. + * + * Sets the UCharIterator function pointers for iteration over the UTF-8 string s + * with UTF-8 iteration boundaries 0 and length. + * The implementation counts the UTF-16 index on the fly and + * lazily evaluates the UTF-16 length of the text. + * + * The start field is used as the UTF-8 offset, the limit field as the UTF-8 length. + * When the reservedField is not 0, then it contains a supplementary code point + * and the UTF-16 index is between the two corresponding surrogates. + * At that point, the UTF-8 index is behind that code point. + * + * The UTF-8 string pointer s is set into UCharIterator.context without copying + * or reallocating the string contents. + * + * getState() returns a state value consisting of + * - the current UTF-8 source byte index (bits 31..1) + * - a flag (bit 0) that indicates whether the UChar position is in the middle + * of a surrogate pair + * (from a 4-byte UTF-8 sequence for the corresponding supplementary code point) + * + * getState() cannot also encode the UTF-16 index in the state value. + * move(relative to limit or length), or + * move(relative to current) after setState(), may return UITER_UNKNOWN_INDEX. + * + * @param iter UCharIterator structure to be set for iteration + * @param s UTF-8 string to iterate over + * @param length Length of s in bytes, or -1 if NUL-terminated + * + * @see UCharIterator + * @stable ICU 2.6 + */ +U_STABLE void U_EXPORT2 +uiter_setUTF8(UCharIterator *iter, const char *s, int32_t length); + +#ifdef XP_CPLUSPLUS + +/** + * Set up a UCharIterator to wrap around a C++ CharacterIterator. + * + * Sets the UCharIterator function pointers for iteration using the + * CharacterIterator charIter. + * + * The CharacterIterator pointer charIter is set into UCharIterator.context + * without copying or cloning the CharacterIterator object. + * The other "protected" UCharIterator fields are set to 0 and will be ignored. + * The iteration index and boundaries are controlled by the CharacterIterator. + * + * getState() simply returns the current index. + * move() will always return the final index. + * + * @param iter UCharIterator structure to be set for iteration + * @param charIter CharacterIterator to wrap + * + * @see UCharIterator + * @stable ICU 2.1 + */ +U_STABLE void U_EXPORT2 +uiter_setCharacterIterator(UCharIterator *iter, U_NAMESPACE_QUALIFIER CharacterIterator *charIter); + +/** + * Set up a UCharIterator to iterate over a C++ Replaceable. + * + * Sets the UCharIterator function pointers for iteration over the + * Replaceable rep with iteration boundaries start=index=0 and + * length=limit=rep->length(). + * The "provider" may set the start, index, and limit values at any time + * within the range 0..length=rep->length(). + * The length field will be ignored. + * + * The Replaceable pointer rep is set into UCharIterator.context without copying + * or cloning/reallocating the Replaceable object. + * + * getState() simply returns the current index. + * move() will always return the final index. + * + * @param iter UCharIterator structure to be set for iteration + * @param rep Replaceable to iterate over + * + * @see UCharIterator + * @stable ICU 2.1 + */ +U_STABLE void U_EXPORT2 +uiter_setReplaceable(UCharIterator *iter, const U_NAMESPACE_QUALIFIER Replaceable *rep); + +#endif + +U_CDECL_END + +#endif diff --git a/utils/openttd/unicode/uloc.h b/utils/openttd/unicode/uloc.h new file mode 100644 index 00000000000..29c479a7615 --- /dev/null +++ b/utils/openttd/unicode/uloc.h @@ -0,0 +1,1046 @@ +/* +********************************************************************** +* Copyright (C) 1997-2008, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* +* File ULOC.H +* +* Modification History: +* +* Date Name Description +* 04/01/97 aliu Creation. +* 08/22/98 stephen JDK 1.2 sync. +* 12/08/98 rtg New C API for Locale +* 03/30/99 damiba overhaul +* 03/31/99 helena Javadoc for uloc functions. +* 04/15/99 Madhu Updated Javadoc +******************************************************************************** +*/ + +#ifndef ULOC_H +#define ULOC_H + +#include "unicode/utypes.h" +#include "unicode/uenum.h" + +/** + * \file + * \brief C API: Locale + * + * <h2> ULoc C API for Locale </h2> + * A <code>Locale</code> represents a specific geographical, political, + * or cultural region. An operation that requires a <code>Locale</code> to perform + * its task is called <em>locale-sensitive</em> and uses the <code>Locale</code> + * to tailor information for the user. For example, displaying a number + * is a locale-sensitive operation--the number should be formatted + * according to the customs/conventions of the user's native country, + * region, or culture. In the C APIs, a locales is simply a const char string. + * + * <P> + * You create a <code>Locale</code> with one of the three options listed below. + * Each of the component is separated by '_' in the locale string. + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * \code + * newLanguage + * + * newLanguage + newCountry + * + * newLanguage + newCountry + newVariant + * \endcode + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * The first option is a valid <STRONG>ISO + * Language Code.</STRONG> These codes are the lower-case two-letter + * codes as defined by ISO-639. + * You can find a full list of these codes at a number of sites, such as: + * <BR><a href ="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt"> + * http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</a> + * + * <P> + * The second option includes an additonal <STRONG>ISO Country + * Code.</STRONG> These codes are the upper-case two-letter codes + * as defined by ISO-3166. + * You can find a full list of these codes at a number of sites, such as: + * <BR><a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html"> + * http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</a> + * + * <P> + * The third option requires another additonal information--the + * <STRONG>Variant.</STRONG> + * The Variant codes are vendor and browser-specific. + * For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX. + * Where there are two variants, separate them with an underscore, and + * put the most important one first. For + * example, a Traditional Spanish collation might be referenced, with + * "ES", "ES", "Traditional_WIN". + * + * <P> + * Because a <code>Locale</code> is just an identifier for a region, + * no validity check is performed when you specify a <code>Locale</code>. + * If you want to see whether particular resources are available for the + * <code>Locale</code> you asked for, you must query those resources. For + * example, ask the <code>UNumberFormat</code> for the locales it supports + * using its <code>getAvailable</code> method. + * <BR><STRONG>Note:</STRONG> When you ask for a resource for a particular + * locale, you get back the best available match, not necessarily + * precisely what you asked for. For more information, look at + * <code>UResourceBundle</code>. + * + * <P> + * The <code>Locale</code> provides a number of convenient constants + * that you can use to specify the commonly used + * locales. For example, the following refers to a locale + * for the United States: + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * \code + * ULOC_US + * \endcode + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * + * <P> + * Once you've specified a locale you can query it for information about + * itself. Use <code>uloc_getCountry</code> to get the ISO Country Code and + * <code>uloc_getLanguage</code> to get the ISO Language Code. You can + * use <code>uloc_getDisplayCountry</code> to get the + * name of the country suitable for displaying to the user. Similarly, + * you can use <code>uloc_getDisplayLanguage</code> to get the name of + * the language suitable for displaying to the user. Interestingly, + * the <code>uloc_getDisplayXXX</code> methods are themselves locale-sensitive + * and have two versions: one that uses the default locale and one + * that takes a locale as an argument and displays the name or country in + * a language appropriate to that locale. + * + * <P> + * The ICU provides a number of services that perform locale-sensitive + * operations. For example, the <code>unum_xxx</code> functions format + * numbers, currency, or percentages in a locale-sensitive manner. + * </P> + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * \code + * UErrorCode success = U_ZERO_ERROR; + * UNumberFormat *nf; + * const char* myLocale = "fr_FR"; + * + * nf = unum_open( UNUM_DEFAULT, NULL, success ); + * unum_close(nf); + * nf = unum_open( UNUM_CURRENCY, NULL, success ); + * unum_close(nf); + * nf = unum_open( UNUM_PERCENT, NULL, success ); + * unum_close(nf); + * \endcode + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * Each of these methods has two variants; one with an explicit locale + * and one without; the latter using the default locale. + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * \code + * + * nf = unum_open( UNUM_DEFAULT, myLocale, success ); + * unum_close(nf); + * nf = unum_open( UNUM_CURRENCY, myLocale, success ); + * unum_close(nf); + * nf = unum_open( UNUM_PERCENT, myLocale, success ); + * unum_close(nf); + * \endcode + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * A <code>Locale</code> is the mechanism for identifying the kind of services + * (<code>UNumberFormat</code>) that you would like to get. The locale is + * <STRONG>just</STRONG> a mechanism for identifying these services. + * + * <P> + * Each international serivce that performs locale-sensitive operations + * allows you + * to get all the available objects of that type. You can sift + * through these objects by language, country, or variant, + * and use the display names to present a menu to the user. + * For example, you can create a menu of all the collation objects + * suitable for a given language. Such classes implement these + * three class methods: + * \htmlonly<blockquote>\endhtmlonly + * <pre> + * \code + * const char* uloc_getAvailable(int32_t index); + * int32_t uloc_countAvailable(); + * int32_t + * uloc_getDisplayName(const char* localeID, + * const char* inLocaleID, + * UChar* result, + * int32_t maxResultSize, + * UErrorCode* err); + * + * \endcode + * </pre> + * \htmlonly</blockquote>\endhtmlonly + * <P> + * Concerning POSIX/RFC1766 Locale IDs, + * the getLanguage/getCountry/getVariant/getName functions do understand + * the POSIX type form of language_COUNTRY.ENCODING\@VARIANT + * and if there is not an ICU-stype variant, uloc_getVariant() for example + * will return the one listed after the \@at sign. As well, the hyphen + * "-" is recognized as a country/variant separator similarly to RFC1766. + * So for example, "en-us" will be interpreted as en_US. + * As a result, uloc_getName() is far from a no-op, and will have the + * effect of converting POSIX/RFC1766 IDs into ICU form, although it does + * NOT map any of the actual codes (i.e. russian->ru) in any way. + * Applications should call uloc_getName() at the point where a locale ID + * is coming from an external source (user entry, OS, web browser) + * and pass the resulting string to other ICU functions. For example, + * don't use de-de\@EURO as an argument to resourcebundle. + * + * @see UResourceBundle + */ + +/** Useful constant for this language. @stable ICU 2.0 */ +#define ULOC_CHINESE "zh" +/** Useful constant for this language. @stable ICU 2.0 */ +#define ULOC_ENGLISH "en" +/** Useful constant for this language. @stable ICU 2.0 */ +#define ULOC_FRENCH "fr" +/** Useful constant for this language. @stable ICU 2.0 */ +#define ULOC_GERMAN "de" +/** Useful constant for this language. @stable ICU 2.0 */ +#define ULOC_ITALIAN "it" +/** Useful constant for this language. @stable ICU 2.0 */ +#define ULOC_JAPANESE "ja" +/** Useful constant for this language. @stable ICU 2.0 */ +#define ULOC_KOREAN "ko" +/** Useful constant for this language. @stable ICU 2.0 */ +#define ULOC_SIMPLIFIED_CHINESE "zh_CN" +/** Useful constant for this language. @stable ICU 2.0 */ +#define ULOC_TRADITIONAL_CHINESE "zh_TW" + +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_CANADA "en_CA" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_CANADA_FRENCH "fr_CA" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_CHINA "zh_CN" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_PRC "zh_CN" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_FRANCE "fr_FR" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_GERMANY "de_DE" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_ITALY "it_IT" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_JAPAN "ja_JP" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_KOREA "ko_KR" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_TAIWAN "zh_TW" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_UK "en_GB" +/** Useful constant for this country/region. @stable ICU 2.0 */ +#define ULOC_US "en_US" + +/** + * Useful constant for the maximum size of the language part of a locale ID. + * (including the terminating NULL). + * @stable ICU 2.0 + */ +#define ULOC_LANG_CAPACITY 12 + +/** + * Useful constant for the maximum size of the country part of a locale ID + * (including the terminating NULL). + * @stable ICU 2.0 + */ +#define ULOC_COUNTRY_CAPACITY 4 +/** + * Useful constant for the maximum size of the whole locale ID + * (including the terminating NULL). + * @stable ICU 2.0 + */ +#define ULOC_FULLNAME_CAPACITY 56 + +/** + * Useful constant for the maximum size of the script part of a locale ID + * (including the terminating NULL). + * @stable ICU 2.8 + */ +#define ULOC_SCRIPT_CAPACITY 6 + +/** + * Useful constant for the maximum size of keywords in a locale + * @stable ICU 2.8 + */ +#define ULOC_KEYWORDS_CAPACITY 50 + +/** + * Useful constant for the maximum SIZE of keywords in a locale + * @stable ICU 2.8 + */ +#define ULOC_KEYWORD_AND_VALUES_CAPACITY 100 + +/** + * Character separating keywords from the locale string + * different for EBCDIC - TODO + * @stable ICU 2.8 + */ +#define ULOC_KEYWORD_SEPARATOR '@' +/** + * Character for assigning value to a keyword + * @stable ICU 2.8 + */ +#define ULOC_KEYWORD_ASSIGN '=' +/** + * Character separating keywords + * @stable ICU 2.8 + */ +#define ULOC_KEYWORD_ITEM_SEPARATOR ';' + +/** + * Constants for *_getLocale() + * Allow user to select whether she wants information on + * requested, valid or actual locale. + * For example, a collator for "en_US_CALIFORNIA" was + * requested. In the current state of ICU (2.0), + * the requested locale is "en_US_CALIFORNIA", + * the valid locale is "en_US" (most specific locale supported by ICU) + * and the actual locale is "root" (the collation data comes unmodified + * from the UCA) + * The locale is considered supported by ICU if there is a core ICU bundle + * for that locale (although it may be empty). + * @stable ICU 2.1 + */ +typedef enum { + /** This is locale the data actually comes from + * @stable ICU 2.1 + */ + ULOC_ACTUAL_LOCALE = 0, + /** This is the most specific locale supported by ICU + * @stable ICU 2.1 + */ + ULOC_VALID_LOCALE = 1, + +#ifndef U_HIDE_DEPRECATED_API + /** This is the requested locale + * @deprecated ICU 2.8 + */ + ULOC_REQUESTED_LOCALE = 2, +#endif /* U_HIDE_DEPRECATED_API */ + + ULOC_DATA_LOCALE_TYPE_LIMIT = 3 +} ULocDataLocaleType ; + + +/** + * Gets ICU's default locale. + * The returned string is a snapshot in time, and will remain valid + * and unchanged even when uloc_setDefault() is called. + * The returned storage is owned by ICU, and must not be altered or deleted + * by the caller. + * + * @return the ICU default locale + * @system + * @stable ICU 2.0 + */ +U_STABLE const char* U_EXPORT2 +uloc_getDefault(void); + +/** + * Sets ICU's default locale. + * By default (without calling this function), ICU's default locale will be based + * on information obtained from the underlying system environment. + * <p> + * Changes to ICU's default locale do not propagate back to the + * system environment. + * <p> + * Changes to ICU's default locale to not affect any ICU services that + * may already be open based on the previous default locale value. + * + * @param localeID the new ICU default locale. A value of NULL will try to get + * the system's default locale. + * @param status the error information if the setting of default locale fails + * @system + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +uloc_setDefault(const char* localeID, + UErrorCode* status); + +/** + * Gets the language code for the specified locale. + * + * @param localeID the locale to get the ISO language code with + * @param language the language code for localeID + * @param languageCapacity the size of the language buffer to store the + * language code with + * @param err error information if retrieving the language code failed + * @return the actual buffer size needed for the language code. If it's greater + * than languageCapacity, the returned language code will be truncated. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getLanguage(const char* localeID, + char* language, + int32_t languageCapacity, + UErrorCode* err); + +/** + * Gets the script code for the specified locale. + * + * @param localeID the locale to get the ISO language code with + * @param script the language code for localeID + * @param scriptCapacity the size of the language buffer to store the + * language code with + * @param err error information if retrieving the language code failed + * @return the actual buffer size needed for the language code. If it's greater + * than scriptCapacity, the returned language code will be truncated. + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getScript(const char* localeID, + char* script, + int32_t scriptCapacity, + UErrorCode* err); + +/** + * Gets the country code for the specified locale. + * + * @param localeID the locale to get the country code with + * @param country the country code for localeID + * @param countryCapacity the size of the country buffer to store the + * country code with + * @param err error information if retrieving the country code failed + * @return the actual buffer size needed for the country code. If it's greater + * than countryCapacity, the returned country code will be truncated. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getCountry(const char* localeID, + char* country, + int32_t countryCapacity, + UErrorCode* err); + +/** + * Gets the variant code for the specified locale. + * + * @param localeID the locale to get the variant code with + * @param variant the variant code for localeID + * @param variantCapacity the size of the variant buffer to store the + * variant code with + * @param err error information if retrieving the variant code failed + * @return the actual buffer size needed for the variant code. If it's greater + * than variantCapacity, the returned variant code will be truncated. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getVariant(const char* localeID, + char* variant, + int32_t variantCapacity, + UErrorCode* err); + + +/** + * Gets the full name for the specified locale. + * Note: This has the effect of 'canonicalizing' the ICU locale ID to + * a certain extent. Upper and lower case are set as needed. + * It does NOT map aliased names in any way. + * See the top of this header file. + * This API supports preflighting. + * + * @param localeID the locale to get the full name with + * @param name fill in buffer for the name without keywords. + * @param nameCapacity capacity of the fill in buffer. + * @param err error information if retrieving the full name failed + * @return the actual buffer size needed for the full name. If it's greater + * than nameCapacity, the returned full name will be truncated. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getName(const char* localeID, + char* name, + int32_t nameCapacity, + UErrorCode* err); + +/** + * Gets the full name for the specified locale. + * Note: This has the effect of 'canonicalizing' the string to + * a certain extent. Upper and lower case are set as needed, + * and if the components were in 'POSIX' format they are changed to + * ICU format. It does NOT map aliased names in any way. + * See the top of this header file. + * + * @param localeID the locale to get the full name with + * @param name the full name for localeID + * @param nameCapacity the size of the name buffer to store the + * full name with + * @param err error information if retrieving the full name failed + * @return the actual buffer size needed for the full name. If it's greater + * than nameCapacity, the returned full name will be truncated. + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +uloc_canonicalize(const char* localeID, + char* name, + int32_t nameCapacity, + UErrorCode* err); + +/** + * Gets the ISO language code for the specified locale. + * + * @param localeID the locale to get the ISO language code with + * @return language the ISO language code for localeID + * @stable ICU 2.0 + */ +U_STABLE const char* U_EXPORT2 +uloc_getISO3Language(const char* localeID); + + +/** + * Gets the ISO country code for the specified locale. + * + * @param localeID the locale to get the ISO country code with + * @return country the ISO country code for localeID + * @stable ICU 2.0 + */ +U_STABLE const char* U_EXPORT2 +uloc_getISO3Country(const char* localeID); + +/** + * Gets the Win32 LCID value for the specified locale. + * If the ICU locale is not recognized by Windows, 0 will be returned. + * + * @param localeID the locale to get the Win32 LCID value with + * @return country the Win32 LCID for localeID + * @stable ICU 2.0 + */ +U_STABLE uint32_t U_EXPORT2 +uloc_getLCID(const char* localeID); + +/** + * Gets the language name suitable for display for the specified locale. + * + * @param locale the locale to get the ISO language code with + * @param displayLocale Specifies the locale to be used to display the name. In other words, + * if the locale's language code is "en", passing Locale::getFrench() for + * inLocale would result in "Anglais", while passing Locale::getGerman() + * for inLocale would result in "Englisch". + * @param language the displayable language code for localeID + * @param languageCapacity the size of the language buffer to store the + * displayable language code with + * @param status error information if retrieving the displayable language code failed + * @return the actual buffer size needed for the displayable language code. If it's greater + * than languageCapacity, the returned language code will be truncated. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getDisplayLanguage(const char* locale, + const char* displayLocale, + UChar* language, + int32_t languageCapacity, + UErrorCode* status); + +/** + * Gets the script name suitable for display for the specified locale. + * + * @param locale the locale to get the displayable script code with. NULL may be used to specify the default. + * @param displayLocale Specifies the locale to be used to display the name. In other words, + * if the locale's language code is "en", passing Locale::getFrench() for + * inLocale would result in "", while passing Locale::getGerman() + * for inLocale would result in "". NULL may be used to specify the default. + * @param script the displayable country code for localeID + * @param scriptCapacity the size of the script buffer to store the + * displayable script code with + * @param status error information if retrieving the displayable script code failed + * @return the actual buffer size needed for the displayable script code. If it's greater + * than scriptCapacity, the returned displayable script code will be truncated. + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getDisplayScript(const char* locale, + const char* displayLocale, + UChar* script, + int32_t scriptCapacity, + UErrorCode* status); + +/** + * Gets the country name suitable for display for the specified locale. + * + * @param locale the locale to get the displayable country code with. NULL may be used to specify the default. + * @param displayLocale Specifies the locale to be used to display the name. In other words, + * if the locale's language code is "en", passing Locale::getFrench() for + * inLocale would result in "Anglais", while passing Locale::getGerman() + * for inLocale would result in "Englisch". NULL may be used to specify the default. + * @param country the displayable country code for localeID + * @param countryCapacity the size of the country buffer to store the + * displayable country code with + * @param status error information if retrieving the displayable country code failed + * @return the actual buffer size needed for the displayable country code. If it's greater + * than countryCapacity, the returned displayable country code will be truncated. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getDisplayCountry(const char* locale, + const char* displayLocale, + UChar* country, + int32_t countryCapacity, + UErrorCode* status); + + +/** + * Gets the variant name suitable for display for the specified locale. + * + * @param locale the locale to get the displayable variant code with. NULL may be used to specify the default. + * @param displayLocale Specifies the locale to be used to display the name. In other words, + * if the locale's language code is "en", passing Locale::getFrench() for + * inLocale would result in "Anglais", while passing Locale::getGerman() + * for inLocale would result in "Englisch". NULL may be used to specify the default. + * @param variant the displayable variant code for localeID + * @param variantCapacity the size of the variant buffer to store the + * displayable variant code with + * @param status error information if retrieving the displayable variant code failed + * @return the actual buffer size needed for the displayable variant code. If it's greater + * than variantCapacity, the returned displayable variant code will be truncated. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getDisplayVariant(const char* locale, + const char* displayLocale, + UChar* variant, + int32_t variantCapacity, + UErrorCode* status); + +/** + * Gets the keyword name suitable for display for the specified locale. + * E.g: for the locale string de_DE\@collation=PHONEBOOK, this API gets the display + * string for the keyword collation. + * Usage: + * <code> + * UErrorCode status = U_ZERO_ERROR; + * const char* keyword =NULL; + * int32_t keywordLen = 0; + * int32_t keywordCount = 0; + * UChar displayKeyword[256]; + * int32_t displayKeywordLen = 0; + * UEnumeration* keywordEnum = uloc_openKeywords("de_DE@collation=PHONEBOOK;calendar=TRADITIONAL", &status); + * for(keywordCount = uenum_count(keywordEnum, &status); keywordCount > 0 ; keywordCount--){ + * if(U_FAILURE(status)){ + * ...something went wrong so handle the error... + * break; + * } + * // the uenum_next returns NUL terminated string + * keyword = uenum_next(keywordEnum, &keywordLen, &status); + * displayKeywordLen = uloc_getDisplayKeyword(keyword, "en_US", displayKeyword, 256); + * ... do something interesting ..... + * } + * uenum_close(keywordEnum); + * </code> + * @param keyword The keyword whose display string needs to be returned. + * @param displayLocale Specifies the locale to be used to display the name. In other words, + * if the locale's language code is "en", passing Locale::getFrench() for + * inLocale would result in "Anglais", while passing Locale::getGerman() + * for inLocale would result in "Englisch". NULL may be used to specify the default. + * @param dest the buffer to which the displayable keyword should be written. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param status error information if retrieving the displayable string failed. + * Should not be NULL and should not indicate failure on entry. + * @return the actual buffer size needed for the displayable variant code. + * @see #uloc_openKeywords + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getDisplayKeyword(const char* keyword, + const char* displayLocale, + UChar* dest, + int32_t destCapacity, + UErrorCode* status); +/** + * Gets the value of the keyword suitable for display for the specified locale. + * E.g: for the locale string de_DE\@collation=PHONEBOOK, this API gets the display + * string for PHONEBOOK, in the display locale, when "collation" is specified as the keyword. + * + * @param locale The locale to get the displayable variant code with. NULL may be used to specify the default. + * @param keyword The keyword for whose value should be used. + * @param displayLocale Specifies the locale to be used to display the name. In other words, + * if the locale's language code is "en", passing Locale::getFrench() for + * inLocale would result in "Anglais", while passing Locale::getGerman() + * for inLocale would result in "Englisch". NULL may be used to specify the default. + * @param dest the buffer to which the displayable keyword should be written. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param status error information if retrieving the displayable string failed. + * Should not be NULL and must not indicate failure on entry. + * @return the actual buffer size needed for the displayable variant code. + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getDisplayKeywordValue( const char* locale, + const char* keyword, + const char* displayLocale, + UChar* dest, + int32_t destCapacity, + UErrorCode* status); +/** + * Gets the full name suitable for display for the specified locale. + * + * @param localeID the locale to get the displayable name with. NULL may be used to specify the default. + * @param inLocaleID Specifies the locale to be used to display the name. In other words, + * if the locale's language code is "en", passing Locale::getFrench() for + * inLocale would result in "Anglais", while passing Locale::getGerman() + * for inLocale would result in "Englisch". NULL may be used to specify the default. + * @param result the displayable name for localeID + * @param maxResultSize the size of the name buffer to store the + * displayable full name with + * @param err error information if retrieving the displayable name failed + * @return the actual buffer size needed for the displayable name. If it's greater + * than maxResultSize, the returned displayable name will be truncated. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getDisplayName(const char* localeID, + const char* inLocaleID, + UChar* result, + int32_t maxResultSize, + UErrorCode* err); + + +/** + * Gets the specified locale from a list of all available locales. + * The return value is a pointer to an item of + * a locale name array. Both this array and the pointers + * it contains are owned by ICU and should not be deleted or written through + * by the caller. The locale name is terminated by a null pointer. + * @param n the specific locale name index of the available locale list + * @return a specified locale name of all available locales + * @stable ICU 2.0 + */ +U_STABLE const char* U_EXPORT2 +uloc_getAvailable(int32_t n); + +/** + * Gets the size of the all available locale list. + * + * @return the size of the locale list + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 uloc_countAvailable(void); + +/** + * + * Gets a list of all available language codes defined in ISO 639. This is a pointer + * to an array of pointers to arrays of char. All of these pointers are owned + * by ICU-- do not delete them, and do not write through them. The array is + * terminated with a null pointer. + * @return a list of all available language codes + * @stable ICU 2.0 + */ +U_STABLE const char* const* U_EXPORT2 +uloc_getISOLanguages(void); + +/** + * + * Gets a list of all available 2-letter country codes defined in ISO 639. This is a + * pointer to an array of pointers to arrays of char. All of these pointers are + * owned by ICU-- do not delete them, and do not write through them. The array is + * terminated with a null pointer. + * @return a list of all available country codes + * @stable ICU 2.0 + */ +U_STABLE const char* const* U_EXPORT2 +uloc_getISOCountries(void); + +/** + * Truncate the locale ID string to get the parent locale ID. + * Copies the part of the string before the last underscore. + * The parent locale ID will be an empty string if there is no + * underscore, or if there is only one underscore at localeID[0]. + * + * @param localeID Input locale ID string. + * @param parent Output string buffer for the parent locale ID. + * @param parentCapacity Size of the output buffer. + * @param err A UErrorCode value. + * @return The length of the parent locale ID. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getParent(const char* localeID, + char* parent, + int32_t parentCapacity, + UErrorCode* err); + + + + +/** + * Gets the full name for the specified locale. + * Note: This has the effect of 'canonicalizing' the string to + * a certain extent. Upper and lower case are set as needed, + * and if the components were in 'POSIX' format they are changed to + * ICU format. It does NOT map aliased names in any way. + * See the top of this header file. + * This API strips off the keyword part, so "de_DE\@collation=phonebook" + * will become "de_DE". + * This API supports preflighting. + * + * @param localeID the locale to get the full name with + * @param name fill in buffer for the name without keywords. + * @param nameCapacity capacity of the fill in buffer. + * @param err error information if retrieving the full name failed + * @return the actual buffer size needed for the full name. If it's greater + * than nameCapacity, the returned full name will be truncated. + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getBaseName(const char* localeID, + char* name, + int32_t nameCapacity, + UErrorCode* err); + +/** + * Gets an enumeration of keywords for the specified locale. Enumeration + * must get disposed of by the client using uenum_close function. + * + * @param localeID the locale to get the variant code with + * @param status error information if retrieving the keywords failed + * @return enumeration of keywords or NULL if there are no keywords. + * @stable ICU 2.8 + */ +U_STABLE UEnumeration* U_EXPORT2 +uloc_openKeywords(const char* localeID, + UErrorCode* status); + +/** + * Get the value for a keyword. Locale name does not need to be normalized. + * + * @param localeID locale name containing the keyword ("de_DE@currency=EURO;collation=PHONEBOOK") + * @param keywordName name of the keyword for which we want the value. Case insensitive. + * @param buffer receiving buffer + * @param bufferCapacity capacity of receiving buffer + * @param status containing error code - buffer not big enough. + * @return the length of keyword value + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +uloc_getKeywordValue(const char* localeID, + const char* keywordName, + char* buffer, int32_t bufferCapacity, + UErrorCode* status); + + +/** + * Set the value of the specified keyword. + * NOTE: Unlike almost every other ICU function which takes a + * buffer, this function will NOT truncate the output text. If a + * BUFFER_OVERFLOW_ERROR is received, it means that the original + * buffer is untouched. This is done to prevent incorrect or possibly + * even malformed locales from being generated and used. + * + * @param keywordName name of the keyword to be set. Case insensitive. + * @param keywordValue value of the keyword to be set. If 0-length or + * NULL, will result in the keyword being removed. No error is given if + * that keyword does not exist. + * @param buffer input buffer containing locale to be modified. + * @param bufferCapacity capacity of receiving buffer + * @param status containing error code - buffer not big enough. + * @return the length needed for the buffer + * @see uloc_getKeywordValue + * @stable ICU 3.2 + */ +U_STABLE int32_t U_EXPORT2 +uloc_setKeywordValue(const char* keywordName, + const char* keywordValue, + char* buffer, int32_t bufferCapacity, + UErrorCode* status); + +/** + * enums for the return value for the character and line orientation + * functions. + * @draft ICU 4.0 + */ +typedef enum { + ULOC_LAYOUT_LTR = 0, /* left-to-right. */ + ULOC_LAYOUT_RTL = 1, /* right-to-left. */ + ULOC_LAYOUT_TTB = 2, /* top-to-bottom. */ + ULOC_LAYOUT_BTT = 3, /* bottom-to-top. */ + ULOC_LAYOUT_UNKNOWN +} ULayoutType; + +/** + * Get the layout character orientation for the specified locale. + * + * @param localeId locale name + * @param status Error status + * @return an enum indicating the layout orientation for characters. + * @draft ICU 4.0 + */ +U_DRAFT ULayoutType U_EXPORT2 +uloc_getCharacterOrientation(const char* localeId, + UErrorCode *status); + +/** + * Get the layout line orientation for the specified locale. + * + * @param localeId locale name + * @param status Error status + * @return an enum indicating the layout orientation for lines. + * @draft ICU 4.0 + */ +U_DRAFT ULayoutType U_EXPORT2 +uloc_getLineOrientation(const char* localeId, + UErrorCode *status); + +/** + * enums for the 'outResult' parameter return value + * @see uloc_acceptLanguageFromHTTP + * @see uloc_acceptLanguage + * @stable ICU 3.2 + */ +typedef enum { + ULOC_ACCEPT_FAILED = 0, /* No exact match was found. */ + ULOC_ACCEPT_VALID = 1, /* An exact match was found. */ + ULOC_ACCEPT_FALLBACK = 2 /* A fallback was found, for example, + Accept list contained 'ja_JP' + which matched available locale 'ja'. */ +} UAcceptResult; + + +/** + * Based on a HTTP header from a web browser and a list of available locales, + * determine an acceptable locale for the user. + * @param result - buffer to accept the result locale + * @param resultAvailable the size of the result buffer. + * @param outResult - An out parameter that contains the fallback status + * @param httpAcceptLanguage - "Accept-Language:" header as per HTTP. + * @param availableLocales - list of available locales to match + * @param status Error status, may be BUFFER_OVERFLOW_ERROR + * @return length needed for the locale. + * @stable ICU 3.2 + */ +U_STABLE int32_t U_EXPORT2 +uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, + UAcceptResult *outResult, + const char *httpAcceptLanguage, + UEnumeration* availableLocales, + UErrorCode *status); + +/** + * Based on a list of available locales, + * determine an acceptable locale for the user. + * @param result - buffer to accept the result locale + * @param resultAvailable the size of the result buffer. + * @param outResult - An out parameter that contains the fallback status + * @param acceptList - list of acceptable languages + * @param acceptListCount - count of acceptList items + * @param availableLocales - list of available locales to match + * @param status Error status, may be BUFFER_OVERFLOW_ERROR + * @return length needed for the locale. + * @stable ICU 3.2 + */ +U_STABLE int32_t U_EXPORT2 +uloc_acceptLanguage(char *result, int32_t resultAvailable, + UAcceptResult *outResult, const char **acceptList, + int32_t acceptListCount, + UEnumeration* availableLocales, + UErrorCode *status); + + +/** + * Gets the ICU locale ID for the specified Win32 LCID value. + * + * @param hostID the Win32 LCID to translate + * @param locale the output buffer for the ICU locale ID, which will be NUL-terminated + * if there is room. + * @param localeCapacity the size of the output buffer + * @param status an error is returned if the LCID is unrecognized or the output buffer + * is too small + * @return actual the actual size of the locale ID, not including NUL-termination + * @stable ICU 4.0 + */ +U_DRAFT int32_t U_EXPORT2 +uloc_getLocaleForLCID(uint32_t hostID, char *locale, int32_t localeCapacity, + UErrorCode *status); + + +/** + * Add the likely subtags for a provided locale ID, per the algorithm described + * in the following CLDR technical report: + * + * http://www.unicode.org/reports/tr35/#Likely_Subtags + * + * If localeID is already in the maximal form, or there is no data available + * for maximization, it will be copied to the output buffer. For example, + * "und-Zzzz" cannot be maximized, since there is no reasonable maximization. + * + * Examples: + * + * "en" maximizes to "en_Latn_US" + * + * "de" maximizes to "de_Latn_US" + * + * "sr" maximizes to "sr_Cyrl_RS" + * + * "sh" maximizes to "sr_Latn_RS" (Note this will not reverse.) + * + * "zh_Hani" maximizes to "zh_Hans_CN" (Note this will not reverse.) + * + * @param localeID The locale to maximize + * @param maximizedLocaleID The maximized locale + * @param maximizedLocaleIDCapacity The capacity of the maximizedLocaleID buffer + * @param err Error information if maximizing the locale failed. If the length + * of the localeID and the null-terminator is greater than the maximum allowed size, + * or the localeId is not well-formed, the error code is U_ILLEGAL_ARGUMENT_ERROR. + * @return The actual buffer size needed for the maximized locale. If it's + * greater than maximizedLocaleIDCapacity, the returned ID will be truncated. + * On error, the return value is -1. + * @draft ICU 4.0 + */ +U_DRAFT int32_t U_EXPORT2 +uloc_addLikelySubtags(const char* localeID, + char* maximizedLocaleID, + int32_t maximizedLocaleIDCapacity, + UErrorCode* err); + + +/** + * Minimize the subtags for a provided locale ID, per the algorithm described + * in the following CLDR technical report: + * + * http://www.unicode.org/reports/tr35/#Likely_Subtags + * + * If localeID is already in the minimal form, or there is no data available + * for minimization, it will be copied to the output buffer. Since the + * minimization algorithm relies on proper maximization, see the comments + * for uloc_addLikelySubtags for reasons why there might not be any data. + * + * Examples: + * + * "en_Latn_US" minimizes to "en" + * + * "de_Latn_US" minimizes to "de" + * + * "sr_Cyrl_RS" minimizes to "sr" + * + * "zh_Hant_TW" minimizes to "zh_TW" (The region is preferred to the + * script, and minimizing to "zh" would imply "zh_Hans_CN".) + * + * @param localeID The locale to minimize + * @param minimizedLocaleID The minimized locale + * @param minimizedLocaleIDCapacity The capacity of the minimizedLocaleID buffer + * @param err Error information if minimizing the locale failed. If the length + * of the localeID and the null-terminator is greater than the maximum allowed size, + * or the localeId is not well-formed, the error code is U_ILLEGAL_ARGUMENT_ERROR. + * @return The actual buffer size needed for the minimized locale. If it's + * greater than minimizedLocaleIDCapacity, the returned ID will be truncated. + * On error, the return value is -1. + * @draft ICU 4.0 + */ +U_DRAFT int32_t U_EXPORT2 +uloc_minimizeSubtags(const char* localeID, + char* minimizedLocaleID, + int32_t minimizedLocaleIDCapacity, + UErrorCode* err); + +#endif /*_ULOC*/ diff --git a/utils/openttd/unicode/umachine.h b/utils/openttd/unicode/umachine.h new file mode 100644 index 00000000000..083f9cf014c --- /dev/null +++ b/utils/openttd/unicode/umachine.h @@ -0,0 +1,338 @@ +/* +****************************************************************************** +* +* Copyright (C) 1999-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +****************************************************************************** +* file name: umachine.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 1999sep13 +* created by: Markus W. Scherer +* +* This file defines basic types and constants for utf.h to be +* platform-independent. umachine.h and utf.h are included into +* utypes.h to provide all the general definitions for ICU. +* All of these definitions used to be in utypes.h before +* the UTF-handling macros made this unmaintainable. +*/ + +#ifndef __UMACHINE_H__ +#define __UMACHINE_H__ + + +/** + * \file + * \brief Basic types and constants for UTF + * + * <h2> Basic types and constants for UTF </h2> + * This file defines basic types and constants for utf.h to be + * platform-independent. umachine.h and utf.h are included into + * utypes.h to provide all the general definitions for ICU. + * All of these definitions used to be in utypes.h before + * the UTF-handling macros made this unmaintainable. + * + */ +/*==========================================================================*/ +/* Include platform-dependent definitions */ +/* which are contained in the platform-specific file platform.h */ +/*==========================================================================*/ + +#if defined(U_PALMOS) +# include "unicode/ppalmos.h" +#elif defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) +# include "unicode/pwin32.h" +#else +# include "unicode/platform.h" +#endif + +/* + * ANSI C headers: + * stddef.h defines wchar_t + */ +#include <stddef.h> + +/*==========================================================================*/ +/* XP_CPLUSPLUS is a cross-platform symbol which should be defined when */ +/* using C++. It should not be defined when compiling under C. */ +/*==========================================================================*/ + +#ifdef __cplusplus +# ifndef XP_CPLUSPLUS +# define XP_CPLUSPLUS +# endif +#else +# undef XP_CPLUSPLUS +#endif + +/*==========================================================================*/ +/* For C wrappers, we use the symbol U_STABLE. */ +/* This works properly if the includer is C or C++. */ +/* Functions are declared U_STABLE return-type U_EXPORT2 function-name()... */ +/*==========================================================================*/ + +/** + * \def U_CFUNC + * This is used in a declaration of a library private ICU C function. + * @stable ICU 2.4 + */ + +/** + * \def U_CDECL_BEGIN + * This is used to begin a declaration of a library private ICU C API. + * @stable ICU 2.4 + */ + +/** + * \def U_CDECL_END + * This is used to end a declaration of a library private ICU C API + * @stable ICU 2.4 + */ + +#ifdef XP_CPLUSPLUS +# define U_CFUNC extern "C" +# define U_CDECL_BEGIN extern "C" { +# define U_CDECL_END } +#else +# define U_CFUNC extern +# define U_CDECL_BEGIN +# define U_CDECL_END +#endif + +/** This is used to declare a function as a public ICU C API @stable ICU 2.0*/ +#define U_CAPI U_CFUNC U_EXPORT +#define U_STABLE U_CAPI +#define U_DRAFT U_CAPI +#define U_DEPRECATED U_CAPI +#define U_OBSOLETE U_CAPI +#define U_INTERNAL U_CAPI + +/*==========================================================================*/ +/* limits for int32_t etc., like in POSIX inttypes.h */ +/*==========================================================================*/ + +#ifndef INT8_MIN +/** The smallest value an 8 bit signed integer can hold @stable ICU 2.0 */ +# define INT8_MIN ((int8_t)(-128)) +#endif +#ifndef INT16_MIN +/** The smallest value a 16 bit signed integer can hold @stable ICU 2.0 */ +# define INT16_MIN ((int16_t)(-32767-1)) +#endif +#ifndef INT32_MIN +/** The smallest value a 32 bit signed integer can hold @stable ICU 2.0 */ +# define INT32_MIN ((int32_t)(-2147483647-1)) +#endif + +#ifndef INT8_MAX +/** The largest value an 8 bit signed integer can hold @stable ICU 2.0 */ +# define INT8_MAX ((int8_t)(127)) +#endif +#ifndef INT16_MAX +/** The largest value a 16 bit signed integer can hold @stable ICU 2.0 */ +# define INT16_MAX ((int16_t)(32767)) +#endif +#ifndef INT32_MAX +/** The largest value a 32 bit signed integer can hold @stable ICU 2.0 */ +# define INT32_MAX ((int32_t)(2147483647)) +#endif + +#ifndef UINT8_MAX +/** The largest value an 8 bit unsigned integer can hold @stable ICU 2.0 */ +# define UINT8_MAX ((uint8_t)(255U)) +#endif +#ifndef UINT16_MAX +/** The largest value a 16 bit unsigned integer can hold @stable ICU 2.0 */ +# define UINT16_MAX ((uint16_t)(65535U)) +#endif +#ifndef UINT32_MAX +/** The largest value a 32 bit unsigned integer can hold @stable ICU 2.0 */ +# define UINT32_MAX ((uint32_t)(4294967295U)) +#endif + +#if defined(U_INT64_T_UNAVAILABLE) +# error int64_t is required for decimal format and rule-based number format. +#else +# ifndef INT64_C +/** + * Provides a platform independent way to specify a signed 64-bit integer constant. + * note: may be wrong for some 64 bit platforms - ensure your compiler provides INT64_C + * @stable ICU 2.8 + */ +# define INT64_C(c) c ## LL +# endif +# ifndef UINT64_C +/** + * Provides a platform independent way to specify an unsigned 64-bit integer constant. + * note: may be wrong for some 64 bit platforms - ensure your compiler provides UINT64_C + * @stable ICU 2.8 + */ +# define UINT64_C(c) c ## ULL +# endif +# ifndef U_INT64_MIN +/** The smallest value a 64 bit signed integer can hold @stable ICU 2.8 */ +# define U_INT64_MIN ((int64_t)(INT64_C(-9223372036854775807)-1)) +# endif +# ifndef U_INT64_MAX +/** The largest value a 64 bit signed integer can hold @stable ICU 2.8 */ +# define U_INT64_MAX ((int64_t)(INT64_C(9223372036854775807))) +# endif +# ifndef U_UINT64_MAX +/** The largest value a 64 bit unsigned integer can hold @stable ICU 2.8 */ +# define U_UINT64_MAX ((uint64_t)(UINT64_C(18446744073709551615))) +# endif +#endif + +/*==========================================================================*/ +/* Boolean data type */ +/*==========================================================================*/ + +/** The ICU boolean type @stable ICU 2.0 */ +typedef int8_t UBool; + +#ifndef TRUE +/** The TRUE value of a UBool @stable ICU 2.0 */ +# define TRUE 1 +#endif +#ifndef FALSE +/** The FALSE value of a UBool @stable ICU 2.0 */ +# define FALSE 0 +#endif + + +/*==========================================================================*/ +/* Unicode data types */ +/*==========================================================================*/ + +/* wchar_t-related definitions -------------------------------------------- */ + +/** + * \def U_HAVE_WCHAR_H + * Indicates whether <wchar.h> is available (1) or not (0). Set to 1 by default. + * + * @stable ICU 2.0 + */ +#ifndef U_HAVE_WCHAR_H +# define U_HAVE_WCHAR_H 1 +#endif + +/** + * \def U_SIZEOF_WCHAR_T + * U_SIZEOF_WCHAR_T==sizeof(wchar_t) (0 means it is not defined or autoconf could not set it) + * + * @stable ICU 2.0 + */ +#if U_SIZEOF_WCHAR_T==0 +# undef U_SIZEOF_WCHAR_T +# define U_SIZEOF_WCHAR_T 4 +#endif + +/* + * \def U_WCHAR_IS_UTF16 + * Defined if wchar_t uses UTF-16. + * + * @stable ICU 2.0 + */ +/* + * \def U_WCHAR_IS_UTF32 + * Defined if wchar_t uses UTF-32. + * + * @stable ICU 2.0 + */ +#if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32) +# ifdef __STDC_ISO_10646__ +# if (U_SIZEOF_WCHAR_T==2) +# define U_WCHAR_IS_UTF16 +# elif (U_SIZEOF_WCHAR_T==4) +# define U_WCHAR_IS_UTF32 +# endif +# elif defined __UCS2__ +# if (__OS390__ || __OS400__) && (U_SIZEOF_WCHAR_T==2) +# define U_WCHAR_IS_UTF16 +# endif +# elif defined __UCS4__ +# if (U_SIZEOF_WCHAR_T==4) +# define U_WCHAR_IS_UTF32 +# endif +# elif defined(U_WINDOWS) +# define U_WCHAR_IS_UTF16 +# endif +#endif + +/* UChar and UChar32 definitions -------------------------------------------- */ + +/** Number of bytes in a UChar. @stable ICU 2.0 */ +#define U_SIZEOF_UCHAR 2 + +/** + * \var UChar + * Define UChar to be wchar_t if that is 16 bits wide; always assumed to be unsigned. + * If wchar_t is not 16 bits wide, then define UChar to be uint16_t. + * This makes the definition of UChar platform-dependent + * but allows direct string type compatibility with platforms with + * 16-bit wchar_t types. + * + * @stable ICU 2.0 + */ + +/* Define UChar to be compatible with wchar_t if possible. */ +#if U_SIZEOF_WCHAR_T==2 + typedef wchar_t UChar; +#else + typedef uint16_t UChar; +#endif + +/** + * Define UChar32 as a type for single Unicode code points. + * UChar32 is a signed 32-bit integer (same as int32_t). + * + * The Unicode code point range is 0..0x10ffff. + * All other values (negative or >=0x110000) are illegal as Unicode code points. + * They may be used as sentinel values to indicate "done", "error" + * or similar non-code point conditions. + * + * Before ICU 2.4 (Jitterbug 2146), UChar32 was defined + * to be wchar_t if that is 32 bits wide (wchar_t may be signed or unsigned) + * or else to be uint32_t. + * That is, the definition of UChar32 was platform-dependent. + * + * @see U_SENTINEL + * @stable ICU 2.4 + */ +typedef int32_t UChar32; + +/*==========================================================================*/ +/* U_INLINE and U_ALIGN_CODE Set default values if these are not already */ +/* defined. Definitions normally are in */ +/* platform.h or the corresponding file for */ +/* the OS in use. */ +/*==========================================================================*/ + +#ifndef U_HIDE_INTERNAL_API + +/** + * \def U_ALIGN_CODE + * This is used to align code fragments to a specific byte boundary. + * This is useful for getting consistent performance test results. + * @internal + */ +#ifndef U_ALIGN_CODE +# define U_ALIGN_CODE(n) +#endif + +#endif /* U_HIDE_INTERNAL_API */ + +#ifndef U_INLINE +# ifdef XP_CPLUSPLUS +# define U_INLINE inline +# else +# define U_INLINE +# endif +#endif + +#include "unicode/urename.h" + +#endif diff --git a/utils/openttd/unicode/umisc.h b/utils/openttd/unicode/umisc.h new file mode 100644 index 00000000000..d85451fc767 --- /dev/null +++ b/utils/openttd/unicode/umisc.h @@ -0,0 +1,60 @@ +/* +********************************************************************** +* Copyright (C) 1999-2006, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* file name: umisc.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 1999oct15 +* created by: Markus W. Scherer +*/ + +#ifndef UMISC_H +#define UMISC_H + +#include "unicode/utypes.h" + +/** + * \file + * \brief C API:misc definitions + * + * This file contains miscellaneous definitions for the C APIs. + */ + +U_CDECL_BEGIN + +/** A struct representing a range of text containing a specific field + * @stable ICU 2.0 + */ +typedef struct UFieldPosition { + /** + * The field + * @stable ICU 2.0 + */ + int32_t field; + /** + * The start of the text range containing field + * @stable ICU 2.0 + */ + int32_t beginIndex; + /** + * The limit of the text range containing field + * @stable ICU 2.0 + */ + int32_t endIndex; +} UFieldPosition; + +#if !UCONFIG_NO_SERVICE +/** + * Opaque type returned by registerInstance, registerFactory and unregister for service registration. + * @stable ICU 2.6 + */ +typedef const void* URegistryKey; +#endif + +U_CDECL_END + +#endif diff --git a/utils/openttd/unicode/unifilt.h b/utils/openttd/unicode/unifilt.h new file mode 100644 index 00000000000..5bf1ba4e4fd --- /dev/null +++ b/utils/openttd/unicode/unifilt.h @@ -0,0 +1,127 @@ +/* +********************************************************************** +* Copyright (C) 1999-2006, International Business Machines Corporation and others. +* All Rights Reserved. +********************************************************************** +* Date Name Description +* 11/17/99 aliu Creation. +********************************************************************** +*/ +#ifndef UNIFILT_H +#define UNIFILT_H + +#include "unicode/unifunct.h" +#include "unicode/unimatch.h" + +/** + * \file + * \brief C++ API: Unicode Filter + */ + +U_NAMESPACE_BEGIN + +/** + * U_ETHER is used to represent character values for positions outside + * a range. For example, transliterator uses this to represent + * characters outside the range contextStart..contextLimit-1. This + * allows explicit matching by rules and UnicodeSets of text outside a + * defined range. + * @stable ICU 3.0 + */ +#define U_ETHER ((UChar)0xFFFF) + +/** + * + * <code>UnicodeFilter</code> defines a protocol for selecting a + * subset of the full range (U+0000 to U+10FFFF) of Unicode characters. + * Currently, filters are used in conjunction with classes like {@link + * Transliterator} to only process selected characters through a + * transformation. + * + * <p>Note: UnicodeFilter currently stubs out two pure virtual methods + * of its base class, UnicodeMatcher. These methods are toPattern() + * and matchesIndexValue(). This is done so that filter classes that + * are not actually used as matchers -- specifically, those in the + * UnicodeFilterLogic component, and those in tests -- can continue to + * work without defining these methods. As long as a filter is not + * used in an RBT during real transliteration, these methods will not + * be called. However, this breaks the UnicodeMatcher base class + * protocol, and it is not a correct solution. + * + * <p>In the future we may revisit the UnicodeMatcher / UnicodeFilter + * hierarchy and either redesign it, or simply remove the stubs in + * UnicodeFilter and force subclasses to implement the full + * UnicodeMatcher protocol. + * + * @see UnicodeFilterLogic + * @stable ICU 2.0 + */ +class U_COMMON_API UnicodeFilter : public UnicodeFunctor, public UnicodeMatcher { + +public: + /** + * Destructor + * @stable ICU 2.0 + */ + virtual ~UnicodeFilter(); + + /** + * Returns <tt>true</tt> for characters that are in the selected + * subset. In other words, if a character is <b>to be + * filtered</b>, then <tt>contains()</tt> returns + * <b><tt>false</tt></b>. + * @stable ICU 2.0 + */ + virtual UBool contains(UChar32 c) const = 0; + + /** + * UnicodeFunctor API. Cast 'this' to a UnicodeMatcher* pointer + * and return the pointer. + * @stable ICU 2.4 + */ + virtual UnicodeMatcher* toMatcher() const; + + /** + * Implement UnicodeMatcher API. + * @stable ICU 2.4 + */ + virtual UMatchDegree matches(const Replaceable& text, + int32_t& offset, + int32_t limit, + UBool incremental); + + /** + * UnicodeFunctor API. Nothing to do. + * @stable ICU 2.4 + */ + virtual void setData(const TransliterationRuleData*); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.2 + */ + virtual UClassID getDynamicClassID() const = 0; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.2 + */ + static UClassID U_EXPORT2 getStaticClassID(); + +protected: + + /* + * Since this class has pure virtual functions, + * a constructor can't be used. + * @stable ICU 2.0 + */ +/* UnicodeFilter();*/ +}; + +/*inline UnicodeFilter::UnicodeFilter() {}*/ + +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/unifunct.h b/utils/openttd/unicode/unifunct.h new file mode 100644 index 00000000000..3aa7b0358c0 --- /dev/null +++ b/utils/openttd/unicode/unifunct.h @@ -0,0 +1,125 @@ +/* +********************************************************************** +* Copyright (c) 2002-2005, International Business Machines Corporation +* and others. All Rights Reserved. +********************************************************************** +* Date Name Description +* 01/14/2002 aliu Creation. +********************************************************************** +*/ +#ifndef UNIFUNCT_H +#define UNIFUNCT_H + +#include "unicode/utypes.h" +#include "unicode/uobject.h" + +/** + * \file + * \brief C++ API: Unicode Functor + */ + +U_NAMESPACE_BEGIN + +class UnicodeMatcher; +class UnicodeReplacer; +class TransliterationRuleData; + +/** + * <code>UnicodeFunctor</code> is an abstract base class for objects + * that perform match and/or replace operations on Unicode strings. + * @author Alan Liu + * @stable ICU 2.4 + */ +class U_COMMON_API UnicodeFunctor : public UObject { + +public: + + /** + * Destructor + * @stable ICU 2.4 + */ + virtual ~UnicodeFunctor(); + + /** + * Return a copy of this object. All UnicodeFunctor objects + * have to support cloning in order to allow classes using + * UnicodeFunctor to implement cloning. + * @stable ICU 2.4 + */ + virtual UnicodeFunctor* clone() const = 0; + + /** + * Cast 'this' to a UnicodeMatcher* pointer and return the + * pointer, or null if this is not a UnicodeMatcher*. Subclasses + * that mix in UnicodeMatcher as a base class must override this. + * This protocol is required because a pointer to a UnicodeFunctor + * cannot be cast to a pointer to a UnicodeMatcher, since + * UnicodeMatcher is a mixin that does not derive from + * UnicodeFunctor. + * @stable ICU 2.4 + */ + virtual UnicodeMatcher* toMatcher() const; + + /** + * Cast 'this' to a UnicodeReplacer* pointer and return the + * pointer, or null if this is not a UnicodeReplacer*. Subclasses + * that mix in UnicodeReplacer as a base class must override this. + * This protocol is required because a pointer to a UnicodeFunctor + * cannot be cast to a pointer to a UnicodeReplacer, since + * UnicodeReplacer is a mixin that does not derive from + * UnicodeFunctor. + * @stable ICU 2.4 + */ + virtual UnicodeReplacer* toReplacer() const; + + /** + * Return the class ID for this class. This is useful only for + * comparing to a return value from getDynamicClassID(). + * @return The class ID for all objects of this class. + * @stable ICU 2.0 + */ + static UClassID U_EXPORT2 getStaticClassID(void); + + /** + * Returns a unique class ID <b>polymorphically</b>. This method + * is to implement a simple version of RTTI, since not all C++ + * compilers support genuine RTTI. Polymorphic operator==() and + * clone() methods call this method. + * + * <p>Concrete subclasses of UnicodeFunctor should use the macro + * UOBJECT_DEFINE_RTTI_IMPLEMENTATION from uobject.h to + * provide definitios getStaticClassID and getDynamicClassID. + * + * @return The class ID for this object. All objects of a given + * class have the same class ID. Objects of other classes have + * different class IDs. + * @stable ICU 2.4 + */ + virtual UClassID getDynamicClassID(void) const = 0; + + /** + * Set the data object associated with this functor. The data + * object provides context for functor-to-standin mapping. This + * method is required when assigning a functor to a different data + * object. This function MAY GO AWAY later if the architecture is + * changed to pass data object pointers through the API. + * @internal ICU 2.1 + */ + virtual void setData(const TransliterationRuleData*) = 0; + +protected: + + /** + * Since this class has pure virtual functions, + * a constructor can't be used. + * @stable ICU 2.0 + */ + /*UnicodeFunctor();*/ + +}; + +/*inline UnicodeFunctor::UnicodeFunctor() {}*/ + +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/unimatch.h b/utils/openttd/unicode/unimatch.h new file mode 100644 index 00000000000..0dbb14efc20 --- /dev/null +++ b/utils/openttd/unicode/unimatch.h @@ -0,0 +1,163 @@ +/* +* Copyright (C) 2001-2005, International Business Machines Corporation and others. All Rights Reserved. +********************************************************************** +* Date Name Description +* 07/18/01 aliu Creation. +********************************************************************** +*/ +#ifndef UNIMATCH_H +#define UNIMATCH_H + +#include "unicode/utypes.h" + +/** + * \file + * \brief C++ API: Unicode Matcher + */ + + +U_NAMESPACE_BEGIN + +class Replaceable; +class UnicodeString; +class UnicodeSet; + +/** + * Constants returned by <code>UnicodeMatcher::matches()</code> + * indicating the degree of match. + * @stable ICU 2.4 + */ +enum UMatchDegree { + /** + * Constant returned by <code>matches()</code> indicating a + * mismatch between the text and this matcher. The text contains + * a character which does not match, or the text does not contain + * all desired characters for a non-incremental match. + * @stable ICU 2.4 + */ + U_MISMATCH, + + /** + * Constant returned by <code>matches()</code> indicating a + * partial match between the text and this matcher. This value is + * only returned for incremental match operations. All characters + * of the text match, but more characters are required for a + * complete match. Alternatively, for variable-length matchers, + * all characters of the text match, and if more characters were + * supplied at limit, they might also match. + * @stable ICU 2.4 + */ + U_PARTIAL_MATCH, + + /** + * Constant returned by <code>matches()</code> indicating a + * complete match between the text and this matcher. For an + * incremental variable-length match, this value is returned if + * the given text matches, and it is known that additional + * characters would not alter the extent of the match. + * @stable ICU 2.4 + */ + U_MATCH +}; + +/** + * <code>UnicodeMatcher</code> defines a protocol for objects that can + * match a range of characters in a Replaceable string. + * @stable ICU 2.4 + */ +class U_COMMON_API UnicodeMatcher /* not : public UObject because this is an interface/mixin class */ { + +public: + /** + * Destructor. + * @stable ICU 2.4 + */ + virtual ~UnicodeMatcher(); + + /** + * Return a UMatchDegree value indicating the degree of match for + * the given text at the given offset. Zero, one, or more + * characters may be matched. + * + * Matching in the forward direction is indicated by limit > + * offset. Characters from offset forwards to limit-1 will be + * considered for matching. + * + * Matching in the reverse direction is indicated by limit < + * offset. Characters from offset backwards to limit+1 will be + * considered for matching. + * + * If limit == offset then the only match possible is a zero + * character match (which subclasses may implement if desired). + * + * As a side effect, advance the offset parameter to the limit of + * the matched substring. In the forward direction, this will be + * the index of the last matched character plus one. In the + * reverse direction, this will be the index of the last matched + * character minus one. + * + * <p>Note: This method is not const because some classes may + * modify their state as the result of a match. + * + * @param text the text to be matched + * @param offset on input, the index into text at which to begin + * matching. On output, the limit of the matched text. The + * number of matched characters is the output value of offset + * minus the input value. Offset should always point to the + * HIGH SURROGATE (leading code unit) of a pair of surrogates, + * both on entry and upon return. + * @param limit the limit index of text to be matched. Greater + * than offset for a forward direction match, less than offset for + * a backward direction match. The last character to be + * considered for matching will be text.charAt(limit-1) in the + * forward direction or text.charAt(limit+1) in the backward + * direction. + * @param incremental if TRUE, then assume further characters may + * be inserted at limit and check for partial matching. Otherwise + * assume the text as given is complete. + * @return a match degree value indicating a full match, a partial + * match, or a mismatch. If incremental is FALSE then + * U_PARTIAL_MATCH should never be returned. + * @stable ICU 2.4 + */ + virtual UMatchDegree matches(const Replaceable& text, + int32_t& offset, + int32_t limit, + UBool incremental) = 0; + + /** + * Returns a string representation of this matcher. If the result of + * calling this function is passed to the appropriate parser, it + * will produce another matcher that is equal to this one. + * @param result the string to receive the pattern. Previous + * contents will be deleted. + * @param escapeUnprintable if TRUE then convert unprintable + * character to their hex escape representations, \\uxxxx or + * \\Uxxxxxxxx. Unprintable characters are those other than + * U+000A, U+0020..U+007E. + * @stable ICU 2.4 + */ + virtual UnicodeString& toPattern(UnicodeString& result, + UBool escapeUnprintable = FALSE) const = 0; + + /** + * Returns TRUE if this matcher will match a character c, where c + * & 0xFF == v, at offset, in the forward direction (with limit > + * offset). This is used by <tt>RuleBasedTransliterator</tt> for + * indexing. + * @stable ICU 2.4 + */ + virtual UBool matchesIndexValue(uint8_t v) const = 0; + + /** + * Union the set of all characters that may be matched by this object + * into the given set. + * @param toUnionTo the set into which to union the source characters + * @stable ICU 2.4 + */ + virtual void addMatchSetTo(UnicodeSet& toUnionTo) const = 0; +}; + +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/uniset.h b/utils/openttd/unicode/uniset.h new file mode 100644 index 00000000000..78396619952 --- /dev/null +++ b/utils/openttd/unicode/uniset.h @@ -0,0 +1,1566 @@ +/* +*************************************************************************** +* Copyright (C) 1999-2008, International Business Machines Corporation +* and others. All Rights Reserved. +*************************************************************************** +* Date Name Description +* 10/20/99 alan Creation. +*************************************************************************** +*/ + +#ifndef UNICODESET_H +#define UNICODESET_H + +#include "unicode/unifilt.h" +#include "unicode/unistr.h" +#include "unicode/uset.h" + +/** + * \file + * \brief C++ API: Unicode Set + */ + +U_NAMESPACE_BEGIN + +class BMPSet; +class ParsePosition; +class SymbolTable; +class UnicodeSetStringSpan; +class UVector; +class RuleCharacterIterator; + +/** + * A mutable set of Unicode characters and multicharacter strings. Objects of this class + * represent <em>character classes</em> used in regular expressions. + * A character specifies a subset of Unicode code points. Legal + * code points are U+0000 to U+10FFFF, inclusive. + * + * <p>The UnicodeSet class is not designed to be subclassed. + * + * <p><code>UnicodeSet</code> supports two APIs. The first is the + * <em>operand</em> API that allows the caller to modify the value of + * a <code>UnicodeSet</code> object. It conforms to Java 2's + * <code>java.util.Set</code> interface, although + * <code>UnicodeSet</code> does not actually implement that + * interface. All methods of <code>Set</code> are supported, with the + * modification that they take a character range or single character + * instead of an <code>Object</code>, and they take a + * <code>UnicodeSet</code> instead of a <code>Collection</code>. The + * operand API may be thought of in terms of boolean logic: a boolean + * OR is implemented by <code>add</code>, a boolean AND is implemented + * by <code>retain</code>, a boolean XOR is implemented by + * <code>complement</code> taking an argument, and a boolean NOT is + * implemented by <code>complement</code> with no argument. In terms + * of traditional set theory function names, <code>add</code> is a + * union, <code>retain</code> is an intersection, <code>remove</code> + * is an asymmetric difference, and <code>complement</code> with no + * argument is a set complement with respect to the superset range + * <code>MIN_VALUE-MAX_VALUE</code> + * + * <p>The second API is the + * <code>applyPattern()</code>/<code>toPattern()</code> API from the + * <code>java.text.Format</code>-derived classes. Unlike the + * methods that add characters, add categories, and control the logic + * of the set, the method <code>applyPattern()</code> sets all + * attributes of a <code>UnicodeSet</code> at once, based on a + * string pattern. + * + * <p><b>Pattern syntax</b></p> + * + * Patterns are accepted by the constructors and the + * <code>applyPattern()</code> methods and returned by the + * <code>toPattern()</code> method. These patterns follow a syntax + * similar to that employed by version 8 regular expression character + * classes. Here are some simple examples: + * + * \htmlonly<blockquote>\endhtmlonly + * <table> + * <tr align="top"> + * <td nowrap valign="top" align="left"><code>[]</code></td> + * <td valign="top">No characters</td> + * </tr><tr align="top"> + * <td nowrap valign="top" align="left"><code>[a]</code></td> + * <td valign="top">The character 'a'</td> + * </tr><tr align="top"> + * <td nowrap valign="top" align="left"><code>[ae]</code></td> + * <td valign="top">The characters 'a' and 'e'</td> + * </tr> + * <tr> + * <td nowrap valign="top" align="left"><code>[a-e]</code></td> + * <td valign="top">The characters 'a' through 'e' inclusive, in Unicode code + * point order</td> + * </tr> + * <tr> + * <td nowrap valign="top" align="left"><code>[\\u4E01]</code></td> + * <td valign="top">The character U+4E01</td> + * </tr> + * <tr> + * <td nowrap valign="top" align="left"><code>[a{ab}{ac}]</code></td> + * <td valign="top">The character 'a' and the multicharacter strings "ab" and + * "ac"</td> + * </tr> + * <tr> + * <td nowrap valign="top" align="left"><code>[\\p{Lu}]</code></td> + * <td valign="top">All characters in the general category Uppercase Letter</td> + * </tr> + * </table> + * \htmlonly</blockquote>\endhtmlonly + * + * Any character may be preceded by a backslash in order to remove any special + * meaning. White space characters, as defined by UCharacter.isWhitespace(), are + * ignored, unless they are escaped. + * + * <p>Property patterns specify a set of characters having a certain + * property as defined by the Unicode standard. Both the POSIX-like + * "[:Lu:]" and the Perl-like syntax "\\p{Lu}" are recognized. For a + * complete list of supported property patterns, see the User's Guide + * for UnicodeSet at + * <a href="http://icu-project.org/userguide/unicodeSet.html"> + * http://icu-project.org/userguide/unicodeSet.html</a>. + * Actual determination of property data is defined by the underlying + * Unicode database as implemented by UCharacter. + * + * <p>Patterns specify individual characters, ranges of characters, and + * Unicode property sets. When elements are concatenated, they + * specify their union. To complement a set, place a '^' immediately + * after the opening '['. Property patterns are inverted by modifying + * their delimiters; "[:^foo]" and "\\P{foo}". In any other location, + * '^' has no special meaning. + * + * <p>Ranges are indicated by placing two a '-' between two + * characters, as in "a-z". This specifies the range of all + * characters from the left to the right, in Unicode order. If the + * left character is greater than or equal to the + * right character it is a syntax error. If a '-' occurs as the first + * character after the opening '[' or '[^', or if it occurs as the + * last character before the closing ']', then it is taken as a + * literal. Thus "[a\-b]", "[-ab]", and "[ab-]" all indicate the same + * set of three characters, 'a', 'b', and '-'. + * + * <p>Sets may be intersected using the '&' operator or the asymmetric + * set difference may be taken using the '-' operator, for example, + * "[[:L:]&[\\u0000-\\u0FFF]]" indicates the set of all Unicode letters + * with values less than 4096. Operators ('&' and '|') have equal + * precedence and bind left-to-right. Thus + * "[[:L:]-[a-z]-[\\u0100-\\u01FF]]" is equivalent to + * "[[[:L:]-[a-z]]-[\\u0100-\\u01FF]]". This only really matters for + * difference; intersection is commutative. + * + * <table> + * <tr valign=top><td nowrap><code>[a]</code><td>The set containing 'a' + * <tr valign=top><td nowrap><code>[a-z]</code><td>The set containing 'a' + * through 'z' and all letters in between, in Unicode order + * <tr valign=top><td nowrap><code>[^a-z]</code><td>The set containing + * all characters but 'a' through 'z', + * that is, U+0000 through 'a'-1 and 'z'+1 through U+10FFFF + * <tr valign=top><td nowrap><code>[[<em>pat1</em>][<em>pat2</em>]]</code> + * <td>The union of sets specified by <em>pat1</em> and <em>pat2</em> + * <tr valign=top><td nowrap><code>[[<em>pat1</em>]&[<em>pat2</em>]]</code> + * <td>The intersection of sets specified by <em>pat1</em> and <em>pat2</em> + * <tr valign=top><td nowrap><code>[[<em>pat1</em>]-[<em>pat2</em>]]</code> + * <td>The asymmetric difference of sets specified by <em>pat1</em> and + * <em>pat2</em> + * <tr valign=top><td nowrap><code>[:Lu:] or \\p{Lu}</code> + * <td>The set of characters having the specified + * Unicode property; in + * this case, Unicode uppercase letters + * <tr valign=top><td nowrap><code>[:^Lu:] or \\P{Lu}</code> + * <td>The set of characters <em>not</em> having the given + * Unicode property + * </table> + * + * <p><b>Warning</b>: you cannot add an empty string ("") to a UnicodeSet.</p> + * + * <p><b>Formal syntax</b></p> + * + * \htmlonly<blockquote>\endhtmlonly + * <table> + * <tr align="top"> + * <td nowrap valign="top" align="right"><code>pattern :=  </code></td> + * <td valign="top"><code>('[' '^'? item* ']') | + * property</code></td> + * </tr> + * <tr align="top"> + * <td nowrap valign="top" align="right"><code>item :=  </code></td> + * <td valign="top"><code>char | (char '-' char) | pattern-expr<br> + * </code></td> + * </tr> + * <tr align="top"> + * <td nowrap valign="top" align="right"><code>pattern-expr :=  </code></td> + * <td valign="top"><code>pattern | pattern-expr pattern | + * pattern-expr op pattern<br> + * </code></td> + * </tr> + * <tr align="top"> + * <td nowrap valign="top" align="right"><code>op :=  </code></td> + * <td valign="top"><code>'&' | '-'<br> + * </code></td> + * </tr> + * <tr align="top"> + * <td nowrap valign="top" align="right"><code>special :=  </code></td> + * <td valign="top"><code>'[' | ']' | '-'<br> + * </code></td> + * </tr> + * <tr align="top"> + * <td nowrap valign="top" align="right"><code>char :=  </code></td> + * <td valign="top"><em>any character that is not</em><code> special<br> + * | ('\' </code><em>any character</em><code>)<br> + * | ('\\u' hex hex hex hex)<br> + * </code></td> + * </tr> + * <tr align="top"> + * <td nowrap valign="top" align="right"><code>hex :=  </code></td> + * <td valign="top"><em>any character for which + * </em><code>Character.digit(c, 16)</code><em> + * returns a non-negative result</em></td> + * </tr> + * <tr> + * <td nowrap valign="top" align="right"><code>property :=  </code></td> + * <td valign="top"><em>a Unicode property set pattern</em></td> + * </tr> + * </table> + * <br> + * <table border="1"> + * <tr> + * <td>Legend: <table> + * <tr> + * <td nowrap valign="top"><code>a := b</code></td> + * <td width="20" valign="top">  </td> + * <td valign="top"><code>a</code> may be replaced by <code>b</code> </td> + * </tr> + * <tr> + * <td nowrap valign="top"><code>a?</code></td> + * <td valign="top"></td> + * <td valign="top">zero or one instance of <code>a</code><br> + * </td> + * </tr> + * <tr> + * <td nowrap valign="top"><code>a*</code></td> + * <td valign="top"></td> + * <td valign="top">one or more instances of <code>a</code><br> + * </td> + * </tr> + * <tr> + * <td nowrap valign="top"><code>a | b</code></td> + * <td valign="top"></td> + * <td valign="top">either <code>a</code> or <code>b</code><br> + * </td> + * </tr> + * <tr> + * <td nowrap valign="top"><code>'a'</code></td> + * <td valign="top"></td> + * <td valign="top">the literal string between the quotes </td> + * </tr> + * </table> + * </td> + * </tr> + * </table> + * \htmlonly</blockquote>\endhtmlonly + * + * <p>Note: + * - Most UnicodeSet methods do not take a UErrorCode parameter because + * there are usually very few opportunities for failure other than a shortage + * of memory, error codes in low-level C++ string methods would be inconvenient, + * and the error code as the last parameter (ICU convention) would prevent + * the use of default parameter values. + * Instead, such methods set the UnicodeSet into a "bogus" state + * (see isBogus()) if an error occurs. + * + * @author Alan Liu + * @stable ICU 2.0 + */ +class U_COMMON_API UnicodeSet : public UnicodeFilter { + + int32_t len; // length of list used; 0 <= len <= capacity + int32_t capacity; // capacity of list + UChar32* list; // MUST be terminated with HIGH + BMPSet *bmpSet; // The set is frozen iff either bmpSet or stringSpan is not NULL. + UChar32* buffer; // internal buffer, may be NULL + int32_t bufferCapacity; // capacity of buffer + int32_t patLen; + + /** + * The pattern representation of this set. This may not be the + * most economical pattern. It is the pattern supplied to + * applyPattern(), with variables substituted and whitespace + * removed. For sets constructed without applyPattern(), or + * modified using the non-pattern API, this string will be empty, + * indicating that toPattern() must generate a pattern + * representation from the inversion list. + */ + UChar *pat; + UVector* strings; // maintained in sorted order + UnicodeSetStringSpan *stringSpan; + +private: + enum { // constants + kIsBogus = 1 // This set is bogus (i.e. not valid) + }; + uint8_t fFlags; // Bit flag (see constants above) +public: + /** + * Determine if this object contains a valid set. + * A bogus set has no value. It is different from an empty set. + * It can be used to indicate that no set value is available. + * + * @return TRUE if the set is valid, FALSE otherwise + * @see setToBogus() + * @draft ICU 4.0 + */ + inline UBool isBogus(void) const; + + /** + * Make this UnicodeSet object invalid. + * The string will test TRUE with isBogus(). + * + * A bogus set has no value. It is different from an empty set. + * It can be used to indicate that no set value is available. + * + * This utility function is used throughout the UnicodeSet + * implementation to indicate that a UnicodeSet operation failed, + * and may be used in other functions, + * especially but not exclusively when such functions do not + * take a UErrorCode for simplicity. + * + * @see isBogus() + * @draft ICU 4.0 + */ + void setToBogus(); + +public: + + enum { + /** + * Minimum value that can be stored in a UnicodeSet. + * @stable ICU 2.4 + */ + MIN_VALUE = 0, + + /** + * Maximum value that can be stored in a UnicodeSet. + * @stable ICU 2.4 + */ + MAX_VALUE = 0x10ffff + }; + + //---------------------------------------------------------------- + // Constructors &c + //---------------------------------------------------------------- + +public: + + /** + * Constructs an empty set. + * @stable ICU 2.0 + */ + UnicodeSet(); + + /** + * Constructs a set containing the given range. If <code>end > + * start</code> then an empty set is created. + * + * @param start first character, inclusive, of range + * @param end last character, inclusive, of range + * @stable ICU 2.4 + */ + UnicodeSet(UChar32 start, UChar32 end); + + /** + * Constructs a set from the given pattern. See the class + * description for the syntax of the pattern language. + * @param pattern a string specifying what characters are in the set + * @param status returns <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the pattern + * contains a syntax error. + * @stable ICU 2.0 + */ + UnicodeSet(const UnicodeString& pattern, + UErrorCode& status); + + /** + * Constructs a set from the given pattern. See the class + * description for the syntax of the pattern language. + * @param pattern a string specifying what characters are in the set + * @param options bitmask for options to apply to the pattern. + * Valid options are USET_IGNORE_SPACE and USET_CASE_INSENSITIVE. + * @param symbols a symbol table mapping variable names to values + * and stand-in characters to UnicodeSets; may be NULL + * @param status returns <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the pattern + * contains a syntax error. + * @internal + */ + UnicodeSet(const UnicodeString& pattern, + uint32_t options, + const SymbolTable* symbols, + UErrorCode& status); + + /** + * Constructs a set from the given pattern. See the class description + * for the syntax of the pattern language. + * @param pattern a string specifying what characters are in the set + * @param pos on input, the position in pattern at which to start parsing. + * On output, the position after the last character parsed. + * @param options bitmask for options to apply to the pattern. + * Valid options are USET_IGNORE_SPACE and USET_CASE_INSENSITIVE. + * @param symbols a symbol table mapping variable names to values + * and stand-in characters to UnicodeSets; may be NULL + * @param status input-output error code + * @stable ICU 2.8 + */ + UnicodeSet(const UnicodeString& pattern, ParsePosition& pos, + uint32_t options, + const SymbolTable* symbols, + UErrorCode& status); + + /** + * Constructs a set that is identical to the given UnicodeSet. + * @stable ICU 2.0 + */ + UnicodeSet(const UnicodeSet& o); + + /** + * Destructs the set. + * @stable ICU 2.0 + */ + virtual ~UnicodeSet(); + + /** + * Assigns this object to be a copy of another. + * A frozen set will not be modified. + * @stable ICU 2.0 + */ + UnicodeSet& operator=(const UnicodeSet& o); + + /** + * Compares the specified object with this set for equality. Returns + * <tt>true</tt> if the two sets + * have the same size, and every member of the specified set is + * contained in this set (or equivalently, every member of this set is + * contained in the specified set). + * + * @param o set to be compared for equality with this set. + * @return <tt>true</tt> if the specified set is equal to this set. + * @stable ICU 2.0 + */ + virtual UBool operator==(const UnicodeSet& o) const; + + /** + * Compares the specified object with this set for equality. Returns + * <tt>true</tt> if the specified set is not equal to this set. + * @stable ICU 2.0 + */ + UBool operator!=(const UnicodeSet& o) const; + + /** + * Returns a copy of this object. All UnicodeFunctor objects have + * to support cloning in order to allow classes using + * UnicodeFunctors, such as Transliterator, to implement cloning. + * If this set is frozen, then the clone will be frozen as well. + * Use cloneAsThawed() for a mutable clone of a frozen set. + * @see cloneAsThawed + * @stable ICU 2.0 + */ + virtual UnicodeFunctor* clone() const; + + /** + * Returns the hash code value for this set. + * + * @return the hash code value for this set. + * @see Object#hashCode() + * @stable ICU 2.0 + */ + virtual int32_t hashCode(void) const; + + //---------------------------------------------------------------- + // Freezable API + //---------------------------------------------------------------- + + /** + * Determines whether the set has been frozen (made immutable) or not. + * See the ICU4J Freezable interface for details. + * @return TRUE/FALSE for whether the set has been frozen + * @see freeze + * @see cloneAsThawed + * @stable ICU 4.0 + */ + inline UBool isFrozen() const; + + /** + * Freeze the set (make it immutable). + * Once frozen, it cannot be unfrozen and is therefore thread-safe + * until it is deleted. + * See the ICU4J Freezable interface for details. + * Freezing the set may also make some operations faster, for example + * contains() and span(). + * A frozen set will not be modified. (It remains frozen.) + * @return this set. + * @see isFrozen + * @see cloneAsThawed + * @stable ICU 4.0 + */ + UnicodeFunctor *freeze(); + + /** + * Clone the set and make the clone mutable. + * See the ICU4J Freezable interface for details. + * @return the mutable clone + * @see freeze + * @see isFrozen + * @stable ICU 4.0 + */ + UnicodeFunctor *cloneAsThawed() const; + + //---------------------------------------------------------------- + // Public API + //---------------------------------------------------------------- + + /** + * Make this object represent the range <code>start - end</code>. + * If <code>end > start</code> then this object is set to an + * an empty range. + * A frozen set will not be modified. + * + * @param start first character in the set, inclusive + * @param end last character in the set, inclusive + * @stable ICU 2.4 + */ + UnicodeSet& set(UChar32 start, UChar32 end); + + /** + * Return true if the given position, in the given pattern, appears + * to be the start of a UnicodeSet pattern. + * @stable ICU 2.4 + */ + static UBool resemblesPattern(const UnicodeString& pattern, + int32_t pos); + + /** + * Modifies this set to represent the set specified by the given + * pattern, optionally ignoring white space. See the class + * description for the syntax of the pattern language. + * A frozen set will not be modified. + * @param pattern a string specifying what characters are in the set + * @param status returns <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the pattern + * contains a syntax error. + * <em> Empties the set passed before applying the pattern.</em> + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeSet& applyPattern(const UnicodeString& pattern, + UErrorCode& status); + + /** + * Modifies this set to represent the set specified by the given + * pattern, optionally ignoring white space. See the class + * description for the syntax of the pattern language. + * A frozen set will not be modified. + * @param pattern a string specifying what characters are in the set + * @param options bitmask for options to apply to the pattern. + * Valid options are USET_IGNORE_SPACE and USET_CASE_INSENSITIVE. + * @param symbols a symbol table mapping variable names to + * values and stand-ins to UnicodeSets; may be NULL + * @param status returns <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the pattern + * contains a syntax error. + *<em> Empties the set passed before applying the pattern.</em> + * @return a reference to this + * @internal + */ + UnicodeSet& applyPattern(const UnicodeString& pattern, + uint32_t options, + const SymbolTable* symbols, + UErrorCode& status); + + /** + * Parses the given pattern, starting at the given position. The + * character at pattern.charAt(pos.getIndex()) must be '[', or the + * parse fails. Parsing continues until the corresponding closing + * ']'. If a syntax error is encountered between the opening and + * closing brace, the parse fails. Upon return from a successful + * parse, the ParsePosition is updated to point to the character + * following the closing ']', and a StringBuffer containing a + * pairs list for the parsed pattern is returned. This method calls + * itself recursively to parse embedded subpatterns. + *<em> Empties the set passed before applying the pattern.</em> + * A frozen set will not be modified. + * + * @param pattern the string containing the pattern to be parsed. + * The portion of the string from pos.getIndex(), which must be a + * '[', to the corresponding closing ']', is parsed. + * @param pos upon entry, the position at which to being parsing. + * The character at pattern.charAt(pos.getIndex()) must be a '['. + * Upon return from a successful parse, pos.getIndex() is either + * the character after the closing ']' of the parsed pattern, or + * pattern.length() if the closing ']' is the last character of + * the pattern string. + * @param options bitmask for options to apply to the pattern. + * Valid options are USET_IGNORE_SPACE and USET_CASE_INSENSITIVE. + * @param symbols a symbol table mapping variable names to + * values and stand-ins to UnicodeSets; may be NULL + * @param status returns <code>U_ILLEGAL_ARGUMENT_ERROR</code> if the pattern + * contains a syntax error. + * @return a reference to this + * @stable ICU 2.8 + */ + UnicodeSet& applyPattern(const UnicodeString& pattern, + ParsePosition& pos, + uint32_t options, + const SymbolTable* symbols, + UErrorCode& status); + + /** + * Returns a string representation of this set. If the result of + * calling this function is passed to a UnicodeSet constructor, it + * will produce another set that is equal to this one. + * A frozen set will not be modified. + * @param result the string to receive the rules. Previous + * contents will be deleted. + * @param escapeUnprintable if TRUE then convert unprintable + * character to their hex escape representations, \\uxxxx or + * \\Uxxxxxxxx. Unprintable characters are those other than + * U+000A, U+0020..U+007E. + * @stable ICU 2.0 + */ + virtual UnicodeString& toPattern(UnicodeString& result, + UBool escapeUnprintable = FALSE) const; + + /** + * Modifies this set to contain those code points which have the given value + * for the given binary or enumerated property, as returned by + * u_getIntPropertyValue. Prior contents of this set are lost. + * A frozen set will not be modified. + * + * @param prop a property in the range UCHAR_BIN_START..UCHAR_BIN_LIMIT-1 + * or UCHAR_INT_START..UCHAR_INT_LIMIT-1 + * or UCHAR_MASK_START..UCHAR_MASK_LIMIT-1. + * + * @param value a value in the range u_getIntPropertyMinValue(prop).. + * u_getIntPropertyMaxValue(prop), with one exception. If prop is + * UCHAR_GENERAL_CATEGORY_MASK, then value should not be a UCharCategory, but + * rather a mask value produced by U_GET_GC_MASK(). This allows grouped + * categories such as [:L:] to be represented. + * + * @param ec error code input/output parameter + * + * @return a reference to this set + * + * @stable ICU 2.4 + */ + UnicodeSet& applyIntPropertyValue(UProperty prop, + int32_t value, + UErrorCode& ec); + + /** + * Modifies this set to contain those code points which have the + * given value for the given property. Prior contents of this + * set are lost. + * A frozen set will not be modified. + * + * @param prop a property alias, either short or long. The name is matched + * loosely. See PropertyAliases.txt for names and a description of loose + * matching. If the value string is empty, then this string is interpreted + * as either a General_Category value alias, a Script value alias, a binary + * property alias, or a special ID. Special IDs are matched loosely and + * correspond to the following sets: + * + * "ANY" = [\\u0000-\\U0010FFFF], + * "ASCII" = [\\u0000-\\u007F], + * "Assigned" = [:^Cn:]. + * + * @param value a value alias, either short or long. The name is matched + * loosely. See PropertyValueAliases.txt for names and a description of + * loose matching. In addition to aliases listed, numeric values and + * canonical combining classes may be expressed numerically, e.g., ("nv", + * "0.5") or ("ccc", "220"). The value string may also be empty. + * + * @param ec error code input/output parameter + * + * @return a reference to this set + * + * @stable ICU 2.4 + */ + UnicodeSet& applyPropertyAlias(const UnicodeString& prop, + const UnicodeString& value, + UErrorCode& ec); + + /** + * Returns the number of elements in this set (its cardinality). + * Note than the elements of a set may include both individual + * codepoints and strings. + * + * @return the number of elements in this set (its cardinality). + * @stable ICU 2.0 + */ + virtual int32_t size(void) const; + + /** + * Returns <tt>true</tt> if this set contains no elements. + * + * @return <tt>true</tt> if this set contains no elements. + * @stable ICU 2.0 + */ + virtual UBool isEmpty(void) const; + + /** + * Returns true if this set contains the given character. + * This function works faster with a frozen set. + * @param c character to be checked for containment + * @return true if the test condition is met + * @stable ICU 2.0 + */ + virtual UBool contains(UChar32 c) const; + + /** + * Returns true if this set contains every character + * of the given range. + * @param start first character, inclusive, of the range + * @param end last character, inclusive, of the range + * @return true if the test condition is met + * @stable ICU 2.0 + */ + virtual UBool contains(UChar32 start, UChar32 end) const; + + /** + * Returns <tt>true</tt> if this set contains the given + * multicharacter string. + * @param s string to be checked for containment + * @return <tt>true</tt> if this set contains the specified string + * @stable ICU 2.4 + */ + UBool contains(const UnicodeString& s) const; + + /** + * Returns true if this set contains all the characters and strings + * of the given set. + * @param c set to be checked for containment + * @return true if the test condition is met + * @stable ICU 2.4 + */ + virtual UBool containsAll(const UnicodeSet& c) const; + + /** + * Returns true if this set contains all the characters + * of the given string. + * @param s string containing characters to be checked for containment + * @return true if the test condition is met + * @stable ICU 2.4 + */ + UBool containsAll(const UnicodeString& s) const; + + /** + * Returns true if this set contains none of the characters + * of the given range. + * @param start first character, inclusive, of the range + * @param end last character, inclusive, of the range + * @return true if the test condition is met + * @stable ICU 2.4 + */ + UBool containsNone(UChar32 start, UChar32 end) const; + + /** + * Returns true if this set contains none of the characters and strings + * of the given set. + * @param c set to be checked for containment + * @return true if the test condition is met + * @stable ICU 2.4 + */ + UBool containsNone(const UnicodeSet& c) const; + + /** + * Returns true if this set contains none of the characters + * of the given string. + * @param s string containing characters to be checked for containment + * @return true if the test condition is met + * @stable ICU 2.4 + */ + UBool containsNone(const UnicodeString& s) const; + + /** + * Returns true if this set contains one or more of the characters + * in the given range. + * @param start first character, inclusive, of the range + * @param end last character, inclusive, of the range + * @return true if the condition is met + * @stable ICU 2.4 + */ + inline UBool containsSome(UChar32 start, UChar32 end) const; + + /** + * Returns true if this set contains one or more of the characters + * and strings of the given set. + * @param s The set to be checked for containment + * @return true if the condition is met + * @stable ICU 2.4 + */ + inline UBool containsSome(const UnicodeSet& s) const; + + /** + * Returns true if this set contains one or more of the characters + * of the given string. + * @param s string containing characters to be checked for containment + * @return true if the condition is met + * @stable ICU 2.4 + */ + inline UBool containsSome(const UnicodeString& s) const; + + /** + * Returns the length of the initial substring of the input string which + * consists only of characters and strings that are contained in this set + * (USET_SPAN_CONTAINED, USET_SPAN_SIMPLE), + * or only of characters and strings that are not contained + * in this set (USET_SPAN_NOT_CONTAINED). + * See USetSpanCondition for details. + * Similar to the strspn() C library function. + * Unpaired surrogates are treated according to contains() of their surrogate code points. + * This function works faster with a frozen set and with a non-negative string length argument. + * @param s start of the string + * @param length of the string; can be -1 for NUL-terminated + * @param spanCondition specifies the containment condition + * @return the length of the initial substring according to the spanCondition; + * 0 if the start of the string does not fit the spanCondition + * @stable ICU 4.0 + * @see USetSpanCondition + */ + int32_t span(const UChar *s, int32_t length, USetSpanCondition spanCondition) const; + + /** + * Returns the start of the trailing substring of the input string which + * consists only of characters and strings that are contained in this set + * (USET_SPAN_CONTAINED, USET_SPAN_SIMPLE), + * or only of characters and strings that are not contained + * in this set (USET_SPAN_NOT_CONTAINED). + * See USetSpanCondition for details. + * Unpaired surrogates are treated according to contains() of their surrogate code points. + * This function works faster with a frozen set and with a non-negative string length argument. + * @param s start of the string + * @param length of the string; can be -1 for NUL-terminated + * @param spanCondition specifies the containment condition + * @return the start of the trailing substring according to the spanCondition; + * the string length if the end of the string does not fit the spanCondition + * @stable ICU 4.0 + * @see USetSpanCondition + */ + int32_t spanBack(const UChar *s, int32_t length, USetSpanCondition spanCondition) const; + + /** + * Returns the length of the initial substring of the input string which + * consists only of characters and strings that are contained in this set + * (USET_SPAN_CONTAINED, USET_SPAN_SIMPLE), + * or only of characters and strings that are not contained + * in this set (USET_SPAN_NOT_CONTAINED). + * See USetSpanCondition for details. + * Similar to the strspn() C library function. + * Malformed byte sequences are treated according to contains(0xfffd). + * This function works faster with a frozen set and with a non-negative string length argument. + * @param s start of the string (UTF-8) + * @param length of the string; can be -1 for NUL-terminated + * @param spanCondition specifies the containment condition + * @return the length of the initial substring according to the spanCondition; + * 0 if the start of the string does not fit the spanCondition + * @stable ICU 4.0 + * @see USetSpanCondition + */ + int32_t spanUTF8(const char *s, int32_t length, USetSpanCondition spanCondition) const; + + /** + * Returns the start of the trailing substring of the input string which + * consists only of characters and strings that are contained in this set + * (USET_SPAN_CONTAINED, USET_SPAN_SIMPLE), + * or only of characters and strings that are not contained + * in this set (USET_SPAN_NOT_CONTAINED). + * See USetSpanCondition for details. + * Malformed byte sequences are treated according to contains(0xfffd). + * This function works faster with a frozen set and with a non-negative string length argument. + * @param s start of the string (UTF-8) + * @param length of the string; can be -1 for NUL-terminated + * @param spanCondition specifies the containment condition + * @return the start of the trailing substring according to the spanCondition; + * the string length if the end of the string does not fit the spanCondition + * @stable ICU 4.0 + * @see USetSpanCondition + */ + int32_t spanBackUTF8(const char *s, int32_t length, USetSpanCondition spanCondition) const; + + /** + * Implement UnicodeMatcher::matches() + * @stable ICU 2.4 + */ + virtual UMatchDegree matches(const Replaceable& text, + int32_t& offset, + int32_t limit, + UBool incremental); + +private: + /** + * Returns the longest match for s in text at the given position. + * If limit > start then match forward from start+1 to limit + * matching all characters except s.charAt(0). If limit < start, + * go backward starting from start-1 matching all characters + * except s.charAt(s.length()-1). This method assumes that the + * first character, text.charAt(start), matches s, so it does not + * check it. + * @param text the text to match + * @param start the first character to match. In the forward + * direction, text.charAt(start) is matched against s.charAt(0). + * In the reverse direction, it is matched against + * s.charAt(s.length()-1). + * @param limit the limit offset for matching, either last+1 in + * the forward direction, or last-1 in the reverse direction, + * where last is the index of the last character to match. + * @return If part of s matches up to the limit, return |limit - + * start|. If all of s matches before reaching the limit, return + * s.length(). If there is a mismatch between s and text, return + * 0 + */ + static int32_t matchRest(const Replaceable& text, + int32_t start, int32_t limit, + const UnicodeString& s); + + /** + * Returns the smallest value i such that c < list[i]. Caller + * must ensure that c is a legal value or this method will enter + * an infinite loop. This method performs a binary search. + * @param c a character in the range MIN_VALUE..MAX_VALUE + * inclusive + * @return the smallest integer i in the range 0..len-1, + * inclusive, such that c < list[i] + */ + int32_t findCodePoint(UChar32 c) const; + +public: + + /** + * Implementation of UnicodeMatcher API. Union the set of all + * characters that may be matched by this object into the given + * set. + * @param toUnionTo the set into which to union the source characters + * @stable ICU 2.4 + */ + virtual void addMatchSetTo(UnicodeSet& toUnionTo) const; + + /** + * Returns the index of the given character within this set, where + * the set is ordered by ascending code point. If the character + * is not in this set, return -1. The inverse of this method is + * <code>charAt()</code>. + * @return an index from 0..size()-1, or -1 + * @stable ICU 2.4 + */ + int32_t indexOf(UChar32 c) const; + + /** + * Returns the character at the given index within this set, where + * the set is ordered by ascending code point. If the index is + * out of range, return (UChar32)-1. The inverse of this method is + * <code>indexOf()</code>. + * @param index an index from 0..size()-1 + * @return the character at the given index, or (UChar32)-1. + * @stable ICU 2.4 + */ + UChar32 charAt(int32_t index) const; + + /** + * Adds the specified range to this set if it is not already + * present. If this set already contains the specified range, + * the call leaves this set unchanged. If <code>end > start</code> + * then an empty range is added, leaving the set unchanged. + * This is equivalent to a boolean logic OR, or a set UNION. + * A frozen set will not be modified. + * + * @param start first character, inclusive, of range to be added + * to this set. + * @param end last character, inclusive, of range to be added + * to this set. + * @stable ICU 2.0 + */ + virtual UnicodeSet& add(UChar32 start, UChar32 end); + + /** + * Adds the specified character to this set if it is not already + * present. If this set already contains the specified character, + * the call leaves this set unchanged. + * A frozen set will not be modified. + * @stable ICU 2.0 + */ + UnicodeSet& add(UChar32 c); + + /** + * Adds the specified multicharacter to this set if it is not already + * present. If this set already contains the multicharacter, + * the call leaves this set unchanged. + * Thus "ch" => {"ch"} + * <br><b>Warning: you cannot add an empty string ("") to a UnicodeSet.</b> + * A frozen set will not be modified. + * @param s the source string + * @return this object, for chaining + * @stable ICU 2.4 + */ + UnicodeSet& add(const UnicodeString& s); + + private: + /** + * @return a code point IF the string consists of a single one. + * otherwise returns -1. + * @param string to test + */ + static int32_t getSingleCP(const UnicodeString& s); + + void _add(const UnicodeString& s); + + public: + /** + * Adds each of the characters in this string to the set. Thus "ch" => {"c", "h"} + * If this set already any particular character, it has no effect on that character. + * A frozen set will not be modified. + * @param s the source string + * @return this object, for chaining + * @stable ICU 2.4 + */ + UnicodeSet& addAll(const UnicodeString& s); + + /** + * Retains EACH of the characters in this string. Note: "ch" == {"c", "h"} + * If this set already any particular character, it has no effect on that character. + * A frozen set will not be modified. + * @param s the source string + * @return this object, for chaining + * @stable ICU 2.4 + */ + UnicodeSet& retainAll(const UnicodeString& s); + + /** + * Complement EACH of the characters in this string. Note: "ch" == {"c", "h"} + * If this set already any particular character, it has no effect on that character. + * A frozen set will not be modified. + * @param s the source string + * @return this object, for chaining + * @stable ICU 2.4 + */ + UnicodeSet& complementAll(const UnicodeString& s); + + /** + * Remove EACH of the characters in this string. Note: "ch" == {"c", "h"} + * If this set already any particular character, it has no effect on that character. + * A frozen set will not be modified. + * @param s the source string + * @return this object, for chaining + * @stable ICU 2.4 + */ + UnicodeSet& removeAll(const UnicodeString& s); + + /** + * Makes a set from a multicharacter string. Thus "ch" => {"ch"} + * <br><b>Warning: you cannot add an empty string ("") to a UnicodeSet.</b> + * @param s the source string + * @return a newly created set containing the given string. + * The caller owns the return object and is responsible for deleting it. + * @stable ICU 2.4 + */ + static UnicodeSet* U_EXPORT2 createFrom(const UnicodeString& s); + + + /** + * Makes a set from each of the characters in the string. Thus "ch" => {"c", "h"} + * @param s the source string + * @return a newly created set containing the given characters + * The caller owns the return object and is responsible for deleting it. + * @stable ICU 2.4 + */ + static UnicodeSet* U_EXPORT2 createFromAll(const UnicodeString& s); + + /** + * Retain only the elements in this set that are contained in the + * specified range. If <code>end > start</code> then an empty range is + * retained, leaving the set empty. This is equivalent to + * a boolean logic AND, or a set INTERSECTION. + * A frozen set will not be modified. + * + * @param start first character, inclusive, of range to be retained + * to this set. + * @param end last character, inclusive, of range to be retained + * to this set. + * @stable ICU 2.0 + */ + virtual UnicodeSet& retain(UChar32 start, UChar32 end); + + + /** + * Retain the specified character from this set if it is present. + * A frozen set will not be modified. + * @stable ICU 2.0 + */ + UnicodeSet& retain(UChar32 c); + + /** + * Removes the specified range from this set if it is present. + * The set will not contain the specified range once the call + * returns. If <code>end > start</code> then an empty range is + * removed, leaving the set unchanged. + * A frozen set will not be modified. + * + * @param start first character, inclusive, of range to be removed + * from this set. + * @param end last character, inclusive, of range to be removed + * from this set. + * @stable ICU 2.0 + */ + virtual UnicodeSet& remove(UChar32 start, UChar32 end); + + /** + * Removes the specified character from this set if it is present. + * The set will not contain the specified range once the call + * returns. + * A frozen set will not be modified. + * @stable ICU 2.0 + */ + UnicodeSet& remove(UChar32 c); + + /** + * Removes the specified string from this set if it is present. + * The set will not contain the specified character once the call + * returns. + * A frozen set will not be modified. + * @param s the source string + * @return this object, for chaining + * @stable ICU 2.4 + */ + UnicodeSet& remove(const UnicodeString& s); + + /** + * Inverts this set. This operation modifies this set so that + * its value is its complement. This is equivalent to + * <code>complement(MIN_VALUE, MAX_VALUE)</code>. + * A frozen set will not be modified. + * @stable ICU 2.0 + */ + virtual UnicodeSet& complement(void); + + /** + * Complements the specified range in this set. Any character in + * the range will be removed if it is in this set, or will be + * added if it is not in this set. If <code>end > start</code> + * then an empty range is complemented, leaving the set unchanged. + * This is equivalent to a boolean logic XOR. + * A frozen set will not be modified. + * + * @param start first character, inclusive, of range to be removed + * from this set. + * @param end last character, inclusive, of range to be removed + * from this set. + * @stable ICU 2.0 + */ + virtual UnicodeSet& complement(UChar32 start, UChar32 end); + + /** + * Complements the specified character in this set. The character + * will be removed if it is in this set, or will be added if it is + * not in this set. + * A frozen set will not be modified. + * @stable ICU 2.0 + */ + UnicodeSet& complement(UChar32 c); + + /** + * Complement the specified string in this set. + * The set will not contain the specified string once the call + * returns. + * <br><b>Warning: you cannot add an empty string ("") to a UnicodeSet.</b> + * A frozen set will not be modified. + * @param s the string to complement + * @return this object, for chaining + * @stable ICU 2.4 + */ + UnicodeSet& complement(const UnicodeString& s); + + /** + * Adds all of the elements in the specified set to this set if + * they're not already present. This operation effectively + * modifies this set so that its value is the <i>union</i> of the two + * sets. The behavior of this operation is unspecified if the specified + * collection is modified while the operation is in progress. + * A frozen set will not be modified. + * + * @param c set whose elements are to be added to this set. + * @see #add(UChar32, UChar32) + * @stable ICU 2.0 + */ + virtual UnicodeSet& addAll(const UnicodeSet& c); + + /** + * Retains only the elements in this set that are contained in the + * specified set. In other words, removes from this set all of + * its elements that are not contained in the specified set. This + * operation effectively modifies this set so that its value is + * the <i>intersection</i> of the two sets. + * A frozen set will not be modified. + * + * @param c set that defines which elements this set will retain. + * @stable ICU 2.0 + */ + virtual UnicodeSet& retainAll(const UnicodeSet& c); + + /** + * Removes from this set all of its elements that are contained in the + * specified set. This operation effectively modifies this + * set so that its value is the <i>asymmetric set difference</i> of + * the two sets. + * A frozen set will not be modified. + * + * @param c set that defines which elements will be removed from + * this set. + * @stable ICU 2.0 + */ + virtual UnicodeSet& removeAll(const UnicodeSet& c); + + /** + * Complements in this set all elements contained in the specified + * set. Any character in the other set will be removed if it is + * in this set, or will be added if it is not in this set. + * A frozen set will not be modified. + * + * @param c set that defines which elements will be xor'ed from + * this set. + * @stable ICU 2.4 + */ + virtual UnicodeSet& complementAll(const UnicodeSet& c); + + /** + * Removes all of the elements from this set. This set will be + * empty after this call returns. + * A frozen set will not be modified. + * @stable ICU 2.0 + */ + virtual UnicodeSet& clear(void); + + /** + * Close this set over the given attribute. For the attribute + * USET_CASE, the result is to modify this set so that: + * + * 1. For each character or string 'a' in this set, all strings or + * characters 'b' such that foldCase(a) == foldCase(b) are added + * to this set. + * + * 2. For each string 'e' in the resulting set, if e != + * foldCase(e), 'e' will be removed. + * + * Example: [aq\\u00DF{Bc}{bC}{Fi}] => [aAqQ\\u00DF\\uFB01{ss}{bc}{fi}] + * + * (Here foldCase(x) refers to the operation u_strFoldCase, and a + * == b denotes that the contents are the same, not pointer + * comparison.) + * + * A frozen set will not be modified. + * + * @param attribute bitmask for attributes to close over. + * Currently only the USET_CASE bit is supported. Any undefined bits + * are ignored. + * @return a reference to this set. + * @internal + */ + UnicodeSet& closeOver(int32_t attribute); + + /** + * Remove all strings from this set. + * + * @return a reference to this set. + * @internal + */ + virtual UnicodeSet &removeAllStrings(); + + /** + * Iteration method that returns the number of ranges contained in + * this set. + * @see #getRangeStart + * @see #getRangeEnd + * @stable ICU 2.4 + */ + virtual int32_t getRangeCount(void) const; + + /** + * Iteration method that returns the first character in the + * specified range of this set. + * @see #getRangeCount + * @see #getRangeEnd + * @stable ICU 2.4 + */ + virtual UChar32 getRangeStart(int32_t index) const; + + /** + * Iteration method that returns the last character in the + * specified range of this set. + * @see #getRangeStart + * @see #getRangeEnd + * @stable ICU 2.4 + */ + virtual UChar32 getRangeEnd(int32_t index) const; + + /** + * Serializes this set into an array of 16-bit integers. Serialization + * (currently) only records the characters in the set; multicharacter + * strings are ignored. + * + * The array has following format (each line is one 16-bit + * integer): + * + * length = (n+2*m) | (m!=0?0x8000:0) + * bmpLength = n; present if m!=0 + * bmp[0] + * bmp[1] + * ... + * bmp[n-1] + * supp-high[0] + * supp-low[0] + * supp-high[1] + * supp-low[1] + * ... + * supp-high[m-1] + * supp-low[m-1] + * + * The array starts with a header. After the header are n bmp + * code points, then m supplementary code points. Either n or m + * or both may be zero. n+2*m is always <= 0x7FFF. + * + * If there are no supplementary characters (if m==0) then the + * header is one 16-bit integer, 'length', with value n. + * + * If there are supplementary characters (if m!=0) then the header + * is two 16-bit integers. The first, 'length', has value + * (n+2*m)|0x8000. The second, 'bmpLength', has value n. + * + * After the header the code points are stored in ascending order. + * Supplementary code points are stored as most significant 16 + * bits followed by least significant 16 bits. + * + * @param dest pointer to buffer of destCapacity 16-bit integers. + * May be NULL only if destCapacity is zero. + * @param destCapacity size of dest, or zero. Must not be negative. + * @param ec error code. Will be set to U_INDEX_OUTOFBOUNDS_ERROR + * if n+2*m > 0x7FFF. Will be set to U_BUFFER_OVERFLOW_ERROR if + * n+2*m+(m!=0?2:1) > destCapacity. + * @return the total length of the serialized format, including + * the header, that is, n+2*m+(m!=0?2:1), or 0 on error other + * than U_BUFFER_OVERFLOW_ERROR. + * @stable ICU 2.4 + */ + int32_t serialize(uint16_t *dest, int32_t destCapacity, UErrorCode& ec) const; + + /** + * Reallocate this objects internal structures to take up the least + * possible space, without changing this object's value. + * A frozen set will not be modified. + * @stable ICU 2.4 + */ + virtual UnicodeSet& compact(); + + /** + * Return the class ID for this class. This is useful only for + * comparing to a return value from getDynamicClassID(). For example: + * <pre> + * . Base* polymorphic_pointer = createPolymorphicObject(); + * . if (polymorphic_pointer->getDynamicClassID() == + * . Derived::getStaticClassID()) ... + * </pre> + * @return The class ID for all objects of this class. + * @stable ICU 2.0 + */ + static UClassID U_EXPORT2 getStaticClassID(void); + + /** + * Implement UnicodeFunctor API. + * + * @return The class ID for this object. All objects of a given + * class have the same class ID. Objects of other classes have + * different class IDs. + * @stable ICU 2.4 + */ + virtual UClassID getDynamicClassID(void) const; + +private: + + // Private API for the USet API + + friend class USetAccess; + + int32_t getStringCount() const; + + const UnicodeString* getString(int32_t index) const; + + //---------------------------------------------------------------- + // RuleBasedTransliterator support + //---------------------------------------------------------------- + +private: + + /** + * Returns <tt>true</tt> if this set contains any character whose low byte + * is the given value. This is used by <tt>RuleBasedTransliterator</tt> for + * indexing. + */ + virtual UBool matchesIndexValue(uint8_t v) const; + +private: + + //---------------------------------------------------------------- + // Implementation: Clone as thawed (see ICU4J Freezable) + //---------------------------------------------------------------- + + UnicodeSet(const UnicodeSet& o, UBool /* asThawed */); + + //---------------------------------------------------------------- + // Implementation: Pattern parsing + //---------------------------------------------------------------- + + void applyPattern(RuleCharacterIterator& chars, + const SymbolTable* symbols, + UnicodeString& rebuiltPat, + uint32_t options, + UErrorCode& ec); + + //---------------------------------------------------------------- + // Implementation: Utility methods + //---------------------------------------------------------------- + + void ensureCapacity(int32_t newLen, UErrorCode& ec); + + void ensureBufferCapacity(int32_t newLen, UErrorCode& ec); + + void swapBuffers(void); + + UBool allocateStrings(UErrorCode &status); + + UnicodeString& _toPattern(UnicodeString& result, + UBool escapeUnprintable) const; + + UnicodeString& _generatePattern(UnicodeString& result, + UBool escapeUnprintable) const; + + static void _appendToPat(UnicodeString& buf, const UnicodeString& s, UBool escapeUnprintable); + + static void _appendToPat(UnicodeString& buf, UChar32 c, UBool escapeUnprintable); + + //---------------------------------------------------------------- + // Implementation: Fundamental operators + //---------------------------------------------------------------- + + void exclusiveOr(const UChar32* other, int32_t otherLen, int8_t polarity); + + void add(const UChar32* other, int32_t otherLen, int8_t polarity); + + void retain(const UChar32* other, int32_t otherLen, int8_t polarity); + + /** + * Return true if the given position, in the given pattern, appears + * to be the start of a property set pattern [:foo:], \\p{foo}, or + * \\P{foo}, or \\N{name}. + */ + static UBool resemblesPropertyPattern(const UnicodeString& pattern, + int32_t pos); + + static UBool resemblesPropertyPattern(RuleCharacterIterator& chars, + int32_t iterOpts); + + /** + * Parse the given property pattern at the given parse position + * and set this UnicodeSet to the result. + * + * The original design document is out of date, but still useful. + * Ignore the property and value names: + * http://source.icu-project.org/repos/icu/icuhtml/trunk/design/unicodeset_properties.html + * + * Recognized syntax: + * + * [:foo:] [:^foo:] - white space not allowed within "[:" or ":]" + * \\p{foo} \\P{foo} - white space not allowed within "\\p" or "\\P" + * \\N{name} - white space not allowed within "\\N" + * + * Other than the above restrictions, white space is ignored. Case + * is ignored except in "\\p" and "\\P" and "\\N". In 'name' leading + * and trailing space is deleted, and internal runs of whitespace + * are collapsed to a single space. + * + * We support binary properties, enumerated properties, and the + * following non-enumerated properties: + * + * Numeric_Value + * Name + * Unicode_1_Name + * + * @param pattern the pattern string + * @param ppos on entry, the position at which to begin parsing. + * This should be one of the locations marked '^': + * + * [:blah:] \\p{blah} \\P{blah} \\N{name} + * ^ % ^ % ^ % ^ % + * + * On return, the position after the last character parsed, that is, + * the locations marked '%'. If the parse fails, ppos is returned + * unchanged. + * @return a reference to this. + */ + UnicodeSet& applyPropertyPattern(const UnicodeString& pattern, + ParsePosition& ppos, + UErrorCode &ec); + + void applyPropertyPattern(RuleCharacterIterator& chars, + UnicodeString& rebuiltPat, + UErrorCode& ec); + + static const UnicodeSet* getInclusions(int32_t src, UErrorCode &status); + + /** + * A filter that returns TRUE if the given code point should be + * included in the UnicodeSet being constructed. + */ + typedef UBool (*Filter)(UChar32 codePoint, void* context); + + /** + * Given a filter, set this UnicodeSet to the code points + * contained by that filter. The filter MUST be + * property-conformant. That is, if it returns value v for one + * code point, then it must return v for all affiliated code + * points, as defined by the inclusions list. See + * getInclusions(). + * src is a UPropertySource value. + */ + void applyFilter(Filter filter, + void* context, + int32_t src, + UErrorCode &status); + + /** + * Set the new pattern to cache. + */ + void setPattern(const UnicodeString& newPat); + /** + * Release existing cached pattern. + */ + void releasePattern(); + + friend class UnicodeSetIterator; +}; + +inline UBool UnicodeSet::operator!=(const UnicodeSet& o) const { + return !operator==(o); +} + +inline UBool UnicodeSet::isFrozen() const { + return (UBool)(bmpSet!=NULL || stringSpan!=NULL); +} + +inline UBool UnicodeSet::containsSome(UChar32 start, UChar32 end) const { + return !containsNone(start, end); +} + +inline UBool UnicodeSet::containsSome(const UnicodeSet& s) const { + return !containsNone(s); +} + +inline UBool UnicodeSet::containsSome(const UnicodeString& s) const { + return !containsNone(s); +} + +inline UBool UnicodeSet::isBogus() const { + return (UBool)(fFlags & kIsBogus); +} + +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/unistr.h b/utils/openttd/unicode/unistr.h new file mode 100644 index 00000000000..9a96bdc2766 --- /dev/null +++ b/utils/openttd/unicode/unistr.h @@ -0,0 +1,4230 @@ +/* +********************************************************************** +* Copyright (C) 1998-2008, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* +* File unistr.h +* +* Modification History: +* +* Date Name Description +* 09/25/98 stephen Creation. +* 11/11/98 stephen Changed per 11/9 code review. +* 04/20/99 stephen Overhauled per 4/16 code review. +* 11/18/99 aliu Made to inherit from Replaceable. Added method +* handleReplaceBetween(); other methods unchanged. +* 06/25/01 grhoten Remove dependency on iostream. +****************************************************************************** +*/ + +#ifndef UNISTR_H +#define UNISTR_H + +/** + * \file + * \brief C++ API: Unicode String + */ + +#include "unicode/rep.h" + +struct UConverter; // unicode/ucnv.h +class StringThreadTest; + +#ifndef U_COMPARE_CODE_POINT_ORDER +/* see also ustring.h and unorm.h */ +/** + * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc: + * Compare strings in code point order instead of code unit order. + * @stable ICU 2.2 + */ +#define U_COMPARE_CODE_POINT_ORDER 0x8000 +#endif + +#ifndef USTRING_H +/** + * \ingroup ustring_ustrlen + */ +U_STABLE int32_t U_EXPORT2 +u_strlen(const UChar *s); +#endif + +U_NAMESPACE_BEGIN + +class Locale; // unicode/locid.h +class StringCharacterIterator; +class BreakIterator; // unicode/brkiter.h + +/* The <iostream> include has been moved to unicode/ustream.h */ + +/** + * Constant to be used in the UnicodeString(char *, int32_t, EInvariant) constructor + * which constructs a Unicode string from an invariant-character char * string. + * About invariant characters see utypes.h. + * This constructor has no runtime dependency on conversion code and is + * therefore recommended over ones taking a charset name string + * (where the empty string "" indicates invariant-character conversion). + * + * @stable ICU 3.2 + */ +#define US_INV U_NAMESPACE_QUALIFIER UnicodeString::kInvariant + +/** + * Unicode String literals in C++. + * Dependent on the platform properties, different UnicodeString + * constructors should be used to create a UnicodeString object from + * a string literal. + * The macros are defined for maximum performance. + * They work only for strings that contain "invariant characters", i.e., + * only latin letters, digits, and some punctuation. + * See utypes.h for details. + * + * The string parameter must be a C string literal. + * The length of the string, not including the terminating + * <code>NUL</code>, must be specified as a constant. + * The U_STRING_DECL macro should be invoked exactly once for one + * such string variable before it is used. + * @stable ICU 2.0 + */ +#if defined(U_DECLARE_UTF16) +# define UNICODE_STRING(cs, _length) U_NAMESPACE_QUALIFIER UnicodeString(TRUE, (const UChar *)U_DECLARE_UTF16(cs), _length) +#elif U_SIZEOF_WCHAR_T==U_SIZEOF_UCHAR && (U_CHARSET_FAMILY==U_ASCII_FAMILY || (U_SIZEOF_UCHAR == 2 && defined(U_WCHAR_IS_UTF16))) +# define UNICODE_STRING(cs, _length) U_NAMESPACE_QUALIFIER UnicodeString(TRUE, (const UChar *)L ## cs, _length) +#elif U_SIZEOF_UCHAR==1 && U_CHARSET_FAMILY==U_ASCII_FAMILY +# define UNICODE_STRING(cs, _length) U_NAMESPACE_QUALIFIER UnicodeString(TRUE, (const UChar *)cs, _length) +#else +# define UNICODE_STRING(cs, _length) U_NAMESPACE_QUALIFIER UnicodeString(cs, _length, US_INV) +#endif + +/** + * Unicode String literals in C++. + * Dependent on the platform properties, different UnicodeString + * constructors should be used to create a UnicodeString object from + * a string literal. + * The macros are defined for improved performance. + * They work only for strings that contain "invariant characters", i.e., + * only latin letters, digits, and some punctuation. + * See utypes.h for details. + * + * The string parameter must be a C string literal. + * @stable ICU 2.0 + */ +#define UNICODE_STRING_SIMPLE(cs) UNICODE_STRING(cs, -1) + +/** + * UnicodeString is a string class that stores Unicode characters directly and provides + * similar functionality as the Java String and StringBuffer classes. + * It is a concrete implementation of the abstract class Replaceable (for transliteration). + * + * The UnicodeString class is not suitable for subclassing. + * + * <p>For an overview of Unicode strings in C and C++ see the + * <a href="http://icu-project.org/userguide/strings.html">User Guide Strings chapter</a>.</p> + * + * <p>In ICU, a Unicode string consists of 16-bit Unicode <em>code units</em>. + * A Unicode character may be stored with either one code unit + * (the most common case) or with a matched pair of special code units + * ("surrogates"). The data type for code units is UChar. + * For single-character handling, a Unicode character code <em>point</em> is a value + * in the range 0..0x10ffff. ICU uses the UChar32 type for code points.</p> + * + * <p>Indexes and offsets into and lengths of strings always count code units, not code points. + * This is the same as with multi-byte char* strings in traditional string handling. + * Operations on partial strings typically do not test for code point boundaries. + * If necessary, the user needs to take care of such boundaries by testing for the code unit + * values or by using functions like + * UnicodeString::getChar32Start() and UnicodeString::getChar32Limit() + * (or, in C, the equivalent macros U16_SET_CP_START() and U16_SET_CP_LIMIT(), see utf.h).</p> + * + * UnicodeString methods are more lenient with regard to input parameter values + * than other ICU APIs. In particular: + * - If indexes are out of bounds for a UnicodeString object + * (<0 or >length()) then they are "pinned" to the nearest boundary. + * - If primitive string pointer values (e.g., const UChar * or char *) + * for input strings are NULL, then those input string parameters are treated + * as if they pointed to an empty string. + * However, this is <em>not</em> the case for char * parameters for charset names + * or other IDs. + * - Most UnicodeString methods do not take a UErrorCode parameter because + * there are usually very few opportunities for failure other than a shortage + * of memory, error codes in low-level C++ string methods would be inconvenient, + * and the error code as the last parameter (ICU convention) would prevent + * the use of default parameter values. + * Instead, such methods set the UnicodeString into a "bogus" state + * (see isBogus()) if an error occurs. + * + * In string comparisons, two UnicodeString objects that are both "bogus" + * compare equal (to be transitive and prevent endless loops in sorting), + * and a "bogus" string compares less than any non-"bogus" one. + * + * Const UnicodeString methods are thread-safe. Multiple threads can use + * const methods on the same UnicodeString object simultaneously, + * but non-const methods must not be called concurrently (in multiple threads) + * with any other (const or non-const) methods. + * + * Similarly, const UnicodeString & parameters are thread-safe. + * One object may be passed in as such a parameter concurrently in multiple threads. + * This includes the const UnicodeString & parameters for + * copy construction, assignment, and cloning. + * + * <p>UnicodeString uses several storage methods. + * String contents can be stored inside the UnicodeString object itself, + * in an allocated and shared buffer, or in an outside buffer that is "aliased". + * Most of this is done transparently, but careful aliasing in particular provides + * significant performance improvements. + * Also, the internal buffer is accessible via special functions. + * For details see the + * <a href="http://icu-project.org/userguide/strings.html">User Guide Strings chapter</a>.</p> + * + * @see utf.h + * @see CharacterIterator + * @stable ICU 2.0 + */ +class U_COMMON_API UnicodeString : public Replaceable +{ +public: + + /** + * Constant to be used in the UnicodeString(char *, int32_t, EInvariant) constructor + * which constructs a Unicode string from an invariant-character char * string. + * Use the macro US_INV instead of the full qualification for this value. + * + * @see US_INV + * @stable ICU 3.2 + */ + enum EInvariant { + /** + * @see EInvariant + * @stable ICU 3.2 + */ + kInvariant + }; + + //======================================== + // Read-only operations + //======================================== + + /* Comparison - bitwise only - for international comparison use collation */ + + /** + * Equality operator. Performs only bitwise comparison. + * @param text The UnicodeString to compare to this one. + * @return TRUE if <TT>text</TT> contains the same characters as this one, + * FALSE otherwise. + * @stable ICU 2.0 + */ + inline UBool operator== (const UnicodeString& text) const; + + /** + * Inequality operator. Performs only bitwise comparison. + * @param text The UnicodeString to compare to this one. + * @return FALSE if <TT>text</TT> contains the same characters as this one, + * TRUE otherwise. + * @stable ICU 2.0 + */ + inline UBool operator!= (const UnicodeString& text) const; + + /** + * Greater than operator. Performs only bitwise comparison. + * @param text The UnicodeString to compare to this one. + * @return TRUE if the characters in this are bitwise + * greater than the characters in <code>text</code>, FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool operator> (const UnicodeString& text) const; + + /** + * Less than operator. Performs only bitwise comparison. + * @param text The UnicodeString to compare to this one. + * @return TRUE if the characters in this are bitwise + * less than the characters in <code>text</code>, FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool operator< (const UnicodeString& text) const; + + /** + * Greater than or equal operator. Performs only bitwise comparison. + * @param text The UnicodeString to compare to this one. + * @return TRUE if the characters in this are bitwise + * greater than or equal to the characters in <code>text</code>, FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool operator>= (const UnicodeString& text) const; + + /** + * Less than or equal operator. Performs only bitwise comparison. + * @param text The UnicodeString to compare to this one. + * @return TRUE if the characters in this are bitwise + * less than or equal to the characters in <code>text</code>, FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool operator<= (const UnicodeString& text) const; + + /** + * Compare the characters bitwise in this UnicodeString to + * the characters in <code>text</code>. + * @param text The UnicodeString to compare to this one. + * @return The result of bitwise character comparison: 0 if this + * contains the same characters as <code>text</code>, -1 if the characters in + * this are bitwise less than the characters in <code>text</code>, +1 if the + * characters in this are bitwise greater than the characters + * in <code>text</code>. + * @stable ICU 2.0 + */ + inline int8_t compare(const UnicodeString& text) const; + + /** + * Compare the characters bitwise in the range + * [<TT>start</TT>, <TT>start + length</TT>) with the characters + * in <TT>text</TT> + * @param start the offset at which the compare operation begins + * @param length the number of characters of text to compare. + * @param text the other text to be compared against this string. + * @return The result of bitwise character comparison: 0 if this + * contains the same characters as <code>text</code>, -1 if the characters in + * this are bitwise less than the characters in <code>text</code>, +1 if the + * characters in this are bitwise greater than the characters + * in <code>text</code>. + * @stable ICU 2.0 + */ + inline int8_t compare(int32_t start, + int32_t length, + const UnicodeString& text) const; + + /** + * Compare the characters bitwise in the range + * [<TT>start</TT>, <TT>start + length</TT>) with the characters + * in <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). + * @param start the offset at which the compare operation begins + * @param length the number of characters in this to compare. + * @param srcText the text to be compared + * @param srcStart the offset into <TT>srcText</TT> to start comparison + * @param srcLength the number of characters in <TT>src</TT> to compare + * @return The result of bitwise character comparison: 0 if this + * contains the same characters as <code>srcText</code>, -1 if the characters in + * this are bitwise less than the characters in <code>srcText</code>, +1 if the + * characters in this are bitwise greater than the characters + * in <code>srcText</code>. + * @stable ICU 2.0 + */ + inline int8_t compare(int32_t start, + int32_t length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const; + + /** + * Compare the characters bitwise in this UnicodeString with the first + * <TT>srcLength</TT> characters in <TT>srcChars</TT>. + * @param srcChars The characters to compare to this UnicodeString. + * @param srcLength the number of characters in <TT>srcChars</TT> to compare + * @return The result of bitwise character comparison: 0 if this + * contains the same characters as <code>srcChars</code>, -1 if the characters in + * this are bitwise less than the characters in <code>srcChars</code>, +1 if the + * characters in this are bitwise greater than the characters + * in <code>srcChars</code>. + * @stable ICU 2.0 + */ + inline int8_t compare(const UChar *srcChars, + int32_t srcLength) const; + + /** + * Compare the characters bitwise in the range + * [<TT>start</TT>, <TT>start + length</TT>) with the first + * <TT>length</TT> characters in <TT>srcChars</TT> + * @param start the offset at which the compare operation begins + * @param length the number of characters to compare. + * @param srcChars the characters to be compared + * @return The result of bitwise character comparison: 0 if this + * contains the same characters as <code>srcChars</code>, -1 if the characters in + * this are bitwise less than the characters in <code>srcChars</code>, +1 if the + * characters in this are bitwise greater than the characters + * in <code>srcChars</code>. + * @stable ICU 2.0 + */ + inline int8_t compare(int32_t start, + int32_t length, + const UChar *srcChars) const; + + /** + * Compare the characters bitwise in the range + * [<TT>start</TT>, <TT>start + length</TT>) with the characters + * in <TT>srcChars</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). + * @param start the offset at which the compare operation begins + * @param length the number of characters in this to compare + * @param srcChars the characters to be compared + * @param srcStart the offset into <TT>srcChars</TT> to start comparison + * @param srcLength the number of characters in <TT>srcChars</TT> to compare + * @return The result of bitwise character comparison: 0 if this + * contains the same characters as <code>srcChars</code>, -1 if the characters in + * this are bitwise less than the characters in <code>srcChars</code>, +1 if the + * characters in this are bitwise greater than the characters + * in <code>srcChars</code>. + * @stable ICU 2.0 + */ + inline int8_t compare(int32_t start, + int32_t length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const; + + /** + * Compare the characters bitwise in the range + * [<TT>start</TT>, <TT>limit</TT>) with the characters + * in <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcLimit</TT>). + * @param start the offset at which the compare operation begins + * @param limit the offset immediately following the compare operation + * @param srcText the text to be compared + * @param srcStart the offset into <TT>srcText</TT> to start comparison + * @param srcLimit the offset into <TT>srcText</TT> to limit comparison + * @return The result of bitwise character comparison: 0 if this + * contains the same characters as <code>srcText</code>, -1 if the characters in + * this are bitwise less than the characters in <code>srcText</code>, +1 if the + * characters in this are bitwise greater than the characters + * in <code>srcText</code>. + * @stable ICU 2.0 + */ + inline int8_t compareBetween(int32_t start, + int32_t limit, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLimit) const; + + /** + * Compare two Unicode strings in code point order. + * The result may be different from the results of compare(), operator<, etc. + * if supplementary characters are present: + * + * In UTF-16, supplementary characters (with code points U+10000 and above) are + * stored with pairs of surrogate code units. These have values from 0xd800 to 0xdfff, + * which means that they compare as less than some other BMP characters like U+feff. + * This function compares Unicode strings in code point order. + * If either of the UTF-16 strings is malformed (i.e., it contains unpaired surrogates), then the result is not defined. + * + * @param text Another string to compare this one to. + * @return a negative/zero/positive integer corresponding to whether + * this string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ + inline int8_t compareCodePointOrder(const UnicodeString& text) const; + + /** + * Compare two Unicode strings in code point order. + * The result may be different from the results of compare(), operator<, etc. + * if supplementary characters are present: + * + * In UTF-16, supplementary characters (with code points U+10000 and above) are + * stored with pairs of surrogate code units. These have values from 0xd800 to 0xdfff, + * which means that they compare as less than some other BMP characters like U+feff. + * This function compares Unicode strings in code point order. + * If either of the UTF-16 strings is malformed (i.e., it contains unpaired surrogates), then the result is not defined. + * + * @param start The start offset in this string at which the compare operation begins. + * @param length The number of code units from this string to compare. + * @param srcText Another string to compare this one to. + * @return a negative/zero/positive integer corresponding to whether + * this string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ + inline int8_t compareCodePointOrder(int32_t start, + int32_t length, + const UnicodeString& srcText) const; + + /** + * Compare two Unicode strings in code point order. + * The result may be different from the results of compare(), operator<, etc. + * if supplementary characters are present: + * + * In UTF-16, supplementary characters (with code points U+10000 and above) are + * stored with pairs of surrogate code units. These have values from 0xd800 to 0xdfff, + * which means that they compare as less than some other BMP characters like U+feff. + * This function compares Unicode strings in code point order. + * If either of the UTF-16 strings is malformed (i.e., it contains unpaired surrogates), then the result is not defined. + * + * @param start The start offset in this string at which the compare operation begins. + * @param length The number of code units from this string to compare. + * @param srcText Another string to compare this one to. + * @param srcStart The start offset in that string at which the compare operation begins. + * @param srcLength The number of code units from that string to compare. + * @return a negative/zero/positive integer corresponding to whether + * this string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ + inline int8_t compareCodePointOrder(int32_t start, + int32_t length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const; + + /** + * Compare two Unicode strings in code point order. + * The result may be different from the results of compare(), operator<, etc. + * if supplementary characters are present: + * + * In UTF-16, supplementary characters (with code points U+10000 and above) are + * stored with pairs of surrogate code units. These have values from 0xd800 to 0xdfff, + * which means that they compare as less than some other BMP characters like U+feff. + * This function compares Unicode strings in code point order. + * If either of the UTF-16 strings is malformed (i.e., it contains unpaired surrogates), then the result is not defined. + * + * @param srcChars A pointer to another string to compare this one to. + * @param srcLength The number of code units from that string to compare. + * @return a negative/zero/positive integer corresponding to whether + * this string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ + inline int8_t compareCodePointOrder(const UChar *srcChars, + int32_t srcLength) const; + + /** + * Compare two Unicode strings in code point order. + * The result may be different from the results of compare(), operator<, etc. + * if supplementary characters are present: + * + * In UTF-16, supplementary characters (with code points U+10000 and above) are + * stored with pairs of surrogate code units. These have values from 0xd800 to 0xdfff, + * which means that they compare as less than some other BMP characters like U+feff. + * This function compares Unicode strings in code point order. + * If either of the UTF-16 strings is malformed (i.e., it contains unpaired surrogates), then the result is not defined. + * + * @param start The start offset in this string at which the compare operation begins. + * @param length The number of code units from this string to compare. + * @param srcChars A pointer to another string to compare this one to. + * @return a negative/zero/positive integer corresponding to whether + * this string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ + inline int8_t compareCodePointOrder(int32_t start, + int32_t length, + const UChar *srcChars) const; + + /** + * Compare two Unicode strings in code point order. + * The result may be different from the results of compare(), operator<, etc. + * if supplementary characters are present: + * + * In UTF-16, supplementary characters (with code points U+10000 and above) are + * stored with pairs of surrogate code units. These have values from 0xd800 to 0xdfff, + * which means that they compare as less than some other BMP characters like U+feff. + * This function compares Unicode strings in code point order. + * If either of the UTF-16 strings is malformed (i.e., it contains unpaired surrogates), then the result is not defined. + * + * @param start The start offset in this string at which the compare operation begins. + * @param length The number of code units from this string to compare. + * @param srcChars A pointer to another string to compare this one to. + * @param srcStart The start offset in that string at which the compare operation begins. + * @param srcLength The number of code units from that string to compare. + * @return a negative/zero/positive integer corresponding to whether + * this string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ + inline int8_t compareCodePointOrder(int32_t start, + int32_t length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const; + + /** + * Compare two Unicode strings in code point order. + * The result may be different from the results of compare(), operator<, etc. + * if supplementary characters are present: + * + * In UTF-16, supplementary characters (with code points U+10000 and above) are + * stored with pairs of surrogate code units. These have values from 0xd800 to 0xdfff, + * which means that they compare as less than some other BMP characters like U+feff. + * This function compares Unicode strings in code point order. + * If either of the UTF-16 strings is malformed (i.e., it contains unpaired surrogates), then the result is not defined. + * + * @param start The start offset in this string at which the compare operation begins. + * @param limit The offset after the last code unit from this string to compare. + * @param srcText Another string to compare this one to. + * @param srcStart The start offset in that string at which the compare operation begins. + * @param srcLimit The offset after the last code unit from that string to compare. + * @return a negative/zero/positive integer corresponding to whether + * this string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ + inline int8_t compareCodePointOrderBetween(int32_t start, + int32_t limit, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLimit) const; + + /** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to this->foldCase(options).compare(text.foldCase(options)). + * + * @param text Another string to compare this one to. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ + inline int8_t caseCompare(const UnicodeString& text, uint32_t options) const; + + /** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to this->foldCase(options).compare(srcText.foldCase(options)). + * + * @param start The start offset in this string at which the compare operation begins. + * @param length The number of code units from this string to compare. + * @param srcText Another string to compare this one to. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ + inline int8_t caseCompare(int32_t start, + int32_t length, + const UnicodeString& srcText, + uint32_t options) const; + + /** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to this->foldCase(options).compare(srcText.foldCase(options)). + * + * @param start The start offset in this string at which the compare operation begins. + * @param length The number of code units from this string to compare. + * @param srcText Another string to compare this one to. + * @param srcStart The start offset in that string at which the compare operation begins. + * @param srcLength The number of code units from that string to compare. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ + inline int8_t caseCompare(int32_t start, + int32_t length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength, + uint32_t options) const; + + /** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to this->foldCase(options).compare(srcChars.foldCase(options)). + * + * @param srcChars A pointer to another string to compare this one to. + * @param srcLength The number of code units from that string to compare. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ + inline int8_t caseCompare(const UChar *srcChars, + int32_t srcLength, + uint32_t options) const; + + /** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to this->foldCase(options).compare(srcChars.foldCase(options)). + * + * @param start The start offset in this string at which the compare operation begins. + * @param length The number of code units from this string to compare. + * @param srcChars A pointer to another string to compare this one to. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ + inline int8_t caseCompare(int32_t start, + int32_t length, + const UChar *srcChars, + uint32_t options) const; + + /** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to this->foldCase(options).compare(srcChars.foldCase(options)). + * + * @param start The start offset in this string at which the compare operation begins. + * @param length The number of code units from this string to compare. + * @param srcChars A pointer to another string to compare this one to. + * @param srcStart The start offset in that string at which the compare operation begins. + * @param srcLength The number of code units from that string to compare. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ + inline int8_t caseCompare(int32_t start, + int32_t length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength, + uint32_t options) const; + + /** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to this->foldCase(options).compareBetween(text.foldCase(options)). + * + * @param start The start offset in this string at which the compare operation begins. + * @param limit The offset after the last code unit from this string to compare. + * @param srcText Another string to compare this one to. + * @param srcStart The start offset in that string at which the compare operation begins. + * @param srcLimit The offset after the last code unit from that string to compare. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ + inline int8_t caseCompareBetween(int32_t start, + int32_t limit, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLimit, + uint32_t options) const; + + /** + * Determine if this starts with the characters in <TT>text</TT> + * @param text The text to match. + * @return TRUE if this starts with the characters in <TT>text</TT>, + * FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool startsWith(const UnicodeString& text) const; + + /** + * Determine if this starts with the characters in <TT>srcText</TT> + * in the range [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). + * @param srcText The text to match. + * @param srcStart the offset into <TT>srcText</TT> to start matching + * @param srcLength the number of characters in <TT>srcText</TT> to match + * @return TRUE if this starts with the characters in <TT>text</TT>, + * FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool startsWith(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const; + + /** + * Determine if this starts with the characters in <TT>srcChars</TT> + * @param srcChars The characters to match. + * @param srcLength the number of characters in <TT>srcChars</TT> + * @return TRUE if this starts with the characters in <TT>srcChars</TT>, + * FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool startsWith(const UChar *srcChars, + int32_t srcLength) const; + + /** + * Determine if this ends with the characters in <TT>srcChars</TT> + * in the range [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). + * @param srcChars The characters to match. + * @param srcStart the offset into <TT>srcText</TT> to start matching + * @param srcLength the number of characters in <TT>srcChars</TT> to match + * @return TRUE if this ends with the characters in <TT>srcChars</TT>, FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool startsWith(const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const; + + /** + * Determine if this ends with the characters in <TT>text</TT> + * @param text The text to match. + * @return TRUE if this ends with the characters in <TT>text</TT>, + * FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool endsWith(const UnicodeString& text) const; + + /** + * Determine if this ends with the characters in <TT>srcText</TT> + * in the range [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). + * @param srcText The text to match. + * @param srcStart the offset into <TT>srcText</TT> to start matching + * @param srcLength the number of characters in <TT>srcText</TT> to match + * @return TRUE if this ends with the characters in <TT>text</TT>, + * FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool endsWith(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const; + + /** + * Determine if this ends with the characters in <TT>srcChars</TT> + * @param srcChars The characters to match. + * @param srcLength the number of characters in <TT>srcChars</TT> + * @return TRUE if this ends with the characters in <TT>srcChars</TT>, + * FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool endsWith(const UChar *srcChars, + int32_t srcLength) const; + + /** + * Determine if this ends with the characters in <TT>srcChars</TT> + * in the range [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). + * @param srcChars The characters to match. + * @param srcStart the offset into <TT>srcText</TT> to start matching + * @param srcLength the number of characters in <TT>srcChars</TT> to match + * @return TRUE if this ends with the characters in <TT>srcChars</TT>, + * FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool endsWith(const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const; + + + /* Searching - bitwise only */ + + /** + * Locate in this the first occurrence of the characters in <TT>text</TT>, + * using bitwise comparison. + * @param text The text to search for. + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(const UnicodeString& text) const; + + /** + * Locate in this the first occurrence of the characters in <TT>text</TT> + * starting at offset <TT>start</TT>, using bitwise comparison. + * @param text The text to search for. + * @param start The offset at which searching will start. + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(const UnicodeString& text, + int32_t start) const; + + /** + * Locate in this the first occurrence in the range + * [<TT>start</TT>, <TT>start + length</TT>) of the characters + * in <TT>text</TT>, using bitwise comparison. + * @param text The text to search for. + * @param start The offset at which searching will start. + * @param length The number of characters to search + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(const UnicodeString& text, + int32_t start, + int32_t length) const; + + /** + * Locate in this the first occurrence in the range + * [<TT>start</TT>, <TT>start + length</TT>) of the characters + * in <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>), + * using bitwise comparison. + * @param srcText The text to search for. + * @param srcStart the offset into <TT>srcText</TT> at which + * to start matching + * @param srcLength the number of characters in <TT>srcText</TT> to match + * @param start the offset into this at which to start matching + * @param length the number of characters in this to search + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength, + int32_t start, + int32_t length) const; + + /** + * Locate in this the first occurrence of the characters in + * <TT>srcChars</TT> + * starting at offset <TT>start</TT>, using bitwise comparison. + * @param srcChars The text to search for. + * @param srcLength the number of characters in <TT>srcChars</TT> to match + * @param start the offset into this at which to start matching + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(const UChar *srcChars, + int32_t srcLength, + int32_t start) const; + + /** + * Locate in this the first occurrence in the range + * [<TT>start</TT>, <TT>start + length</TT>) of the characters + * in <TT>srcChars</TT>, using bitwise comparison. + * @param srcChars The text to search for. + * @param srcLength the number of characters in <TT>srcChars</TT> + * @param start The offset at which searching will start. + * @param length The number of characters to search + * @return The offset into this of the start of <TT>srcChars</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(const UChar *srcChars, + int32_t srcLength, + int32_t start, + int32_t length) const; + + /** + * Locate in this the first occurrence in the range + * [<TT>start</TT>, <TT>start + length</TT>) of the characters + * in <TT>srcChars</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>), + * using bitwise comparison. + * @param srcChars The text to search for. + * @param srcStart the offset into <TT>srcChars</TT> at which + * to start matching + * @param srcLength the number of characters in <TT>srcChars</TT> to match + * @param start the offset into this at which to start matching + * @param length the number of characters in this to search + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + int32_t indexOf(const UChar *srcChars, + int32_t srcStart, + int32_t srcLength, + int32_t start, + int32_t length) const; + + /** + * Locate in this the first occurrence of the BMP code point <code>c</code>, + * using bitwise comparison. + * @param c The code unit to search for. + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(UChar c) const; + + /** + * Locate in this the first occurrence of the code point <TT>c</TT>, + * using bitwise comparison. + * + * @param c The code point to search for. + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(UChar32 c) const; + + /** + * Locate in this the first occurrence of the BMP code point <code>c</code>, + * starting at offset <TT>start</TT>, using bitwise comparison. + * @param c The code unit to search for. + * @param start The offset at which searching will start. + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(UChar c, + int32_t start) const; + + /** + * Locate in this the first occurrence of the code point <TT>c</TT> + * starting at offset <TT>start</TT>, using bitwise comparison. + * + * @param c The code point to search for. + * @param start The offset at which searching will start. + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(UChar32 c, + int32_t start) const; + + /** + * Locate in this the first occurrence of the BMP code point <code>c</code> + * in the range [<TT>start</TT>, <TT>start + length</TT>), + * using bitwise comparison. + * @param c The code unit to search for. + * @param start the offset into this at which to start matching + * @param length the number of characters in this to search + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(UChar c, + int32_t start, + int32_t length) const; + + /** + * Locate in this the first occurrence of the code point <TT>c</TT> + * in the range [<TT>start</TT>, <TT>start + length</TT>), + * using bitwise comparison. + * + * @param c The code point to search for. + * @param start the offset into this at which to start matching + * @param length the number of characters in this to search + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t indexOf(UChar32 c, + int32_t start, + int32_t length) const; + + /** + * Locate in this the last occurrence of the characters in <TT>text</TT>, + * using bitwise comparison. + * @param text The text to search for. + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(const UnicodeString& text) const; + + /** + * Locate in this the last occurrence of the characters in <TT>text</TT> + * starting at offset <TT>start</TT>, using bitwise comparison. + * @param text The text to search for. + * @param start The offset at which searching will start. + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(const UnicodeString& text, + int32_t start) const; + + /** + * Locate in this the last occurrence in the range + * [<TT>start</TT>, <TT>start + length</TT>) of the characters + * in <TT>text</TT>, using bitwise comparison. + * @param text The text to search for. + * @param start The offset at which searching will start. + * @param length The number of characters to search + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(const UnicodeString& text, + int32_t start, + int32_t length) const; + + /** + * Locate in this the last occurrence in the range + * [<TT>start</TT>, <TT>start + length</TT>) of the characters + * in <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>), + * using bitwise comparison. + * @param srcText The text to search for. + * @param srcStart the offset into <TT>srcText</TT> at which + * to start matching + * @param srcLength the number of characters in <TT>srcText</TT> to match + * @param start the offset into this at which to start matching + * @param length the number of characters in this to search + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength, + int32_t start, + int32_t length) const; + + /** + * Locate in this the last occurrence of the characters in <TT>srcChars</TT> + * starting at offset <TT>start</TT>, using bitwise comparison. + * @param srcChars The text to search for. + * @param srcLength the number of characters in <TT>srcChars</TT> to match + * @param start the offset into this at which to start matching + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(const UChar *srcChars, + int32_t srcLength, + int32_t start) const; + + /** + * Locate in this the last occurrence in the range + * [<TT>start</TT>, <TT>start + length</TT>) of the characters + * in <TT>srcChars</TT>, using bitwise comparison. + * @param srcChars The text to search for. + * @param srcLength the number of characters in <TT>srcChars</TT> + * @param start The offset at which searching will start. + * @param length The number of characters to search + * @return The offset into this of the start of <TT>srcChars</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(const UChar *srcChars, + int32_t srcLength, + int32_t start, + int32_t length) const; + + /** + * Locate in this the last occurrence in the range + * [<TT>start</TT>, <TT>start + length</TT>) of the characters + * in <TT>srcChars</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>), + * using bitwise comparison. + * @param srcChars The text to search for. + * @param srcStart the offset into <TT>srcChars</TT> at which + * to start matching + * @param srcLength the number of characters in <TT>srcChars</TT> to match + * @param start the offset into this at which to start matching + * @param length the number of characters in this to search + * @return The offset into this of the start of <TT>text</TT>, + * or -1 if not found. + * @stable ICU 2.0 + */ + int32_t lastIndexOf(const UChar *srcChars, + int32_t srcStart, + int32_t srcLength, + int32_t start, + int32_t length) const; + + /** + * Locate in this the last occurrence of the BMP code point <code>c</code>, + * using bitwise comparison. + * @param c The code unit to search for. + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(UChar c) const; + + /** + * Locate in this the last occurrence of the code point <TT>c</TT>, + * using bitwise comparison. + * + * @param c The code point to search for. + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(UChar32 c) const; + + /** + * Locate in this the last occurrence of the BMP code point <code>c</code> + * starting at offset <TT>start</TT>, using bitwise comparison. + * @param c The code unit to search for. + * @param start The offset at which searching will start. + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(UChar c, + int32_t start) const; + + /** + * Locate in this the last occurrence of the code point <TT>c</TT> + * starting at offset <TT>start</TT>, using bitwise comparison. + * + * @param c The code point to search for. + * @param start The offset at which searching will start. + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(UChar32 c, + int32_t start) const; + + /** + * Locate in this the last occurrence of the BMP code point <code>c</code> + * in the range [<TT>start</TT>, <TT>start + length</TT>), + * using bitwise comparison. + * @param c The code unit to search for. + * @param start the offset into this at which to start matching + * @param length the number of characters in this to search + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(UChar c, + int32_t start, + int32_t length) const; + + /** + * Locate in this the last occurrence of the code point <TT>c</TT> + * in the range [<TT>start</TT>, <TT>start + length</TT>), + * using bitwise comparison. + * + * @param c The code point to search for. + * @param start the offset into this at which to start matching + * @param length the number of characters in this to search + * @return The offset into this of <TT>c</TT>, or -1 if not found. + * @stable ICU 2.0 + */ + inline int32_t lastIndexOf(UChar32 c, + int32_t start, + int32_t length) const; + + + /* Character access */ + + /** + * Return the code unit at offset <tt>offset</tt>. + * If the offset is not valid (0..length()-1) then U+ffff is returned. + * @param offset a valid offset into the text + * @return the code unit at offset <tt>offset</tt> + * or 0xffff if the offset is not valid for this string + * @stable ICU 2.0 + */ + inline UChar charAt(int32_t offset) const; + + /** + * Return the code unit at offset <tt>offset</tt>. + * If the offset is not valid (0..length()-1) then U+ffff is returned. + * @param offset a valid offset into the text + * @return the code unit at offset <tt>offset</tt> + * @stable ICU 2.0 + */ + inline UChar operator[] (int32_t offset) const; + + /** + * Return the code point that contains the code unit + * at offset <tt>offset</tt>. + * If the offset is not valid (0..length()-1) then U+ffff is returned. + * @param offset a valid offset into the text + * that indicates the text offset of any of the code units + * that will be assembled into a code point (21-bit value) and returned + * @return the code point of text at <tt>offset</tt> + * or 0xffff if the offset is not valid for this string + * @stable ICU 2.0 + */ + inline UChar32 char32At(int32_t offset) const; + + /** + * Adjust a random-access offset so that + * it points to the beginning of a Unicode character. + * The offset that is passed in points to + * any code unit of a code point, + * while the returned offset will point to the first code unit + * of the same code point. + * In UTF-16, if the input offset points to a second surrogate + * of a surrogate pair, then the returned offset will point + * to the first surrogate. + * @param offset a valid offset into one code point of the text + * @return offset of the first code unit of the same code point + * @see U16_SET_CP_START + * @stable ICU 2.0 + */ + inline int32_t getChar32Start(int32_t offset) const; + + /** + * Adjust a random-access offset so that + * it points behind a Unicode character. + * The offset that is passed in points behind + * any code unit of a code point, + * while the returned offset will point behind the last code unit + * of the same code point. + * In UTF-16, if the input offset points behind the first surrogate + * (i.e., to the second surrogate) + * of a surrogate pair, then the returned offset will point + * behind the second surrogate (i.e., to the first surrogate). + * @param offset a valid offset after any code unit of a code point of the text + * @return offset of the first code unit after the same code point + * @see U16_SET_CP_LIMIT + * @stable ICU 2.0 + */ + inline int32_t getChar32Limit(int32_t offset) const; + + /** + * Move the code unit index along the string by delta code points. + * Interpret the input index as a code unit-based offset into the string, + * move the index forward or backward by delta code points, and + * return the resulting index. + * The input index should point to the first code unit of a code point, + * if there is more than one. + * + * Both input and output indexes are code unit-based as for all + * string indexes/offsets in ICU (and other libraries, like MBCS char*). + * If delta<0 then the index is moved backward (toward the start of the string). + * If delta>0 then the index is moved forward (toward the end of the string). + * + * This behaves like CharacterIterator::move32(delta, kCurrent). + * + * Behavior for out-of-bounds indexes: + * <code>moveIndex32</code> pins the input index to 0..length(), i.e., + * if the input index<0 then it is pinned to 0; + * if it is index>length() then it is pinned to length(). + * Afterwards, the index is moved by <code>delta</code> code points + * forward or backward, + * but no further backward than to 0 and no further forward than to length(). + * The resulting index return value will be in between 0 and length(), inclusively. + * + * Examples: + * <pre> + * // s has code points 'a' U+10000 'b' U+10ffff U+2029 + * UnicodeString s=UNICODE_STRING("a\\U00010000b\\U0010ffff\\u2029", 31).unescape(); + * + * // initial index: position of U+10000 + * int32_t index=1; + * + * // the following examples will all result in index==4, position of U+10ffff + * + * // skip 2 code points from some position in the string + * index=s.moveIndex32(index, 2); // skips U+10000 and 'b' + * + * // go to the 3rd code point from the start of s (0-based) + * index=s.moveIndex32(0, 3); // skips 'a', U+10000, and 'b' + * + * // go to the next-to-last code point of s + * index=s.moveIndex32(s.length(), -2); // backward-skips U+2029 and U+10ffff + * </pre> + * + * @param index input code unit index + * @param delta (signed) code point count to move the index forward or backward + * in the string + * @return the resulting code unit index + * @stable ICU 2.0 + */ + int32_t moveIndex32(int32_t index, int32_t delta) const; + + /* Substring extraction */ + + /** + * Copy the characters in the range + * [<tt>start</tt>, <tt>start + length</tt>) into the array <tt>dst</tt>, + * beginning at <tt>dstStart</tt>. + * If the string aliases to <code>dst</code> itself as an external buffer, + * then extract() will not copy the contents. + * + * @param start offset of first character which will be copied into the array + * @param length the number of characters to extract + * @param dst array in which to copy characters. The length of <tt>dst</tt> + * must be at least (<tt>dstStart + length</tt>). + * @param dstStart the offset in <TT>dst</TT> where the first character + * will be extracted + * @stable ICU 2.0 + */ + inline void extract(int32_t start, + int32_t length, + UChar *dst, + int32_t dstStart = 0) const; + + /** + * Copy the contents of the string into dest. + * This is a convenience function that + * checks if there is enough space in dest, + * extracts the entire string if possible, + * and NUL-terminates dest if possible. + * + * If the string fits into dest but cannot be NUL-terminated + * (length()==destCapacity) then the error code is set to U_STRING_NOT_TERMINATED_WARNING. + * If the string itself does not fit into dest + * (length()>destCapacity) then the error code is set to U_BUFFER_OVERFLOW_ERROR. + * + * If the string aliases to <code>dest</code> itself as an external buffer, + * then extract() will not copy the contents. + * + * @param dest Destination string buffer. + * @param destCapacity Number of UChars available at dest. + * @param errorCode ICU error code. + * @return length() + * @stable ICU 2.0 + */ + int32_t + extract(UChar *dest, int32_t destCapacity, + UErrorCode &errorCode) const; + + /** + * Copy the characters in the range + * [<tt>start</tt>, <tt>start + length</tt>) into the UnicodeString + * <tt>target</tt>. + * @param start offset of first character which will be copied + * @param length the number of characters to extract + * @param target UnicodeString into which to copy characters. + * @return A reference to <TT>target</TT> + * @stable ICU 2.0 + */ + inline void extract(int32_t start, + int32_t length, + UnicodeString& target) const; + + /** + * Copy the characters in the range [<tt>start</tt>, <tt>limit</tt>) + * into the array <tt>dst</tt>, beginning at <tt>dstStart</tt>. + * @param start offset of first character which will be copied into the array + * @param limit offset immediately following the last character to be copied + * @param dst array in which to copy characters. The length of <tt>dst</tt> + * must be at least (<tt>dstStart + (limit - start)</tt>). + * @param dstStart the offset in <TT>dst</TT> where the first character + * will be extracted + * @stable ICU 2.0 + */ + inline void extractBetween(int32_t start, + int32_t limit, + UChar *dst, + int32_t dstStart = 0) const; + + /** + * Copy the characters in the range [<tt>start</tt>, <tt>limit</tt>) + * into the UnicodeString <tt>target</tt>. Replaceable API. + * @param start offset of first character which will be copied + * @param limit offset immediately following the last character to be copied + * @param target UnicodeString into which to copy characters. + * @return A reference to <TT>target</TT> + * @stable ICU 2.0 + */ + virtual void extractBetween(int32_t start, + int32_t limit, + UnicodeString& target) const; + + /** + * Copy the characters in the range + * [<tt>start</TT>, <tt>start + length</TT>) into an array of characters. + * All characters must be invariant (see utypes.h). + * Use US_INV as the last, signature-distinguishing parameter. + * + * This function does not write any more than <code>targetLength</code> + * characters but returns the length of the entire output string + * so that one can allocate a larger buffer and call the function again + * if necessary. + * The output string is NUL-terminated if possible. + * + * @param start offset of first character which will be copied + * @param startLength the number of characters to extract + * @param target the target buffer for extraction, can be NULL + * if targetLength is 0 + * @param targetCapacity the length of the target buffer + * @param inv Signature-distinguishing paramater, use US_INV. + * @return the output string length, not including the terminating NUL + * @stable ICU 3.2 + */ + int32_t extract(int32_t start, + int32_t startLength, + char *target, + int32_t targetCapacity, + enum EInvariant inv) const; + +#if !UCONFIG_NO_CONVERSION + + /** + * Copy the characters in the range + * [<tt>start</TT>, <tt>start + length</TT>) into an array of characters + * in a specified codepage. + * The output string is NUL-terminated. + * + * Recommendation: For invariant-character strings use + * extract(int32_t start, int32_t length, char *target, int32_t targetCapacity, enum EInvariant inv) const + * because it avoids object code dependencies of UnicodeString on + * the conversion code. + * + * @param start offset of first character which will be copied + * @param startLength the number of characters to extract + * @param target the target buffer for extraction + * @param codepage the desired codepage for the characters. 0 has + * the special meaning of the default codepage + * If <code>codepage</code> is an empty string (<code>""</code>), + * then a simple conversion is performed on the codepage-invariant + * subset ("invariant characters") of the platform encoding. See utypes.h. + * If <TT>target</TT> is NULL, then the number of bytes required for + * <TT>target</TT> is returned. It is assumed that the target is big enough + * to fit all of the characters. + * @return the output string length, not including the terminating NUL + * @stable ICU 2.0 + */ + inline int32_t extract(int32_t start, + int32_t startLength, + char *target, + const char *codepage = 0) const; + + /** + * Copy the characters in the range + * [<tt>start</TT>, <tt>start + length</TT>) into an array of characters + * in a specified codepage. + * This function does not write any more than <code>targetLength</code> + * characters but returns the length of the entire output string + * so that one can allocate a larger buffer and call the function again + * if necessary. + * The output string is NUL-terminated if possible. + * + * Recommendation: For invariant-character strings use + * extract(int32_t start, int32_t length, char *target, int32_t targetCapacity, enum EInvariant inv) const + * because it avoids object code dependencies of UnicodeString on + * the conversion code. + * + * @param start offset of first character which will be copied + * @param startLength the number of characters to extract + * @param target the target buffer for extraction + * @param targetLength the length of the target buffer + * @param codepage the desired codepage for the characters. 0 has + * the special meaning of the default codepage + * If <code>codepage</code> is an empty string (<code>""</code>), + * then a simple conversion is performed on the codepage-invariant + * subset ("invariant characters") of the platform encoding. See utypes.h. + * If <TT>target</TT> is NULL, then the number of bytes required for + * <TT>target</TT> is returned. + * @return the output string length, not including the terminating NUL + * @stable ICU 2.0 + */ + int32_t extract(int32_t start, + int32_t startLength, + char *target, + uint32_t targetLength, + const char *codepage = 0) const; + + /** + * Convert the UnicodeString into a codepage string using an existing UConverter. + * The output string is NUL-terminated if possible. + * + * This function avoids the overhead of opening and closing a converter if + * multiple strings are extracted. + * + * @param dest destination string buffer, can be NULL if destCapacity==0 + * @param destCapacity the number of chars available at dest + * @param cnv the converter object to be used (ucnv_resetFromUnicode() will be called), + * or NULL for the default converter + * @param errorCode normal ICU error code + * @return the length of the output string, not counting the terminating NUL; + * if the length is greater than destCapacity, then the string will not fit + * and a buffer of the indicated length would need to be passed in + * @stable ICU 2.0 + */ + int32_t extract(char *dest, int32_t destCapacity, + UConverter *cnv, + UErrorCode &errorCode) const; + +#endif + + /* Length operations */ + + /** + * Return the length of the UnicodeString object. + * The length is the number of UChar code units are in the UnicodeString. + * If you want the number of code points, please use countChar32(). + * @return the length of the UnicodeString object + * @see countChar32 + * @stable ICU 2.0 + */ + inline int32_t length(void) const; + + /** + * Count Unicode code points in the length UChar code units of the string. + * A code point may occupy either one or two UChar code units. + * Counting code points involves reading all code units. + * + * This functions is basically the inverse of moveIndex32(). + * + * @param start the index of the first code unit to check + * @param length the number of UChar code units to check + * @return the number of code points in the specified code units + * @see length + * @stable ICU 2.0 + */ + int32_t + countChar32(int32_t start=0, int32_t length=INT32_MAX) const; + + /** + * Check if the length UChar code units of the string + * contain more Unicode code points than a certain number. + * This is more efficient than counting all code points in this part of the string + * and comparing that number with a threshold. + * This function may not need to scan the string at all if the length + * falls within a certain range, and + * never needs to count more than 'number+1' code points. + * Logically equivalent to (countChar32(start, length)>number). + * A Unicode code point may occupy either one or two UChar code units. + * + * @param start the index of the first code unit to check (0 for the entire string) + * @param length the number of UChar code units to check + * (use INT32_MAX for the entire string; remember that start/length + * values are pinned) + * @param number The number of code points in the (sub)string is compared against + * the 'number' parameter. + * @return Boolean value for whether the string contains more Unicode code points + * than 'number'. Same as (u_countChar32(s, length)>number). + * @see countChar32 + * @see u_strHasMoreChar32Than + * @stable ICU 2.4 + */ + UBool + hasMoreChar32Than(int32_t start, int32_t length, int32_t number) const; + + /** + * Determine if this string is empty. + * @return TRUE if this string contains 0 characters, FALSE otherwise. + * @stable ICU 2.0 + */ + inline UBool isEmpty(void) const; + + /** + * Return the capacity of the internal buffer of the UnicodeString object. + * This is useful together with the getBuffer functions. + * See there for details. + * + * @return the number of UChars available in the internal buffer + * @see getBuffer + * @stable ICU 2.0 + */ + inline int32_t getCapacity(void) const; + + /* Other operations */ + + /** + * Generate a hash code for this object. + * @return The hash code of this UnicodeString. + * @stable ICU 2.0 + */ + inline int32_t hashCode(void) const; + + /** + * Determine if this object contains a valid string. + * A bogus string has no value. It is different from an empty string. + * It can be used to indicate that no string value is available. + * getBuffer() and getTerminatedBuffer() return NULL, and + * length() returns 0. + * + * @return TRUE if the string is valid, FALSE otherwise + * @see setToBogus() + * @stable ICU 2.0 + */ + inline UBool isBogus(void) const; + + + //======================================== + // Write operations + //======================================== + + /* Assignment operations */ + + /** + * Assignment operator. Replace the characters in this UnicodeString + * with the characters from <TT>srcText</TT>. + * @param srcText The text containing the characters to replace + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString &operator=(const UnicodeString &srcText); + + /** + * Almost the same as the assignment operator. + * Replace the characters in this UnicodeString + * with the characters from <code>srcText</code>. + * + * This function works the same for all strings except for ones that + * are readonly aliases. + * Starting with ICU 2.4, the assignment operator and the copy constructor + * allocate a new buffer and copy the buffer contents even for readonly aliases. + * This function implements the old, more efficient but less safe behavior + * of making this string also a readonly alias to the same buffer. + * The fastCopyFrom function must be used only if it is known that the lifetime of + * this UnicodeString is at least as long as the lifetime of the aliased buffer + * including its contents, for example for strings from resource bundles + * or aliases to string contents. + * + * @param src The text containing the characters to replace. + * @return a reference to this + * @stable ICU 2.4 + */ + UnicodeString &fastCopyFrom(const UnicodeString &src); + + /** + * Assignment operator. Replace the characters in this UnicodeString + * with the code unit <TT>ch</TT>. + * @param ch the code unit to replace + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& operator= (UChar ch); + + /** + * Assignment operator. Replace the characters in this UnicodeString + * with the code point <TT>ch</TT>. + * @param ch the code point to replace + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& operator= (UChar32 ch); + + /** + * Set the text in the UnicodeString object to the characters + * in <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcText.length()</TT>). + * <TT>srcText</TT> is not modified. + * @param srcText the source for the new characters + * @param srcStart the offset into <TT>srcText</TT> where new characters + * will be obtained + * @return a reference to this + * @stable ICU 2.2 + */ + inline UnicodeString& setTo(const UnicodeString& srcText, + int32_t srcStart); + + /** + * Set the text in the UnicodeString object to the characters + * in <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). + * <TT>srcText</TT> is not modified. + * @param srcText the source for the new characters + * @param srcStart the offset into <TT>srcText</TT> where new characters + * will be obtained + * @param srcLength the number of characters in <TT>srcText</TT> in the + * replace string. + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& setTo(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength); + + /** + * Set the text in the UnicodeString object to the characters in + * <TT>srcText</TT>. + * <TT>srcText</TT> is not modified. + * @param srcText the source for the new characters + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& setTo(const UnicodeString& srcText); + + /** + * Set the characters in the UnicodeString object to the characters + * in <TT>srcChars</TT>. <TT>srcChars</TT> is not modified. + * @param srcChars the source for the new characters + * @param srcLength the number of Unicode characters in srcChars. + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& setTo(const UChar *srcChars, + int32_t srcLength); + + /** + * Set the characters in the UnicodeString object to the code unit + * <TT>srcChar</TT>. + * @param srcChar the code unit which becomes the UnicodeString's character + * content + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString& setTo(UChar srcChar); + + /** + * Set the characters in the UnicodeString object to the code point + * <TT>srcChar</TT>. + * @param srcChar the code point which becomes the UnicodeString's character + * content + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString& setTo(UChar32 srcChar); + + /** + * Aliasing setTo() function, analogous to the readonly-aliasing UChar* constructor. + * The text will be used for the UnicodeString object, but + * it will not be released when the UnicodeString is destroyed. + * This has copy-on-write semantics: + * When the string is modified, then the buffer is first copied into + * newly allocated memory. + * The aliased buffer is never modified. + * In an assignment to another UnicodeString, the text will be aliased again, + * so that both strings then alias the same readonly-text. + * + * @param isTerminated specifies if <code>text</code> is <code>NUL</code>-terminated. + * This must be true if <code>textLength==-1</code>. + * @param text The characters to alias for the UnicodeString. + * @param textLength The number of Unicode characters in <code>text</code> to alias. + * If -1, then this constructor will determine the length + * by calling <code>u_strlen()</code>. + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString &setTo(UBool isTerminated, + const UChar *text, + int32_t textLength); + + /** + * Aliasing setTo() function, analogous to the writable-aliasing UChar* constructor. + * The text will be used for the UnicodeString object, but + * it will not be released when the UnicodeString is destroyed. + * This has write-through semantics: + * For as long as the capacity of the buffer is sufficient, write operations + * will directly affect the buffer. When more capacity is necessary, then + * a new buffer will be allocated and the contents copied as with regularly + * constructed strings. + * In an assignment to another UnicodeString, the buffer will be copied. + * The extract(UChar *dst) function detects whether the dst pointer is the same + * as the string buffer itself and will in this case not copy the contents. + * + * @param buffer The characters to alias for the UnicodeString. + * @param buffLength The number of Unicode characters in <code>buffer</code> to alias. + * @param buffCapacity The size of <code>buffer</code> in UChars. + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString &setTo(UChar *buffer, + int32_t buffLength, + int32_t buffCapacity); + + /** + * Make this UnicodeString object invalid. + * The string will test TRUE with isBogus(). + * + * A bogus string has no value. It is different from an empty string. + * It can be used to indicate that no string value is available. + * getBuffer() and getTerminatedBuffer() return NULL, and + * length() returns 0. + * + * This utility function is used throughout the UnicodeString + * implementation to indicate that a UnicodeString operation failed, + * and may be used in other functions, + * especially but not exclusively when such functions do not + * take a UErrorCode for simplicity. + * + * The following methods, and no others, will clear a string object's bogus flag: + * - remove() + * - remove(0, INT32_MAX) + * - truncate(0) + * - operator=() (assignment operator) + * - setTo(...) + * + * The simplest ways to turn a bogus string into an empty one + * is to use the remove() function. + * Examples for other functions that are equivalent to "set to empty string": + * \code + * if(s.isBogus()) { + * s.remove(); // set to an empty string (remove all), or + * s.remove(0, INT32_MAX); // set to an empty string (remove all), or + * s.truncate(0); // set to an empty string (complete truncation), or + * s=UnicodeString(); // assign an empty string, or + * s.setTo((UChar32)-1); // set to a pseudo code point that is out of range, or + * static const UChar nul=0; + * s.setTo(&nul, 0); // set to an empty C Unicode string + * } + * \endcode + * + * @see isBogus() + * @stable ICU 2.0 + */ + void setToBogus(); + + /** + * Set the character at the specified offset to the specified character. + * @param offset A valid offset into the text of the character to set + * @param ch The new character + * @return A reference to this + * @stable ICU 2.0 + */ + UnicodeString& setCharAt(int32_t offset, + UChar ch); + + + /* Append operations */ + + /** + * Append operator. Append the code unit <TT>ch</TT> to the UnicodeString + * object. + * @param ch the code unit to be appended + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& operator+= (UChar ch); + + /** + * Append operator. Append the code point <TT>ch</TT> to the UnicodeString + * object. + * @param ch the code point to be appended + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& operator+= (UChar32 ch); + + /** + * Append operator. Append the characters in <TT>srcText</TT> to the + * UnicodeString object at offset <TT>start</TT>. <TT>srcText</TT> is + * not modified. + * @param srcText the source for the new characters + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& operator+= (const UnicodeString& srcText); + + /** + * Append the characters + * in <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>) to the + * UnicodeString object at offset <TT>start</TT>. <TT>srcText</TT> + * is not modified. + * @param srcText the source for the new characters + * @param srcStart the offset into <TT>srcText</TT> where new characters + * will be obtained + * @param srcLength the number of characters in <TT>srcText</TT> in + * the append string + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& append(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength); + + /** + * Append the characters in <TT>srcText</TT> to the UnicodeString object at + * offset <TT>start</TT>. <TT>srcText</TT> is not modified. + * @param srcText the source for the new characters + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& append(const UnicodeString& srcText); + + /** + * Append the characters in <TT>srcChars</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>) to the UnicodeString + * object at offset + * <TT>start</TT>. <TT>srcChars</TT> is not modified. + * @param srcChars the source for the new characters + * @param srcStart the offset into <TT>srcChars</TT> where new characters + * will be obtained + * @param srcLength the number of characters in <TT>srcChars</TT> in + * the append string + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& append(const UChar *srcChars, + int32_t srcStart, + int32_t srcLength); + + /** + * Append the characters in <TT>srcChars</TT> to the UnicodeString object + * at offset <TT>start</TT>. <TT>srcChars</TT> is not modified. + * @param srcChars the source for the new characters + * @param srcLength the number of Unicode characters in <TT>srcChars</TT> + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& append(const UChar *srcChars, + int32_t srcLength); + + /** + * Append the code unit <TT>srcChar</TT> to the UnicodeString object. + * @param srcChar the code unit to append + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& append(UChar srcChar); + + /** + * Append the code point <TT>srcChar</TT> to the UnicodeString object. + * @param srcChar the code point to append + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& append(UChar32 srcChar); + + + /* Insert operations */ + + /** + * Insert the characters in <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>) into the UnicodeString + * object at offset <TT>start</TT>. <TT>srcText</TT> is not modified. + * @param start the offset where the insertion begins + * @param srcText the source for the new characters + * @param srcStart the offset into <TT>srcText</TT> where new characters + * will be obtained + * @param srcLength the number of characters in <TT>srcText</TT> in + * the insert string + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& insert(int32_t start, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength); + + /** + * Insert the characters in <TT>srcText</TT> into the UnicodeString object + * at offset <TT>start</TT>. <TT>srcText</TT> is not modified. + * @param start the offset where the insertion begins + * @param srcText the source for the new characters + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& insert(int32_t start, + const UnicodeString& srcText); + + /** + * Insert the characters in <TT>srcChars</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>) into the UnicodeString + * object at offset <TT>start</TT>. <TT>srcChars</TT> is not modified. + * @param start the offset at which the insertion begins + * @param srcChars the source for the new characters + * @param srcStart the offset into <TT>srcChars</TT> where new characters + * will be obtained + * @param srcLength the number of characters in <TT>srcChars</TT> + * in the insert string + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& insert(int32_t start, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength); + + /** + * Insert the characters in <TT>srcChars</TT> into the UnicodeString object + * at offset <TT>start</TT>. <TT>srcChars</TT> is not modified. + * @param start the offset where the insertion begins + * @param srcChars the source for the new characters + * @param srcLength the number of Unicode characters in srcChars. + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& insert(int32_t start, + const UChar *srcChars, + int32_t srcLength); + + /** + * Insert the code unit <TT>srcChar</TT> into the UnicodeString object at + * offset <TT>start</TT>. + * @param start the offset at which the insertion occurs + * @param srcChar the code unit to insert + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& insert(int32_t start, + UChar srcChar); + + /** + * Insert the code point <TT>srcChar</TT> into the UnicodeString object at + * offset <TT>start</TT>. + * @param start the offset at which the insertion occurs + * @param srcChar the code point to insert + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& insert(int32_t start, + UChar32 srcChar); + + + /* Replace operations */ + + /** + * Replace the characters in the range + * [<TT>start</TT>, <TT>start + length</TT>) with the characters in + * <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). + * <TT>srcText</TT> is not modified. + * @param start the offset at which the replace operation begins + * @param length the number of characters to replace. The character at + * <TT>start + length</TT> is not modified. + * @param srcText the source for the new characters + * @param srcStart the offset into <TT>srcText</TT> where new characters + * will be obtained + * @param srcLength the number of characters in <TT>srcText</TT> in + * the replace string + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString& replace(int32_t start, + int32_t length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength); + + /** + * Replace the characters in the range + * [<TT>start</TT>, <TT>start + length</TT>) + * with the characters in <TT>srcText</TT>. <TT>srcText</TT> is + * not modified. + * @param start the offset at which the replace operation begins + * @param length the number of characters to replace. The character at + * <TT>start + length</TT> is not modified. + * @param srcText the source for the new characters + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString& replace(int32_t start, + int32_t length, + const UnicodeString& srcText); + + /** + * Replace the characters in the range + * [<TT>start</TT>, <TT>start + length</TT>) with the characters in + * <TT>srcChars</TT> in the range + * [<TT>srcStart</TT>, <TT>srcStart + srcLength</TT>). <TT>srcChars</TT> + * is not modified. + * @param start the offset at which the replace operation begins + * @param length the number of characters to replace. The character at + * <TT>start + length</TT> is not modified. + * @param srcChars the source for the new characters + * @param srcStart the offset into <TT>srcChars</TT> where new characters + * will be obtained + * @param srcLength the number of characters in <TT>srcChars</TT> + * in the replace string + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString& replace(int32_t start, + int32_t length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength); + + /** + * Replace the characters in the range + * [<TT>start</TT>, <TT>start + length</TT>) with the characters in + * <TT>srcChars</TT>. <TT>srcChars</TT> is not modified. + * @param start the offset at which the replace operation begins + * @param length number of characters to replace. The character at + * <TT>start + length</TT> is not modified. + * @param srcChars the source for the new characters + * @param srcLength the number of Unicode characters in srcChars + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& replace(int32_t start, + int32_t length, + const UChar *srcChars, + int32_t srcLength); + + /** + * Replace the characters in the range + * [<TT>start</TT>, <TT>start + length</TT>) with the code unit + * <TT>srcChar</TT>. + * @param start the offset at which the replace operation begins + * @param length the number of characters to replace. The character at + * <TT>start + length</TT> is not modified. + * @param srcChar the new code unit + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& replace(int32_t start, + int32_t length, + UChar srcChar); + + /** + * Replace the characters in the range + * [<TT>start</TT>, <TT>start + length</TT>) with the code point + * <TT>srcChar</TT>. + * @param start the offset at which the replace operation begins + * @param length the number of characters to replace. The character at + * <TT>start + length</TT> is not modified. + * @param srcChar the new code point + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& replace(int32_t start, + int32_t length, + UChar32 srcChar); + + /** + * Replace the characters in the range [<TT>start</TT>, <TT>limit</TT>) + * with the characters in <TT>srcText</TT>. <TT>srcText</TT> is not modified. + * @param start the offset at which the replace operation begins + * @param limit the offset immediately following the replace range + * @param srcText the source for the new characters + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& replaceBetween(int32_t start, + int32_t limit, + const UnicodeString& srcText); + + /** + * Replace the characters in the range [<TT>start</TT>, <TT>limit</TT>) + * with the characters in <TT>srcText</TT> in the range + * [<TT>srcStart</TT>, <TT>srcLimit</TT>). <TT>srcText</TT> is not modified. + * @param start the offset at which the replace operation begins + * @param limit the offset immediately following the replace range + * @param srcText the source for the new characters + * @param srcStart the offset into <TT>srcChars</TT> where new characters + * will be obtained + * @param srcLimit the offset immediately following the range to copy + * in <TT>srcText</TT> + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& replaceBetween(int32_t start, + int32_t limit, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLimit); + + /** + * Replace a substring of this object with the given text. + * @param start the beginning index, inclusive; <code>0 <= start + * <= limit</code>. + * @param limit the ending index, exclusive; <code>start <= limit + * <= length()</code>. + * @param text the text to replace characters <code>start</code> + * to <code>limit - 1</code> + * @stable ICU 2.0 + */ + virtual void handleReplaceBetween(int32_t start, + int32_t limit, + const UnicodeString& text); + + /** + * Replaceable API + * @return TRUE if it has MetaData + * @stable ICU 2.4 + */ + virtual UBool hasMetaData() const; + + /** + * Copy a substring of this object, retaining attribute (out-of-band) + * information. This method is used to duplicate or reorder substrings. + * The destination index must not overlap the source range. + * + * @param start the beginning index, inclusive; <code>0 <= start <= + * limit</code>. + * @param limit the ending index, exclusive; <code>start <= limit <= + * length()</code>. + * @param dest the destination index. The characters from + * <code>start..limit-1</code> will be copied to <code>dest</code>. + * Implementations of this method may assume that <code>dest <= start || + * dest >= limit</code>. + * @stable ICU 2.0 + */ + virtual void copy(int32_t start, int32_t limit, int32_t dest); + + /* Search and replace operations */ + + /** + * Replace all occurrences of characters in oldText with the characters + * in newText + * @param oldText the text containing the search text + * @param newText the text containing the replacement text + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& findAndReplace(const UnicodeString& oldText, + const UnicodeString& newText); + + /** + * Replace all occurrences of characters in oldText with characters + * in newText + * in the range [<TT>start</TT>, <TT>start + length</TT>). + * @param start the start of the range in which replace will performed + * @param length the length of the range in which replace will be performed + * @param oldText the text containing the search text + * @param newText the text containing the replacement text + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& findAndReplace(int32_t start, + int32_t length, + const UnicodeString& oldText, + const UnicodeString& newText); + + /** + * Replace all occurrences of characters in oldText in the range + * [<TT>oldStart</TT>, <TT>oldStart + oldLength</TT>) with the characters + * in newText in the range + * [<TT>newStart</TT>, <TT>newStart + newLength</TT>) + * in the range [<TT>start</TT>, <TT>start + length</TT>). + * @param start the start of the range in which replace will performed + * @param length the length of the range in which replace will be performed + * @param oldText the text containing the search text + * @param oldStart the start of the search range in <TT>oldText</TT> + * @param oldLength the length of the search range in <TT>oldText</TT> + * @param newText the text containing the replacement text + * @param newStart the start of the replacement range in <TT>newText</TT> + * @param newLength the length of the replacement range in <TT>newText</TT> + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString& findAndReplace(int32_t start, + int32_t length, + const UnicodeString& oldText, + int32_t oldStart, + int32_t oldLength, + const UnicodeString& newText, + int32_t newStart, + int32_t newLength); + + + /* Remove operations */ + + /** + * Remove all characters from the UnicodeString object. + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& remove(void); + + /** + * Remove the characters in the range + * [<TT>start</TT>, <TT>start + length</TT>) from the UnicodeString object. + * @param start the offset of the first character to remove + * @param length the number of characters to remove + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& remove(int32_t start, + int32_t length = (int32_t)INT32_MAX); + + /** + * Remove the characters in the range + * [<TT>start</TT>, <TT>limit</TT>) from the UnicodeString object. + * @param start the offset of the first character to remove + * @param limit the offset immediately following the range to remove + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& removeBetween(int32_t start, + int32_t limit = (int32_t)INT32_MAX); + + + /* Length operations */ + + /** + * Pad the start of this UnicodeString with the character <TT>padChar</TT>. + * If the length of this UnicodeString is less than targetLength, + * length() - targetLength copies of padChar will be added to the + * beginning of this UnicodeString. + * @param targetLength the desired length of the string + * @param padChar the character to use for padding. Defaults to + * space (U+0020) + * @return TRUE if the text was padded, FALSE otherwise. + * @stable ICU 2.0 + */ + UBool padLeading(int32_t targetLength, + UChar padChar = 0x0020); + + /** + * Pad the end of this UnicodeString with the character <TT>padChar</TT>. + * If the length of this UnicodeString is less than targetLength, + * length() - targetLength copies of padChar will be added to the + * end of this UnicodeString. + * @param targetLength the desired length of the string + * @param padChar the character to use for padding. Defaults to + * space (U+0020) + * @return TRUE if the text was padded, FALSE otherwise. + * @stable ICU 2.0 + */ + UBool padTrailing(int32_t targetLength, + UChar padChar = 0x0020); + + /** + * Truncate this UnicodeString to the <TT>targetLength</TT>. + * @param targetLength the desired length of this UnicodeString. + * @return TRUE if the text was truncated, FALSE otherwise + * @stable ICU 2.0 + */ + inline UBool truncate(int32_t targetLength); + + /** + * Trims leading and trailing whitespace from this UnicodeString. + * @return a reference to this + * @stable ICU 2.0 + */ + UnicodeString& trim(void); + + + /* Miscellaneous operations */ + + /** + * Reverse this UnicodeString in place. + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& reverse(void); + + /** + * Reverse the range [<TT>start</TT>, <TT>start + length</TT>) in + * this UnicodeString. + * @param start the start of the range to reverse + * @param length the number of characters to to reverse + * @return a reference to this + * @stable ICU 2.0 + */ + inline UnicodeString& reverse(int32_t start, + int32_t length); + + /** + * Convert the characters in this to UPPER CASE following the conventions of + * the default locale. + * @return A reference to this. + * @stable ICU 2.0 + */ + UnicodeString& toUpper(void); + + /** + * Convert the characters in this to UPPER CASE following the conventions of + * a specific locale. + * @param locale The locale containing the conventions to use. + * @return A reference to this. + * @stable ICU 2.0 + */ + UnicodeString& toUpper(const Locale& locale); + + /** + * Convert the characters in this to lower case following the conventions of + * the default locale. + * @return A reference to this. + * @stable ICU 2.0 + */ + UnicodeString& toLower(void); + + /** + * Convert the characters in this to lower case following the conventions of + * a specific locale. + * @param locale The locale containing the conventions to use. + * @return A reference to this. + * @stable ICU 2.0 + */ + UnicodeString& toLower(const Locale& locale); + +#if !UCONFIG_NO_BREAK_ITERATION + + /** + * Titlecase this string, convenience function using the default locale. + * + * Casing is locale-dependent and context-sensitive. + * Titlecasing uses a break iterator to find the first characters of words + * that are to be titlecased. It titlecases those characters and lowercases + * all others. + * + * The titlecase break iterator can be provided to customize for arbitrary + * styles, using rules and dictionaries beyond the standard iterators. + * It may be more efficient to always provide an iterator to avoid + * opening and closing one for each string. + * The standard titlecase iterator for the root locale implements the + * algorithm of Unicode TR 21. + * + * This function uses only the setText(), first() and next() methods of the + * provided break iterator. + * + * @param titleIter A break iterator to find the first characters of words + * that are to be titlecased. + * If none is provided (0), then a standard titlecase + * break iterator is opened. + * Otherwise the provided iterator is set to the string's text. + * @return A reference to this. + * @stable ICU 2.1 + */ + UnicodeString &toTitle(BreakIterator *titleIter); + + /** + * Titlecase this string. + * + * Casing is locale-dependent and context-sensitive. + * Titlecasing uses a break iterator to find the first characters of words + * that are to be titlecased. It titlecases those characters and lowercases + * all others. + * + * The titlecase break iterator can be provided to customize for arbitrary + * styles, using rules and dictionaries beyond the standard iterators. + * It may be more efficient to always provide an iterator to avoid + * opening and closing one for each string. + * The standard titlecase iterator for the root locale implements the + * algorithm of Unicode TR 21. + * + * This function uses only the setText(), first() and next() methods of the + * provided break iterator. + * + * @param titleIter A break iterator to find the first characters of words + * that are to be titlecased. + * If none is provided (0), then a standard titlecase + * break iterator is opened. + * Otherwise the provided iterator is set to the string's text. + * @param locale The locale to consider. + * @return A reference to this. + * @stable ICU 2.1 + */ + UnicodeString &toTitle(BreakIterator *titleIter, const Locale &locale); + + /** + * Titlecase this string, with options. + * + * Casing is locale-dependent and context-sensitive. + * Titlecasing uses a break iterator to find the first characters of words + * that are to be titlecased. It titlecases those characters and lowercases + * all others. (This can be modified with options.) + * + * The titlecase break iterator can be provided to customize for arbitrary + * styles, using rules and dictionaries beyond the standard iterators. + * It may be more efficient to always provide an iterator to avoid + * opening and closing one for each string. + * The standard titlecase iterator for the root locale implements the + * algorithm of Unicode TR 21. + * + * This function uses only the setText(), first() and next() methods of the + * provided break iterator. + * + * @param titleIter A break iterator to find the first characters of words + * that are to be titlecased. + * If none is provided (0), then a standard titlecase + * break iterator is opened. + * Otherwise the provided iterator is set to the string's text. + * @param locale The locale to consider. + * @param options Options bit set, see ucasemap_open(). + * @return A reference to this. + * @see U_TITLECASE_NO_LOWERCASE + * @see U_TITLECASE_NO_BREAK_ADJUSTMENT + * @see ucasemap_open + * @stable ICU 4.0 + */ + UnicodeString &toTitle(BreakIterator *titleIter, const Locale &locale, uint32_t options); + +#endif + + /** + * Case-fold the characters in this string. + * Case-folding is locale-independent and not context-sensitive, + * but there is an option for whether to include or exclude mappings for dotted I + * and dotless i that are marked with 'I' in CaseFolding.txt. + * The result may be longer or shorter than the original. + * + * @param options Either U_FOLD_CASE_DEFAULT or U_FOLD_CASE_EXCLUDE_SPECIAL_I + * @return A reference to this. + * @stable ICU 2.0 + */ + UnicodeString &foldCase(uint32_t options=0 /*U_FOLD_CASE_DEFAULT*/); + + //======================================== + // Access to the internal buffer + //======================================== + + /** + * Get a read/write pointer to the internal buffer. + * The buffer is guaranteed to be large enough for at least minCapacity UChars, + * writable, and is still owned by the UnicodeString object. + * Calls to getBuffer(minCapacity) must not be nested, and + * must be matched with calls to releaseBuffer(newLength). + * If the string buffer was read-only or shared, + * then it will be reallocated and copied. + * + * An attempted nested call will return 0, and will not further modify the + * state of the UnicodeString object. + * It also returns 0 if the string is bogus. + * + * The actual capacity of the string buffer may be larger than minCapacity. + * getCapacity() returns the actual capacity. + * For many operations, the full capacity should be used to avoid reallocations. + * + * While the buffer is "open" between getBuffer(minCapacity) + * and releaseBuffer(newLength), the following applies: + * - The string length is set to 0. + * - Any read API call on the UnicodeString object will behave like on a 0-length string. + * - Any write API call on the UnicodeString object is disallowed and will have no effect. + * - You can read from and write to the returned buffer. + * - The previous string contents will still be in the buffer; + * if you want to use it, then you need to call length() before getBuffer(minCapacity). + * If the length() was greater than minCapacity, then any contents after minCapacity + * may be lost. + * The buffer contents is not NUL-terminated by getBuffer(). + * If length()<getCapacity() then you can terminate it by writing a NUL + * at index length(). + * - You must call releaseBuffer(newLength) before and in order to + * return to normal UnicodeString operation. + * + * @param minCapacity the minimum number of UChars that are to be available + * in the buffer, starting at the returned pointer; + * default to the current string capacity if minCapacity==-1 + * @return a writable pointer to the internal string buffer, + * or 0 if an error occurs (nested calls, out of memory) + * + * @see releaseBuffer + * @see getTerminatedBuffer() + * @stable ICU 2.0 + */ + UChar *getBuffer(int32_t minCapacity); + + /** + * Release a read/write buffer on a UnicodeString object with an + * "open" getBuffer(minCapacity). + * This function must be called in a matched pair with getBuffer(minCapacity). + * releaseBuffer(newLength) must be called if and only if a getBuffer(minCapacity) is "open". + * + * It will set the string length to newLength, at most to the current capacity. + * If newLength==-1 then it will set the length according to the + * first NUL in the buffer, or to the capacity if there is no NUL. + * + * After calling releaseBuffer(newLength) the UnicodeString is back to normal operation. + * + * @param newLength the new length of the UnicodeString object; + * defaults to the current capacity if newLength is greater than that; + * if newLength==-1, it defaults to u_strlen(buffer) but not more than + * the current capacity of the string + * + * @see getBuffer(int32_t minCapacity) + * @stable ICU 2.0 + */ + void releaseBuffer(int32_t newLength=-1); + + /** + * Get a read-only pointer to the internal buffer. + * This can be called at any time on a valid UnicodeString. + * + * It returns 0 if the string is bogus, or + * during an "open" getBuffer(minCapacity). + * + * It can be called as many times as desired. + * The pointer that it returns will remain valid until the UnicodeString object is modified, + * at which time the pointer is semantically invalidated and must not be used any more. + * + * The capacity of the buffer can be determined with getCapacity(). + * The part after length() may or may not be initialized and valid, + * depending on the history of the UnicodeString object. + * + * The buffer contents is (probably) not NUL-terminated. + * You can check if it is with + * <code>(s.length()<s.getCapacity() && buffer[s.length()]==0)</code>. + * (See getTerminatedBuffer().) + * + * The buffer may reside in read-only memory. Its contents must not + * be modified. + * + * @return a read-only pointer to the internal string buffer, + * or 0 if the string is empty or bogus + * + * @see getBuffer(int32_t minCapacity) + * @see getTerminatedBuffer() + * @stable ICU 2.0 + */ + inline const UChar *getBuffer() const; + + /** + * Get a read-only pointer to the internal buffer, + * making sure that it is NUL-terminated. + * This can be called at any time on a valid UnicodeString. + * + * It returns 0 if the string is bogus, or + * during an "open" getBuffer(minCapacity), or if the buffer cannot + * be NUL-terminated (because memory allocation failed). + * + * It can be called as many times as desired. + * The pointer that it returns will remain valid until the UnicodeString object is modified, + * at which time the pointer is semantically invalidated and must not be used any more. + * + * The capacity of the buffer can be determined with getCapacity(). + * The part after length()+1 may or may not be initialized and valid, + * depending on the history of the UnicodeString object. + * + * The buffer contents is guaranteed to be NUL-terminated. + * getTerminatedBuffer() may reallocate the buffer if a terminating NUL + * is written. + * For this reason, this function is not const, unlike getBuffer(). + * Note that a UnicodeString may also contain NUL characters as part of its contents. + * + * The buffer may reside in read-only memory. Its contents must not + * be modified. + * + * @return a read-only pointer to the internal string buffer, + * or 0 if the string is empty or bogus + * + * @see getBuffer(int32_t minCapacity) + * @see getBuffer() + * @stable ICU 2.2 + */ + inline const UChar *getTerminatedBuffer(); + + //======================================== + // Constructors + //======================================== + + /** Construct an empty UnicodeString. + * @stable ICU 2.0 + */ + UnicodeString(); + + /** + * Construct a UnicodeString with capacity to hold <TT>capacity</TT> UChars + * @param capacity the number of UChars this UnicodeString should hold + * before a resize is necessary; if count is greater than 0 and count + * code points c take up more space than capacity, then capacity is adjusted + * accordingly. + * @param c is used to initially fill the string + * @param count specifies how many code points c are to be written in the + * string + * @stable ICU 2.0 + */ + UnicodeString(int32_t capacity, UChar32 c, int32_t count); + + /** + * Single UChar (code unit) constructor. + * @param ch the character to place in the UnicodeString + * @stable ICU 2.0 + */ + UnicodeString(UChar ch); + + /** + * Single UChar32 (code point) constructor. + * @param ch the character to place in the UnicodeString + * @stable ICU 2.0 + */ + UnicodeString(UChar32 ch); + + /** + * UChar* constructor. + * @param text The characters to place in the UnicodeString. <TT>text</TT> + * must be NULL (U+0000) terminated. + * @stable ICU 2.0 + */ + UnicodeString(const UChar *text); + + /** + * UChar* constructor. + * @param text The characters to place in the UnicodeString. + * @param textLength The number of Unicode characters in <TT>text</TT> + * to copy. + * @stable ICU 2.0 + */ + UnicodeString(const UChar *text, + int32_t textLength); + + /** + * Readonly-aliasing UChar* constructor. + * The text will be used for the UnicodeString object, but + * it will not be released when the UnicodeString is destroyed. + * This has copy-on-write semantics: + * When the string is modified, then the buffer is first copied into + * newly allocated memory. + * The aliased buffer is never modified. + * In an assignment to another UnicodeString, the text will be aliased again, + * so that both strings then alias the same readonly-text. + * + * @param isTerminated specifies if <code>text</code> is <code>NUL</code>-terminated. + * This must be true if <code>textLength==-1</code>. + * @param text The characters to alias for the UnicodeString. + * @param textLength The number of Unicode characters in <code>text</code> to alias. + * If -1, then this constructor will determine the length + * by calling <code>u_strlen()</code>. + * @stable ICU 2.0 + */ + UnicodeString(UBool isTerminated, + const UChar *text, + int32_t textLength); + + /** + * Writable-aliasing UChar* constructor. + * The text will be used for the UnicodeString object, but + * it will not be released when the UnicodeString is destroyed. + * This has write-through semantics: + * For as long as the capacity of the buffer is sufficient, write operations + * will directly affect the buffer. When more capacity is necessary, then + * a new buffer will be allocated and the contents copied as with regularly + * constructed strings. + * In an assignment to another UnicodeString, the buffer will be copied. + * The extract(UChar *dst) function detects whether the dst pointer is the same + * as the string buffer itself and will in this case not copy the contents. + * + * @param buffer The characters to alias for the UnicodeString. + * @param buffLength The number of Unicode characters in <code>buffer</code> to alias. + * @param buffCapacity The size of <code>buffer</code> in UChars. + * @stable ICU 2.0 + */ + UnicodeString(UChar *buffer, int32_t buffLength, int32_t buffCapacity); + +#if !UCONFIG_NO_CONVERSION + + /** + * char* constructor. + * @param codepageData an array of bytes, null-terminated + * @param codepage the encoding of <TT>codepageData</TT>. The special + * value 0 for <TT>codepage</TT> indicates that the text is in the + * platform's default codepage. + * + * If <code>codepage</code> is an empty string (<code>""</code>), + * then a simple conversion is performed on the codepage-invariant + * subset ("invariant characters") of the platform encoding. See utypes.h. + * Recommendation: For invariant-character strings use the constructor + * UnicodeString(const char *src, int32_t length, enum EInvariant inv) + * because it avoids object code dependencies of UnicodeString on + * the conversion code. + * + * @stable ICU 2.0 + */ + UnicodeString(const char *codepageData, + const char *codepage = 0); + + /** + * char* constructor. + * @param codepageData an array of bytes. + * @param dataLength The number of bytes in <TT>codepageData</TT>. + * @param codepage the encoding of <TT>codepageData</TT>. The special + * value 0 for <TT>codepage</TT> indicates that the text is in the + * platform's default codepage. + * If <code>codepage</code> is an empty string (<code>""</code>), + * then a simple conversion is performed on the codepage-invariant + * subset ("invariant characters") of the platform encoding. See utypes.h. + * Recommendation: For invariant-character strings use the constructor + * UnicodeString(const char *src, int32_t length, enum EInvariant inv) + * because it avoids object code dependencies of UnicodeString on + * the conversion code. + * + * @stable ICU 2.0 + */ + UnicodeString(const char *codepageData, + int32_t dataLength, + const char *codepage = 0); + + /** + * char * / UConverter constructor. + * This constructor uses an existing UConverter object to + * convert the codepage string to Unicode and construct a UnicodeString + * from that. + * + * The converter is reset at first. + * If the error code indicates a failure before this constructor is called, + * or if an error occurs during conversion or construction, + * then the string will be bogus. + * + * This function avoids the overhead of opening and closing a converter if + * multiple strings are constructed. + * + * @param src input codepage string + * @param srcLength length of the input string, can be -1 for NUL-terminated strings + * @param cnv converter object (ucnv_resetToUnicode() will be called), + * can be NULL for the default converter + * @param errorCode normal ICU error code + * @stable ICU 2.0 + */ + UnicodeString( + const char *src, int32_t srcLength, + UConverter *cnv, + UErrorCode &errorCode); + +#endif + + /** + * Constructs a Unicode string from an invariant-character char * string. + * About invariant characters see utypes.h. + * This constructor has no runtime dependency on conversion code and is + * therefore recommended over ones taking a charset name string + * (where the empty string "" indicates invariant-character conversion). + * + * Use the macro US_INV as the third, signature-distinguishing parameter. + * + * For example: + * \code + * void fn(const char *s) { + * UnicodeString ustr(s, -1, US_INV); + * // use ustr ... + * } + * \endcode + * + * @param src String using only invariant characters. + * @param length Length of src, or -1 if NUL-terminated. + * @param inv Signature-distinguishing paramater, use US_INV. + * + * @see US_INV + * @stable ICU 3.2 + */ + UnicodeString(const char *src, int32_t length, enum EInvariant inv); + + + /** + * Copy constructor. + * @param that The UnicodeString object to copy. + * @stable ICU 2.0 + */ + UnicodeString(const UnicodeString& that); + + /** + * 'Substring' constructor from tail of source string. + * @param src The UnicodeString object to copy. + * @param srcStart The offset into <tt>src</tt> at which to start copying. + * @stable ICU 2.2 + */ + UnicodeString(const UnicodeString& src, int32_t srcStart); + + /** + * 'Substring' constructor from subrange of source string. + * @param src The UnicodeString object to copy. + * @param srcStart The offset into <tt>src</tt> at which to start copying. + * @param srcLength The number of characters from <tt>src</tt> to copy. + * @stable ICU 2.2 + */ + UnicodeString(const UnicodeString& src, int32_t srcStart, int32_t srcLength); + + /** + * Clone this object, an instance of a subclass of Replaceable. + * Clones can be used concurrently in multiple threads. + * If a subclass does not implement clone(), or if an error occurs, + * then NULL is returned. + * The clone functions in all subclasses return a pointer to a Replaceable + * because some compilers do not support covariant (same-as-this) + * return types; cast to the appropriate subclass if necessary. + * The caller must delete the clone. + * + * @return a clone of this object + * + * @see Replaceable::clone + * @see getDynamicClassID + * @stable ICU 2.6 + */ + virtual Replaceable *clone() const; + + /** Destructor. + * @stable ICU 2.0 + */ + virtual ~UnicodeString(); + + + /* Miscellaneous operations */ + + /** + * Unescape a string of characters and return a string containing + * the result. The following escape sequences are recognized: + * + * \\uhhhh 4 hex digits; h in [0-9A-Fa-f] + * \\Uhhhhhhhh 8 hex digits + * \\xhh 1-2 hex digits + * \\ooo 1-3 octal digits; o in [0-7] + * \\cX control-X; X is masked with 0x1F + * + * as well as the standard ANSI C escapes: + * + * \\a => U+0007, \\b => U+0008, \\t => U+0009, \\n => U+000A, + * \\v => U+000B, \\f => U+000C, \\r => U+000D, \\e => U+001B, + * \\" => U+0022, \\' => U+0027, \\? => U+003F, \\\\ => U+005C + * + * Anything else following a backslash is generically escaped. For + * example, "[a\\-z]" returns "[a-z]". + * + * If an escape sequence is ill-formed, this method returns an empty + * string. An example of an ill-formed sequence is "\\u" followed by + * fewer than 4 hex digits. + * + * This function is similar to u_unescape() but not identical to it. + * The latter takes a source char*, so it does escape recognition + * and also invariant conversion. + * + * @return a string with backslash escapes interpreted, or an + * empty string on error. + * @see UnicodeString#unescapeAt() + * @see u_unescape() + * @see u_unescapeAt() + * @stable ICU 2.0 + */ + UnicodeString unescape() const; + + /** + * Unescape a single escape sequence and return the represented + * character. See unescape() for a listing of the recognized escape + * sequences. The character at offset-1 is assumed (without + * checking) to be a backslash. If the escape sequence is + * ill-formed, or the offset is out of range, (UChar32)0xFFFFFFFF is + * returned. + * + * @param offset an input output parameter. On input, it is the + * offset into this string where the escape sequence is located, + * after the initial backslash. On output, it is advanced after the + * last character parsed. On error, it is not advanced at all. + * @return the character represented by the escape sequence at + * offset, or (UChar32)0xFFFFFFFF on error. + * @see UnicodeString#unescape() + * @see u_unescape() + * @see u_unescapeAt() + * @stable ICU 2.0 + */ + UChar32 unescapeAt(int32_t &offset) const; + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.2 + */ + static UClassID U_EXPORT2 getStaticClassID(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.2 + */ + virtual UClassID getDynamicClassID() const; + + //======================================== + // Implementation methods + //======================================== + +protected: + /** + * Implement Replaceable::getLength() (see jitterbug 1027). + * @stable ICU 2.4 + */ + virtual int32_t getLength() const; + + /** + * The change in Replaceable to use virtual getCharAt() allows + * UnicodeString::charAt() to be inline again (see jitterbug 709). + * @stable ICU 2.4 + */ + virtual UChar getCharAt(int32_t offset) const; + + /** + * The change in Replaceable to use virtual getChar32At() allows + * UnicodeString::char32At() to be inline again (see jitterbug 709). + * @stable ICU 2.4 + */ + virtual UChar32 getChar32At(int32_t offset) const; + +private: + + inline int8_t + doCompare(int32_t start, + int32_t length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const; + + int8_t doCompare(int32_t start, + int32_t length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const; + + inline int8_t + doCompareCodePointOrder(int32_t start, + int32_t length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const; + + int8_t doCompareCodePointOrder(int32_t start, + int32_t length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const; + + inline int8_t + doCaseCompare(int32_t start, + int32_t length, + const UnicodeString &srcText, + int32_t srcStart, + int32_t srcLength, + uint32_t options) const; + + int8_t + doCaseCompare(int32_t start, + int32_t length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength, + uint32_t options) const; + + int32_t doIndexOf(UChar c, + int32_t start, + int32_t length) const; + + int32_t doIndexOf(UChar32 c, + int32_t start, + int32_t length) const; + + int32_t doLastIndexOf(UChar c, + int32_t start, + int32_t length) const; + + int32_t doLastIndexOf(UChar32 c, + int32_t start, + int32_t length) const; + + void doExtract(int32_t start, + int32_t length, + UChar *dst, + int32_t dstStart) const; + + inline void doExtract(int32_t start, + int32_t length, + UnicodeString& target) const; + + inline UChar doCharAt(int32_t offset) const; + + UnicodeString& doReplace(int32_t start, + int32_t length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength); + + UnicodeString& doReplace(int32_t start, + int32_t length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength); + + UnicodeString& doReverse(int32_t start, + int32_t length); + + // calculate hash code + int32_t doHashCode(void) const; + + // get pointer to start of array + // these do not check for kOpenGetBuffer, unlike the public getBuffer() function + inline UChar* getArrayStart(void); + inline const UChar* getArrayStart(void) const; + + // A UnicodeString object (not necessarily its current buffer) + // is writable unless it isBogus() or it has an "open" getBuffer(minCapacity). + inline UBool isWritable() const; + + // Is the current buffer writable? + inline UBool isBufferWritable() const; + + // None of the following does releaseArray(). + inline void setLength(int32_t len); // sets only fShortLength and fLength + inline void setToEmpty(); // sets fFlags=kShortString + inline void setToStackBuffer(int32_t len); // sets fFlags=kShortString + inline void setArray(UChar *array, int32_t len, int32_t capacity); // does not set fFlags + + // allocate the array; result may be fStackBuffer + // sets refCount to 1 if appropriate + // sets fArray, fCapacity, and fFlags + // returns boolean for success or failure + UBool allocate(int32_t capacity); + + // release the array if owned + void releaseArray(void); + + // turn a bogus string into an empty one + void unBogus(); + + // implements assigment operator, copy constructor, and fastCopyFrom() + UnicodeString ©From(const UnicodeString &src, UBool fastCopy=FALSE); + + // Pin start and limit to acceptable values. + inline void pinIndex(int32_t& start) const; + inline void pinIndices(int32_t& start, + int32_t& length) const; + +#if !UCONFIG_NO_CONVERSION + + /* Internal extract() using UConverter. */ + int32_t doExtract(int32_t start, int32_t length, + char *dest, int32_t destCapacity, + UConverter *cnv, + UErrorCode &errorCode) const; + + /* + * Real constructor for converting from codepage data. + * It assumes that it is called with !fRefCounted. + * + * If <code>codepage==0</code>, then the default converter + * is used for the platform encoding. + * If <code>codepage</code> is an empty string (<code>""</code>), + * then a simple conversion is performed on the codepage-invariant + * subset ("invariant characters") of the platform encoding. See utypes.h. + */ + void doCodepageCreate(const char *codepageData, + int32_t dataLength, + const char *codepage); + + /* + * Worker function for creating a UnicodeString from + * a codepage string using a UConverter. + */ + void + doCodepageCreate(const char *codepageData, + int32_t dataLength, + UConverter *converter, + UErrorCode &status); + +#endif + + /* + * This function is called when write access to the array + * is necessary. + * + * We need to make a copy of the array if + * the buffer is read-only, or + * the buffer is refCounted (shared), and refCount>1, or + * the buffer is too small. + * + * Return FALSE if memory could not be allocated. + */ + UBool cloneArrayIfNeeded(int32_t newCapacity = -1, + int32_t growCapacity = -1, + UBool doCopyArray = TRUE, + int32_t **pBufferToDelete = 0, + UBool forceClone = FALSE); + + // common function for case mappings + UnicodeString & + caseMap(BreakIterator *titleIter, + const char *locale, + uint32_t options, + int32_t toWhichCase); + + // ref counting + void addRef(void); + int32_t removeRef(void); + int32_t refCount(void) const; + + // constants + enum { + // Set the stack buffer size so that sizeof(UnicodeString) is a multiple of sizeof(pointer): + // 32-bit pointers: 4+1+1+13*2 = 32 bytes + // 64-bit pointers: 8+1+1+15*2 = 40 bytes + US_STACKBUF_SIZE= sizeof(void *)==4 ? 13 : 15, // Size of stack buffer for small strings + kInvalidUChar=0xffff, // invalid UChar index + kGrowSize=128, // grow size for this buffer + kInvalidHashCode=0, // invalid hash code + kEmptyHashCode=1, // hash code for empty string + + // bit flag values for fFlags + kIsBogus=1, // this string is bogus, i.e., not valid or NULL + kUsingStackBuffer=2,// fArray==fStackBuffer + kRefCounted=4, // there is a refCount field before the characters in fArray + kBufferIsReadonly=8,// do not write to this buffer + kOpenGetBuffer=16, // getBuffer(minCapacity) was called (is "open"), + // and releaseBuffer(newLength) must be called + + // combined values for convenience + kShortString=kUsingStackBuffer, + kLongString=kRefCounted, + kReadonlyAlias=kBufferIsReadonly, + kWritableAlias=0 + }; + + friend class StringThreadTest; + + union StackBufferOrFields; // forward declaration necessary before friend declaration + friend union StackBufferOrFields; // make US_STACKBUF_SIZE visible inside fUnion + + /* + * The following are all the class fields that are stored + * in each UnicodeString object. + * Note that UnicodeString has virtual functions, + * therefore there is an implicit vtable pointer + * as the first real field. + * The fields should be aligned such that no padding is + * necessary, mostly by having larger types first. + * On 32-bit machines, the size should be 32 bytes, + * on 64-bit machines (8-byte pointers), it should be 40 bytes. + */ + // (implicit) *vtable; + int8_t fShortLength; // 0..127: length <0: real length is in fUnion.fFields.fLength + uint8_t fFlags; // bit flags: see constants above + union StackBufferOrFields { + // fStackBuffer is used iff (fFlags&kUsingStackBuffer) + // else fFields is used + UChar fStackBuffer [US_STACKBUF_SIZE]; // buffer for small strings + struct { + uint16_t fPadding; // align the following field at 8B (32b pointers) or 12B (64b) + int32_t fLength; // number of characters in fArray if >127; else undefined + UChar *fArray; // the Unicode data (aligned at 12B (32b pointers) or 16B (64b)) + int32_t fCapacity; // sizeof fArray + } fFields; + } fUnion; +}; + +/** + * Create a new UnicodeString with the concatenation of two others. + * + * @param s1 The first string to be copied to the new one. + * @param s2 The second string to be copied to the new one, after s1. + * @return UnicodeString(s1).append(s2) + * @stable ICU 2.8 + */ +U_COMMON_API UnicodeString U_EXPORT2 +operator+ (const UnicodeString &s1, const UnicodeString &s2); + +//======================================== +// Inline members +//======================================== + +//======================================== +// Privates +//======================================== + +inline void +UnicodeString::pinIndex(int32_t& start) const +{ + // pin index + if(start < 0) { + start = 0; + } else if(start > length()) { + start = length(); + } +} + +inline void +UnicodeString::pinIndices(int32_t& start, + int32_t& _length) const +{ + // pin indices + int32_t len = length(); + if(start < 0) { + start = 0; + } else if(start > len) { + start = len; + } + if(_length < 0) { + _length = 0; + } else if(_length > (len - start)) { + _length = (len - start); + } +} + +inline UChar* +UnicodeString::getArrayStart() +{ return (fFlags&kUsingStackBuffer) ? fUnion.fStackBuffer : fUnion.fFields.fArray; } + +inline const UChar* +UnicodeString::getArrayStart() const +{ return (fFlags&kUsingStackBuffer) ? fUnion.fStackBuffer : fUnion.fFields.fArray; } + +//======================================== +// Read-only implementation methods +//======================================== +inline int32_t +UnicodeString::length() const +{ return fShortLength>=0 ? fShortLength : fUnion.fFields.fLength; } + +inline int32_t +UnicodeString::getCapacity() const +{ return (fFlags&kUsingStackBuffer) ? US_STACKBUF_SIZE : fUnion.fFields.fCapacity; } + +inline int32_t +UnicodeString::hashCode() const +{ return doHashCode(); } + +inline UBool +UnicodeString::isBogus() const +{ return (UBool)(fFlags & kIsBogus); } + +inline UBool +UnicodeString::isWritable() const +{ return (UBool)!(fFlags&(kOpenGetBuffer|kIsBogus)); } + +inline UBool +UnicodeString::isBufferWritable() const +{ + return (UBool)( + !(fFlags&(kOpenGetBuffer|kIsBogus|kBufferIsReadonly)) && + (!(fFlags&kRefCounted) || refCount()==1)); +} + +inline const UChar * +UnicodeString::getBuffer() const { + if(fFlags&(kIsBogus|kOpenGetBuffer)) { + return 0; + } else if(fFlags&kUsingStackBuffer) { + return fUnion.fStackBuffer; + } else { + return fUnion.fFields.fArray; + } +} + +//======================================== +// Read-only alias methods +//======================================== +inline int8_t +UnicodeString::doCompare(int32_t start, + int32_t thisLength, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const +{ + if(srcText.isBogus()) { + return (int8_t)!isBogus(); // 0 if both are bogus, 1 otherwise + } else { + srcText.pinIndices(srcStart, srcLength); + return doCompare(start, thisLength, srcText.getArrayStart(), srcStart, srcLength); + } +} + +inline UBool +UnicodeString::operator== (const UnicodeString& text) const +{ + if(isBogus()) { + return text.isBogus(); + } else { + int32_t len = length(), textLength = text.length(); + return + !text.isBogus() && + len == textLength && + doCompare(0, len, text, 0, textLength) == 0; + } +} + +inline UBool +UnicodeString::operator!= (const UnicodeString& text) const +{ return (! operator==(text)); } + +inline UBool +UnicodeString::operator> (const UnicodeString& text) const +{ return doCompare(0, length(), text, 0, text.length()) == 1; } + +inline UBool +UnicodeString::operator< (const UnicodeString& text) const +{ return doCompare(0, length(), text, 0, text.length()) == -1; } + +inline UBool +UnicodeString::operator>= (const UnicodeString& text) const +{ return doCompare(0, length(), text, 0, text.length()) != -1; } + +inline UBool +UnicodeString::operator<= (const UnicodeString& text) const +{ return doCompare(0, length(), text, 0, text.length()) != 1; } + +inline int8_t +UnicodeString::compare(const UnicodeString& text) const +{ return doCompare(0, length(), text, 0, text.length()); } + +inline int8_t +UnicodeString::compare(int32_t start, + int32_t _length, + const UnicodeString& srcText) const +{ return doCompare(start, _length, srcText, 0, srcText.length()); } + +inline int8_t +UnicodeString::compare(const UChar *srcChars, + int32_t srcLength) const +{ return doCompare(0, length(), srcChars, 0, srcLength); } + +inline int8_t +UnicodeString::compare(int32_t start, + int32_t _length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const +{ return doCompare(start, _length, srcText, srcStart, srcLength); } + +inline int8_t +UnicodeString::compare(int32_t start, + int32_t _length, + const UChar *srcChars) const +{ return doCompare(start, _length, srcChars, 0, _length); } + +inline int8_t +UnicodeString::compare(int32_t start, + int32_t _length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const +{ return doCompare(start, _length, srcChars, srcStart, srcLength); } + +inline int8_t +UnicodeString::compareBetween(int32_t start, + int32_t limit, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLimit) const +{ return doCompare(start, limit - start, + srcText, srcStart, srcLimit - srcStart); } + +inline int8_t +UnicodeString::doCompareCodePointOrder(int32_t start, + int32_t thisLength, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const +{ + if(srcText.isBogus()) { + return (int8_t)!isBogus(); // 0 if both are bogus, 1 otherwise + } else { + srcText.pinIndices(srcStart, srcLength); + return doCompareCodePointOrder(start, thisLength, srcText.getArrayStart(), srcStart, srcLength); + } +} + +inline int8_t +UnicodeString::compareCodePointOrder(const UnicodeString& text) const +{ return doCompareCodePointOrder(0, length(), text, 0, text.length()); } + +inline int8_t +UnicodeString::compareCodePointOrder(int32_t start, + int32_t _length, + const UnicodeString& srcText) const +{ return doCompareCodePointOrder(start, _length, srcText, 0, srcText.length()); } + +inline int8_t +UnicodeString::compareCodePointOrder(const UChar *srcChars, + int32_t srcLength) const +{ return doCompareCodePointOrder(0, length(), srcChars, 0, srcLength); } + +inline int8_t +UnicodeString::compareCodePointOrder(int32_t start, + int32_t _length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const +{ return doCompareCodePointOrder(start, _length, srcText, srcStart, srcLength); } + +inline int8_t +UnicodeString::compareCodePointOrder(int32_t start, + int32_t _length, + const UChar *srcChars) const +{ return doCompareCodePointOrder(start, _length, srcChars, 0, _length); } + +inline int8_t +UnicodeString::compareCodePointOrder(int32_t start, + int32_t _length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const +{ return doCompareCodePointOrder(start, _length, srcChars, srcStart, srcLength); } + +inline int8_t +UnicodeString::compareCodePointOrderBetween(int32_t start, + int32_t limit, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLimit) const +{ return doCompareCodePointOrder(start, limit - start, + srcText, srcStart, srcLimit - srcStart); } + +inline int8_t +UnicodeString::doCaseCompare(int32_t start, + int32_t thisLength, + const UnicodeString &srcText, + int32_t srcStart, + int32_t srcLength, + uint32_t options) const +{ + if(srcText.isBogus()) { + return (int8_t)!isBogus(); // 0 if both are bogus, 1 otherwise + } else { + srcText.pinIndices(srcStart, srcLength); + return doCaseCompare(start, thisLength, srcText.getArrayStart(), srcStart, srcLength, options); + } +} + +inline int8_t +UnicodeString::caseCompare(const UnicodeString &text, uint32_t options) const { + return doCaseCompare(0, length(), text, 0, text.length(), options); +} + +inline int8_t +UnicodeString::caseCompare(int32_t start, + int32_t _length, + const UnicodeString &srcText, + uint32_t options) const { + return doCaseCompare(start, _length, srcText, 0, srcText.length(), options); +} + +inline int8_t +UnicodeString::caseCompare(const UChar *srcChars, + int32_t srcLength, + uint32_t options) const { + return doCaseCompare(0, length(), srcChars, 0, srcLength, options); +} + +inline int8_t +UnicodeString::caseCompare(int32_t start, + int32_t _length, + const UnicodeString &srcText, + int32_t srcStart, + int32_t srcLength, + uint32_t options) const { + return doCaseCompare(start, _length, srcText, srcStart, srcLength, options); +} + +inline int8_t +UnicodeString::caseCompare(int32_t start, + int32_t _length, + const UChar *srcChars, + uint32_t options) const { + return doCaseCompare(start, _length, srcChars, 0, _length, options); +} + +inline int8_t +UnicodeString::caseCompare(int32_t start, + int32_t _length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength, + uint32_t options) const { + return doCaseCompare(start, _length, srcChars, srcStart, srcLength, options); +} + +inline int8_t +UnicodeString::caseCompareBetween(int32_t start, + int32_t limit, + const UnicodeString &srcText, + int32_t srcStart, + int32_t srcLimit, + uint32_t options) const { + return doCaseCompare(start, limit - start, srcText, srcStart, srcLimit - srcStart, options); +} + +inline int32_t +UnicodeString::indexOf(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength, + int32_t start, + int32_t _length) const +{ + if(!srcText.isBogus()) { + srcText.pinIndices(srcStart, srcLength); + if(srcLength > 0) { + return indexOf(srcText.getArrayStart(), srcStart, srcLength, start, _length); + } + } + return -1; +} + +inline int32_t +UnicodeString::indexOf(const UnicodeString& text) const +{ return indexOf(text, 0, text.length(), 0, length()); } + +inline int32_t +UnicodeString::indexOf(const UnicodeString& text, + int32_t start) const { + pinIndex(start); + return indexOf(text, 0, text.length(), start, length() - start); +} + +inline int32_t +UnicodeString::indexOf(const UnicodeString& text, + int32_t start, + int32_t _length) const +{ return indexOf(text, 0, text.length(), start, _length); } + +inline int32_t +UnicodeString::indexOf(const UChar *srcChars, + int32_t srcLength, + int32_t start) const { + pinIndex(start); + return indexOf(srcChars, 0, srcLength, start, length() - start); +} + +inline int32_t +UnicodeString::indexOf(const UChar *srcChars, + int32_t srcLength, + int32_t start, + int32_t _length) const +{ return indexOf(srcChars, 0, srcLength, start, _length); } + +inline int32_t +UnicodeString::indexOf(UChar c, + int32_t start, + int32_t _length) const +{ return doIndexOf(c, start, _length); } + +inline int32_t +UnicodeString::indexOf(UChar32 c, + int32_t start, + int32_t _length) const +{ return doIndexOf(c, start, _length); } + +inline int32_t +UnicodeString::indexOf(UChar c) const +{ return doIndexOf(c, 0, length()); } + +inline int32_t +UnicodeString::indexOf(UChar32 c) const +{ return indexOf(c, 0, length()); } + +inline int32_t +UnicodeString::indexOf(UChar c, + int32_t start) const { + pinIndex(start); + return doIndexOf(c, start, length() - start); +} + +inline int32_t +UnicodeString::indexOf(UChar32 c, + int32_t start) const { + pinIndex(start); + return indexOf(c, start, length() - start); +} + +inline int32_t +UnicodeString::lastIndexOf(const UChar *srcChars, + int32_t srcLength, + int32_t start, + int32_t _length) const +{ return lastIndexOf(srcChars, 0, srcLength, start, _length); } + +inline int32_t +UnicodeString::lastIndexOf(const UChar *srcChars, + int32_t srcLength, + int32_t start) const { + pinIndex(start); + return lastIndexOf(srcChars, 0, srcLength, start, length() - start); +} + +inline int32_t +UnicodeString::lastIndexOf(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength, + int32_t start, + int32_t _length) const +{ + if(!srcText.isBogus()) { + srcText.pinIndices(srcStart, srcLength); + if(srcLength > 0) { + return lastIndexOf(srcText.getArrayStart(), srcStart, srcLength, start, _length); + } + } + return -1; +} + +inline int32_t +UnicodeString::lastIndexOf(const UnicodeString& text, + int32_t start, + int32_t _length) const +{ return lastIndexOf(text, 0, text.length(), start, _length); } + +inline int32_t +UnicodeString::lastIndexOf(const UnicodeString& text, + int32_t start) const { + pinIndex(start); + return lastIndexOf(text, 0, text.length(), start, length() - start); +} + +inline int32_t +UnicodeString::lastIndexOf(const UnicodeString& text) const +{ return lastIndexOf(text, 0, text.length(), 0, length()); } + +inline int32_t +UnicodeString::lastIndexOf(UChar c, + int32_t start, + int32_t _length) const +{ return doLastIndexOf(c, start, _length); } + +inline int32_t +UnicodeString::lastIndexOf(UChar32 c, + int32_t start, + int32_t _length) const { + return doLastIndexOf(c, start, _length); +} + +inline int32_t +UnicodeString::lastIndexOf(UChar c) const +{ return doLastIndexOf(c, 0, length()); } + +inline int32_t +UnicodeString::lastIndexOf(UChar32 c) const { + return lastIndexOf(c, 0, length()); +} + +inline int32_t +UnicodeString::lastIndexOf(UChar c, + int32_t start) const { + pinIndex(start); + return doLastIndexOf(c, start, length() - start); +} + +inline int32_t +UnicodeString::lastIndexOf(UChar32 c, + int32_t start) const { + pinIndex(start); + return lastIndexOf(c, start, length() - start); +} + +inline UBool +UnicodeString::startsWith(const UnicodeString& text) const +{ return compare(0, text.length(), text, 0, text.length()) == 0; } + +inline UBool +UnicodeString::startsWith(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const +{ return doCompare(0, srcLength, srcText, srcStart, srcLength) == 0; } + +inline UBool +UnicodeString::startsWith(const UChar *srcChars, + int32_t srcLength) const +{ return doCompare(0, srcLength, srcChars, 0, srcLength) == 0; } + +inline UBool +UnicodeString::startsWith(const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const +{ return doCompare(0, srcLength, srcChars, srcStart, srcLength) == 0;} + +inline UBool +UnicodeString::endsWith(const UnicodeString& text) const +{ return doCompare(length() - text.length(), text.length(), + text, 0, text.length()) == 0; } + +inline UBool +UnicodeString::endsWith(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) const { + srcText.pinIndices(srcStart, srcLength); + return doCompare(length() - srcLength, srcLength, + srcText, srcStart, srcLength) == 0; +} + +inline UBool +UnicodeString::endsWith(const UChar *srcChars, + int32_t srcLength) const { + if(srcLength < 0) { + srcLength = u_strlen(srcChars); + } + return doCompare(length() - srcLength, srcLength, + srcChars, 0, srcLength) == 0; +} + +inline UBool +UnicodeString::endsWith(const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) const { + if(srcLength < 0) { + srcLength = u_strlen(srcChars + srcStart); + } + return doCompare(length() - srcLength, srcLength, + srcChars, srcStart, srcLength) == 0; +} + +//======================================== +// replace +//======================================== +inline UnicodeString& +UnicodeString::replace(int32_t start, + int32_t _length, + const UnicodeString& srcText) +{ return doReplace(start, _length, srcText, 0, srcText.length()); } + +inline UnicodeString& +UnicodeString::replace(int32_t start, + int32_t _length, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) +{ return doReplace(start, _length, srcText, srcStart, srcLength); } + +inline UnicodeString& +UnicodeString::replace(int32_t start, + int32_t _length, + const UChar *srcChars, + int32_t srcLength) +{ return doReplace(start, _length, srcChars, 0, srcLength); } + +inline UnicodeString& +UnicodeString::replace(int32_t start, + int32_t _length, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) +{ return doReplace(start, _length, srcChars, srcStart, srcLength); } + +inline UnicodeString& +UnicodeString::replace(int32_t start, + int32_t _length, + UChar srcChar) +{ return doReplace(start, _length, &srcChar, 0, 1); } + +inline UnicodeString& +UnicodeString::replace(int32_t start, + int32_t _length, + UChar32 srcChar) { + UChar buffer[U16_MAX_LENGTH]; + int32_t count = 0; + UBool isError = FALSE; + U16_APPEND(buffer, count, U16_MAX_LENGTH, srcChar, isError); + return doReplace(start, _length, buffer, 0, count); +} + +inline UnicodeString& +UnicodeString::replaceBetween(int32_t start, + int32_t limit, + const UnicodeString& srcText) +{ return doReplace(start, limit - start, srcText, 0, srcText.length()); } + +inline UnicodeString& +UnicodeString::replaceBetween(int32_t start, + int32_t limit, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLimit) +{ return doReplace(start, limit - start, srcText, srcStart, srcLimit - srcStart); } + +inline UnicodeString& +UnicodeString::findAndReplace(const UnicodeString& oldText, + const UnicodeString& newText) +{ return findAndReplace(0, length(), oldText, 0, oldText.length(), + newText, 0, newText.length()); } + +inline UnicodeString& +UnicodeString::findAndReplace(int32_t start, + int32_t _length, + const UnicodeString& oldText, + const UnicodeString& newText) +{ return findAndReplace(start, _length, oldText, 0, oldText.length(), + newText, 0, newText.length()); } + +// ============================ +// extract +// ============================ +inline void +UnicodeString::doExtract(int32_t start, + int32_t _length, + UnicodeString& target) const +{ target.replace(0, target.length(), *this, start, _length); } + +inline void +UnicodeString::extract(int32_t start, + int32_t _length, + UChar *target, + int32_t targetStart) const +{ doExtract(start, _length, target, targetStart); } + +inline void +UnicodeString::extract(int32_t start, + int32_t _length, + UnicodeString& target) const +{ doExtract(start, _length, target); } + +#if !UCONFIG_NO_CONVERSION + +inline int32_t +UnicodeString::extract(int32_t start, + int32_t _length, + char *dst, + const char *codepage) const + +{ + // This dstSize value will be checked explicitly + return extract(start, _length, dst, dst!=0 ? 0xffffffff : 0, codepage); +} + +#endif + +inline void +UnicodeString::extractBetween(int32_t start, + int32_t limit, + UChar *dst, + int32_t dstStart) const { + pinIndex(start); + pinIndex(limit); + doExtract(start, limit - start, dst, dstStart); +} + +inline UChar +UnicodeString::doCharAt(int32_t offset) const +{ + if((uint32_t)offset < (uint32_t)length()) { + return getArrayStart()[offset]; + } else { + return kInvalidUChar; + } +} + +inline UChar +UnicodeString::charAt(int32_t offset) const +{ return doCharAt(offset); } + +inline UChar +UnicodeString::operator[] (int32_t offset) const +{ return doCharAt(offset); } + +inline UChar32 +UnicodeString::char32At(int32_t offset) const +{ + int32_t len = length(); + if((uint32_t)offset < (uint32_t)len) { + const UChar *array = getArrayStart(); + UChar32 c; + U16_GET(array, 0, offset, len, c); + return c; + } else { + return kInvalidUChar; + } +} + +inline int32_t +UnicodeString::getChar32Start(int32_t offset) const { + if((uint32_t)offset < (uint32_t)length()) { + const UChar *array = getArrayStart(); + U16_SET_CP_START(array, 0, offset); + return offset; + } else { + return 0; + } +} + +inline int32_t +UnicodeString::getChar32Limit(int32_t offset) const { + int32_t len = length(); + if((uint32_t)offset < (uint32_t)len) { + const UChar *array = getArrayStart(); + U16_SET_CP_LIMIT(array, 0, offset, len); + return offset; + } else { + return len; + } +} + +inline UBool +UnicodeString::isEmpty() const { + return fShortLength == 0; +} + +//======================================== +// Write implementation methods +//======================================== +inline void +UnicodeString::setLength(int32_t len) { + if(len <= 127) { + fShortLength = (int8_t)len; + } else { + fShortLength = (int8_t)-1; + fUnion.fFields.fLength = len; + } +} + +inline void +UnicodeString::setToEmpty() { + fShortLength = 0; + fFlags = kShortString; +} + +inline void +UnicodeString::setToStackBuffer(int32_t len) { + fShortLength = (int8_t)len; + fFlags = kShortString; +} + +inline void +UnicodeString::setArray(UChar *array, int32_t len, int32_t capacity) { + setLength(len); + fUnion.fFields.fArray = array; + fUnion.fFields.fCapacity = capacity; +} + +inline const UChar * +UnicodeString::getTerminatedBuffer() { + if(!isWritable()) { + return 0; + } else { + UChar *array = getArrayStart(); + int32_t len = length(); + if(len < getCapacity() && array[len] == 0) { + return array; + } else if(cloneArrayIfNeeded(len+1)) { + array = getArrayStart(); + array[len] = 0; + return array; + } else { + return 0; + } + } +} + +inline UnicodeString& +UnicodeString::operator= (UChar ch) +{ return doReplace(0, length(), &ch, 0, 1); } + +inline UnicodeString& +UnicodeString::operator= (UChar32 ch) +{ return replace(0, length(), ch); } + +inline UnicodeString& +UnicodeString::setTo(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) +{ + unBogus(); + return doReplace(0, length(), srcText, srcStart, srcLength); +} + +inline UnicodeString& +UnicodeString::setTo(const UnicodeString& srcText, + int32_t srcStart) +{ + unBogus(); + srcText.pinIndex(srcStart); + return doReplace(0, length(), srcText, srcStart, srcText.length() - srcStart); +} + +inline UnicodeString& +UnicodeString::setTo(const UnicodeString& srcText) +{ + unBogus(); + return doReplace(0, length(), srcText, 0, srcText.length()); +} + +inline UnicodeString& +UnicodeString::setTo(const UChar *srcChars, + int32_t srcLength) +{ + unBogus(); + return doReplace(0, length(), srcChars, 0, srcLength); +} + +inline UnicodeString& +UnicodeString::setTo(UChar srcChar) +{ + unBogus(); + return doReplace(0, length(), &srcChar, 0, 1); +} + +inline UnicodeString& +UnicodeString::setTo(UChar32 srcChar) +{ + unBogus(); + return replace(0, length(), srcChar); +} + +inline UnicodeString& +UnicodeString::append(const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) +{ return doReplace(length(), 0, srcText, srcStart, srcLength); } + +inline UnicodeString& +UnicodeString::append(const UnicodeString& srcText) +{ return doReplace(length(), 0, srcText, 0, srcText.length()); } + +inline UnicodeString& +UnicodeString::append(const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) +{ return doReplace(length(), 0, srcChars, srcStart, srcLength); } + +inline UnicodeString& +UnicodeString::append(const UChar *srcChars, + int32_t srcLength) +{ return doReplace(length(), 0, srcChars, 0, srcLength); } + +inline UnicodeString& +UnicodeString::append(UChar srcChar) +{ return doReplace(length(), 0, &srcChar, 0, 1); } + +inline UnicodeString& +UnicodeString::append(UChar32 srcChar) { + UChar buffer[U16_MAX_LENGTH]; + int32_t _length = 0; + UBool isError = FALSE; + U16_APPEND(buffer, _length, U16_MAX_LENGTH, srcChar, isError); + return doReplace(length(), 0, buffer, 0, _length); +} + +inline UnicodeString& +UnicodeString::operator+= (UChar ch) +{ return doReplace(length(), 0, &ch, 0, 1); } + +inline UnicodeString& +UnicodeString::operator+= (UChar32 ch) { + return append(ch); +} + +inline UnicodeString& +UnicodeString::operator+= (const UnicodeString& srcText) +{ return doReplace(length(), 0, srcText, 0, srcText.length()); } + +inline UnicodeString& +UnicodeString::insert(int32_t start, + const UnicodeString& srcText, + int32_t srcStart, + int32_t srcLength) +{ return doReplace(start, 0, srcText, srcStart, srcLength); } + +inline UnicodeString& +UnicodeString::insert(int32_t start, + const UnicodeString& srcText) +{ return doReplace(start, 0, srcText, 0, srcText.length()); } + +inline UnicodeString& +UnicodeString::insert(int32_t start, + const UChar *srcChars, + int32_t srcStart, + int32_t srcLength) +{ return doReplace(start, 0, srcChars, srcStart, srcLength); } + +inline UnicodeString& +UnicodeString::insert(int32_t start, + const UChar *srcChars, + int32_t srcLength) +{ return doReplace(start, 0, srcChars, 0, srcLength); } + +inline UnicodeString& +UnicodeString::insert(int32_t start, + UChar srcChar) +{ return doReplace(start, 0, &srcChar, 0, 1); } + +inline UnicodeString& +UnicodeString::insert(int32_t start, + UChar32 srcChar) +{ return replace(start, 0, srcChar); } + + +inline UnicodeString& +UnicodeString::remove() +{ + // remove() of a bogus string makes the string empty and non-bogus + if(isBogus()) { + unBogus(); + } else { + setLength(0); + } + return *this; +} + +inline UnicodeString& +UnicodeString::remove(int32_t start, + int32_t _length) +{ + if(start <= 0 && _length == INT32_MAX) { + // remove(guaranteed everything) of a bogus string makes the string empty and non-bogus + return remove(); + } + return doReplace(start, _length, NULL, 0, 0); +} + +inline UnicodeString& +UnicodeString::removeBetween(int32_t start, + int32_t limit) +{ return doReplace(start, limit - start, NULL, 0, 0); } + +inline UBool +UnicodeString::truncate(int32_t targetLength) +{ + if(isBogus() && targetLength == 0) { + // truncate(0) of a bogus string makes the string empty and non-bogus + unBogus(); + return FALSE; + } else if((uint32_t)targetLength < (uint32_t)length()) { + setLength(targetLength); + return TRUE; + } else { + return FALSE; + } +} + +inline UnicodeString& +UnicodeString::reverse() +{ return doReverse(0, length()); } + +inline UnicodeString& +UnicodeString::reverse(int32_t start, + int32_t _length) +{ return doReverse(start, _length); } + +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/unorm.h b/utils/openttd/unicode/unorm.h new file mode 100644 index 00000000000..c22b808aa57 --- /dev/null +++ b/utils/openttd/unicode/unorm.h @@ -0,0 +1,576 @@ +/* +******************************************************************************* +* Copyright (c) 1996-2007, International Business Machines Corporation +* and others. All Rights Reserved. +******************************************************************************* +* File unorm.h +* +* Created by: Vladimir Weinstein 12052000 +* +* Modification history : +* +* Date Name Description +* 02/01/01 synwee Added normalization quickcheck enum and method. +*/ +#ifndef UNORM_H +#define UNORM_H + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_NORMALIZATION + +#include "unicode/uiter.h" + +/** + * \file + * \brief C API: Unicode Normalization + * + * <h2>Unicode normalization API</h2> + * + * <code>unorm_normalize</code> transforms Unicode text into an equivalent composed or + * decomposed form, allowing for easier sorting and searching of text. + * <code>unorm_normalize</code> supports the standard normalization forms described in + * <a href="http://www.unicode.org/unicode/reports/tr15/" target="unicode"> + * Unicode Standard Annex #15: Unicode Normalization Forms</a>. + * + * Characters with accents or other adornments can be encoded in + * several different ways in Unicode. For example, take the character A-acute. + * In Unicode, this can be encoded as a single character (the + * "composed" form): + * + * \code + * 00C1 LATIN CAPITAL LETTER A WITH ACUTE + * \endcode + * + * or as two separate characters (the "decomposed" form): + * + * \code + * 0041 LATIN CAPITAL LETTER A + * 0301 COMBINING ACUTE ACCENT + * \endcode + * + * To a user of your program, however, both of these sequences should be + * treated as the same "user-level" character "A with acute accent". When you are searching or + * comparing text, you must ensure that these two sequences are treated + * equivalently. In addition, you must handle characters with more than one + * accent. Sometimes the order of a character's combining accents is + * significant, while in other cases accent sequences in different orders are + * really equivalent. + * + * Similarly, the string "ffi" can be encoded as three separate letters: + * + * \code + * 0066 LATIN SMALL LETTER F + * 0066 LATIN SMALL LETTER F + * 0069 LATIN SMALL LETTER I + * \endcode + * + * or as the single character + * + * \code + * FB03 LATIN SMALL LIGATURE FFI + * \endcode + * + * The ffi ligature is not a distinct semantic character, and strictly speaking + * it shouldn't be in Unicode at all, but it was included for compatibility + * with existing character sets that already provided it. The Unicode standard + * identifies such characters by giving them "compatibility" decompositions + * into the corresponding semantic characters. When sorting and searching, you + * will often want to use these mappings. + * + * <code>unorm_normalize</code> helps solve these problems by transforming text into the + * canonical composed and decomposed forms as shown in the first example above. + * In addition, you can have it perform compatibility decompositions so that + * you can treat compatibility characters the same as their equivalents. + * Finally, <code>unorm_normalize</code> rearranges accents into the proper canonical + * order, so that you do not have to worry about accent rearrangement on your + * own. + * + * Form FCD, "Fast C or D", is also designed for collation. + * It allows to work on strings that are not necessarily normalized + * with an algorithm (like in collation) that works under "canonical closure", i.e., it treats precomposed + * characters and their decomposed equivalents the same. + * + * It is not a normalization form because it does not provide for uniqueness of representation. Multiple strings + * may be canonically equivalent (their NFDs are identical) and may all conform to FCD without being identical + * themselves. + * + * The form is defined such that the "raw decomposition", the recursive canonical decomposition of each character, + * results in a string that is canonically ordered. This means that precomposed characters are allowed for as long + * as their decompositions do not need canonical reordering. + * + * Its advantage for a process like collation is that all NFD and most NFC texts - and many unnormalized texts - + * already conform to FCD and do not need to be normalized (NFD) for such a process. The FCD quick check will + * return UNORM_YES for most strings in practice. + * + * unorm_normalize(UNORM_FCD) may be implemented with UNORM_NFD. + * + * For more details on FCD see the collation design document: + * http://source.icu-project.org/repos/icu/icuhtml/trunk/design/collation/ICU_collation_design.htm + * + * ICU collation performs either NFD or FCD normalization automatically if normalization + * is turned on for the collator object. + * Beyond collation and string search, normalized strings may be useful for string equivalence comparisons, + * transliteration/transcription, unique representations, etc. + * + * The W3C generally recommends to exchange texts in NFC. + * Note also that most legacy character encodings use only precomposed forms and often do not + * encode any combining marks by themselves. For conversion to such character encodings the + * Unicode text needs to be normalized to NFC. + * For more usage examples, see the Unicode Standard Annex. + */ + +/** + * Constants for normalization modes. + * @stable ICU 2.0 + */ +typedef enum { + /** No decomposition/composition. @stable ICU 2.0 */ + UNORM_NONE = 1, + /** Canonical decomposition. @stable ICU 2.0 */ + UNORM_NFD = 2, + /** Compatibility decomposition. @stable ICU 2.0 */ + UNORM_NFKD = 3, + /** Canonical decomposition followed by canonical composition. @stable ICU 2.0 */ + UNORM_NFC = 4, + /** Default normalization. @stable ICU 2.0 */ + UNORM_DEFAULT = UNORM_NFC, + /** Compatibility decomposition followed by canonical composition. @stable ICU 2.0 */ + UNORM_NFKC =5, + /** "Fast C or D" form. @stable ICU 2.0 */ + UNORM_FCD = 6, + + /** One more than the highest normalization mode constant. @stable ICU 2.0 */ + UNORM_MODE_COUNT +} UNormalizationMode; + +/** + * Constants for options flags for normalization. + * Use 0 for default options, + * including normalization according to the Unicode version + * that is currently supported by ICU (see u_getUnicodeVersion). + * @stable ICU 2.6 + */ +enum { + /** + * Options bit set value to select Unicode 3.2 normalization + * (except NormalizationCorrections). + * At most one Unicode version can be selected at a time. + * @stable ICU 2.6 + */ + UNORM_UNICODE_3_2=0x20 +}; + +/** + * Lowest-order bit number of unorm_compare() options bits corresponding to + * normalization options bits. + * + * The options parameter for unorm_compare() uses most bits for + * itself and for various comparison and folding flags. + * The most significant bits, however, are shifted down and passed on + * to the normalization implementation. + * (That is, from unorm_compare(..., options, ...), + * options>>UNORM_COMPARE_NORM_OPTIONS_SHIFT will be passed on to the + * internal normalization functions.) + * + * @see unorm_compare + * @stable ICU 2.6 + */ +#define UNORM_COMPARE_NORM_OPTIONS_SHIFT 20 + +/** + * Normalize a string. + * The string will be normalized according the specified normalization mode + * and options. + * The source and result buffers must not be the same, nor overlap. + * + * @param source The string to normalize. + * @param sourceLength The length of source, or -1 if NUL-terminated. + * @param mode The normalization mode; one of UNORM_NONE, + * UNORM_NFD, UNORM_NFC, UNORM_NFKC, UNORM_NFKD, UNORM_DEFAULT. + * @param options The normalization options, ORed together (0 for no options). + * @param result A pointer to a buffer to receive the result string. + * The result string is NUL-terminated if possible. + * @param resultLength The maximum size of result. + * @param status A pointer to a UErrorCode to receive any errors. + * @return The total buffer size needed; if greater than resultLength, + * the output was truncated, and the error code is set to U_BUFFER_OVERFLOW_ERROR. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +unorm_normalize(const UChar *source, int32_t sourceLength, + UNormalizationMode mode, int32_t options, + UChar *result, int32_t resultLength, + UErrorCode *status); +#endif +/** + * Result values for unorm_quickCheck(). + * For details see Unicode Technical Report 15. + * @stable ICU 2.0 + */ +typedef enum UNormalizationCheckResult { + /** + * Indicates that string is not in the normalized format + */ + UNORM_NO, + /** + * Indicates that string is in the normalized format + */ + UNORM_YES, + /** + * Indicates that string cannot be determined if it is in the normalized + * format without further thorough checks. + */ + UNORM_MAYBE +} UNormalizationCheckResult; +#if !UCONFIG_NO_NORMALIZATION +/** + * Performing quick check on a string, to quickly determine if the string is + * in a particular normalization format. + * Three types of result can be returned UNORM_YES, UNORM_NO or + * UNORM_MAYBE. Result UNORM_YES indicates that the argument + * string is in the desired normalized format, UNORM_NO determines that + * argument string is not in the desired normalized format. A + * UNORM_MAYBE result indicates that a more thorough check is required, + * the user may have to put the string in its normalized form and compare the + * results. + * + * @param source string for determining if it is in a normalized format + * @param sourcelength length of source to test, or -1 if NUL-terminated + * @param mode which normalization form to test for + * @param status a pointer to a UErrorCode to receive any errors + * @return UNORM_YES, UNORM_NO or UNORM_MAYBE + * + * @see unorm_isNormalized + * @stable ICU 2.0 + */ +U_STABLE UNormalizationCheckResult U_EXPORT2 +unorm_quickCheck(const UChar *source, int32_t sourcelength, + UNormalizationMode mode, + UErrorCode *status); + +/** + * Performing quick check on a string; same as unorm_quickCheck but + * takes an extra options parameter like most normalization functions. + * + * @param src String that is to be tested if it is in a normalization format. + * @param srcLength Length of source to test, or -1 if NUL-terminated. + * @param mode Which normalization form to test for. + * @param options The normalization options, ORed together (0 for no options). + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return UNORM_YES, UNORM_NO or UNORM_MAYBE + * + * @see unorm_quickCheck + * @see unorm_isNormalized + * @stable ICU 2.6 + */ +U_STABLE UNormalizationCheckResult U_EXPORT2 +unorm_quickCheckWithOptions(const UChar *src, int32_t srcLength, + UNormalizationMode mode, int32_t options, + UErrorCode *pErrorCode); + +/** + * Test if a string is in a given normalization form. + * This is semantically equivalent to source.equals(normalize(source, mode)) . + * + * Unlike unorm_quickCheck(), this function returns a definitive result, + * never a "maybe". + * For NFD, NFKD, and FCD, both functions work exactly the same. + * For NFC and NFKC where quickCheck may return "maybe", this function will + * perform further tests to arrive at a TRUE/FALSE result. + * + * @param src String that is to be tested if it is in a normalization format. + * @param srcLength Length of source to test, or -1 if NUL-terminated. + * @param mode Which normalization form to test for. + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Boolean value indicating whether the source string is in the + * "mode" normalization form. + * + * @see unorm_quickCheck + * @stable ICU 2.2 + */ +U_STABLE UBool U_EXPORT2 +unorm_isNormalized(const UChar *src, int32_t srcLength, + UNormalizationMode mode, + UErrorCode *pErrorCode); + +/** + * Test if a string is in a given normalization form; same as unorm_isNormalized but + * takes an extra options parameter like most normalization functions. + * + * @param src String that is to be tested if it is in a normalization format. + * @param srcLength Length of source to test, or -1 if NUL-terminated. + * @param mode Which normalization form to test for. + * @param options The normalization options, ORed together (0 for no options). + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Boolean value indicating whether the source string is in the + * "mode/options" normalization form. + * + * @see unorm_quickCheck + * @see unorm_isNormalized + * @stable ICU 2.6 + */ +U_STABLE UBool U_EXPORT2 +unorm_isNormalizedWithOptions(const UChar *src, int32_t srcLength, + UNormalizationMode mode, int32_t options, + UErrorCode *pErrorCode); + +/** + * Iterative normalization forward. + * This function (together with unorm_previous) is somewhat + * similar to the C++ Normalizer class (see its non-static functions). + * + * Iterative normalization is useful when only a small portion of a longer + * string/text needs to be processed. + * + * For example, the likelihood may be high that processing the first 10% of some + * text will be sufficient to find certain data. + * Another example: When one wants to concatenate two normalized strings and get a + * normalized result, it is much more efficient to normalize just a small part of + * the result around the concatenation place instead of re-normalizing everything. + * + * The input text is an instance of the C character iteration API UCharIterator. + * It may wrap around a simple string, a CharacterIterator, a Replaceable, or any + * other kind of text object. + * + * If a buffer overflow occurs, then the caller needs to reset the iterator to the + * old index and call the function again with a larger buffer - if the caller cares + * for the actual output. + * Regardless of the output buffer, the iterator will always be moved to the next + * normalization boundary. + * + * This function (like unorm_previous) serves two purposes: + * + * 1) To find the next boundary so that the normalization of the part of the text + * from the current position to that boundary does not affect and is not affected + * by the part of the text beyond that boundary. + * + * 2) To normalize the text up to the boundary. + * + * The second step is optional, per the doNormalize parameter. + * It is omitted for operations like string concatenation, where the two adjacent + * string ends need to be normalized together. + * In such a case, the output buffer will just contain a copy of the text up to the + * boundary. + * + * pNeededToNormalize is an output-only parameter. Its output value is only defined + * if normalization was requested (doNormalize) and successful (especially, no + * buffer overflow). + * It is useful for operations like a normalizing transliterator, where one would + * not want to replace a piece of text if it is not modified. + * + * If doNormalize==TRUE and pNeededToNormalize!=NULL then *pNeeded... is set TRUE + * if the normalization was necessary. + * + * If doNormalize==FALSE then *pNeededToNormalize will be set to FALSE. + * + * If the buffer overflows, then *pNeededToNormalize will be undefined; + * essentially, whenever U_FAILURE is true (like in buffer overflows), this result + * will be undefined. + * + * @param src The input text in the form of a C character iterator. + * @param dest The output buffer; can be NULL if destCapacity==0 for pure preflighting. + * @param destCapacity The number of UChars that fit into dest. + * @param mode The normalization mode. + * @param options The normalization options, ORed together (0 for no options). + * @param doNormalize Indicates if the source text up to the next boundary + * is to be normalized (TRUE) or just copied (FALSE). + * @param pNeededToNormalize Output flag indicating if the normalization resulted in + * different text from the input. + * Not defined if an error occurs including buffer overflow. + * Always FALSE if !doNormalize. + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Length of output (number of UChars) when successful or buffer overflow. + * + * @see unorm_previous + * @see unorm_normalize + * + * @stable ICU 2.1 + */ +U_STABLE int32_t U_EXPORT2 +unorm_next(UCharIterator *src, + UChar *dest, int32_t destCapacity, + UNormalizationMode mode, int32_t options, + UBool doNormalize, UBool *pNeededToNormalize, + UErrorCode *pErrorCode); + +/** + * Iterative normalization backward. + * This function (together with unorm_next) is somewhat + * similar to the C++ Normalizer class (see its non-static functions). + * For all details see unorm_next. + * + * @param src The input text in the form of a C character iterator. + * @param dest The output buffer; can be NULL if destCapacity==0 for pure preflighting. + * @param destCapacity The number of UChars that fit into dest. + * @param mode The normalization mode. + * @param options The normalization options, ORed together (0 for no options). + * @param doNormalize Indicates if the source text up to the next boundary + * is to be normalized (TRUE) or just copied (FALSE). + * @param pNeededToNormalize Output flag indicating if the normalization resulted in + * different text from the input. + * Not defined if an error occurs including buffer overflow. + * Always FALSE if !doNormalize. + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Length of output (number of UChars) when successful or buffer overflow. + * + * @see unorm_next + * @see unorm_normalize + * + * @stable ICU 2.1 + */ +U_STABLE int32_t U_EXPORT2 +unorm_previous(UCharIterator *src, + UChar *dest, int32_t destCapacity, + UNormalizationMode mode, int32_t options, + UBool doNormalize, UBool *pNeededToNormalize, + UErrorCode *pErrorCode); + +/** + * Concatenate normalized strings, making sure that the result is normalized as well. + * + * If both the left and the right strings are in + * the normalization form according to "mode/options", + * then the result will be + * + * \code + * dest=normalize(left+right, mode, options) + * \endcode + * + * With the input strings already being normalized, + * this function will use unorm_next() and unorm_previous() + * to find the adjacent end pieces of the input strings. + * Only the concatenation of these end pieces will be normalized and + * then concatenated with the remaining parts of the input strings. + * + * It is allowed to have dest==left to avoid copying the entire left string. + * + * @param left Left source string, may be same as dest. + * @param leftLength Length of left source string, or -1 if NUL-terminated. + * @param right Right source string. Must not be the same as dest, nor overlap. + * @param rightLength Length of right source string, or -1 if NUL-terminated. + * @param dest The output buffer; can be NULL if destCapacity==0 for pure preflighting. + * @param destCapacity The number of UChars that fit into dest. + * @param mode The normalization mode. + * @param options The normalization options, ORed together (0 for no options). + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return Length of output (number of UChars) when successful or buffer overflow. + * + * @see unorm_normalize + * @see unorm_next + * @see unorm_previous + * + * @stable ICU 2.1 + */ +U_STABLE int32_t U_EXPORT2 +unorm_concatenate(const UChar *left, int32_t leftLength, + const UChar *right, int32_t rightLength, + UChar *dest, int32_t destCapacity, + UNormalizationMode mode, int32_t options, + UErrorCode *pErrorCode); + +/** + * Option bit for unorm_compare: + * Both input strings are assumed to fulfill FCD conditions. + * @stable ICU 2.2 + */ +#define UNORM_INPUT_IS_FCD 0x20000 + +/** + * Option bit for unorm_compare: + * Perform case-insensitive comparison. + * @stable ICU 2.2 + */ +#define U_COMPARE_IGNORE_CASE 0x10000 + +#ifndef U_COMPARE_CODE_POINT_ORDER +/* see also unistr.h and ustring.h */ +/** + * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc: + * Compare strings in code point order instead of code unit order. + * @stable ICU 2.2 + */ +#define U_COMPARE_CODE_POINT_ORDER 0x8000 +#endif + +/** + * Compare two strings for canonical equivalence. + * Further options include case-insensitive comparison and + * code point order (as opposed to code unit order). + * + * Canonical equivalence between two strings is defined as their normalized + * forms (NFD or NFC) being identical. + * This function compares strings incrementally instead of normalizing + * (and optionally case-folding) both strings entirely, + * improving performance significantly. + * + * Bulk normalization is only necessary if the strings do not fulfill the FCD + * conditions. Only in this case, and only if the strings are relatively long, + * is memory allocated temporarily. + * For FCD strings and short non-FCD strings there is no memory allocation. + * + * Semantically, this is equivalent to + * strcmp[CodePointOrder](NFD(foldCase(NFD(s1))), NFD(foldCase(NFD(s2)))) + * where code point order and foldCase are all optional. + * + * UAX 21 2.5 Caseless Matching specifies that for a canonical caseless match + * the case folding must be performed first, then the normalization. + * + * @param s1 First source string. + * @param length1 Length of first source string, or -1 if NUL-terminated. + * + * @param s2 Second source string. + * @param length2 Length of second source string, or -1 if NUL-terminated. + * + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Case-sensitive comparison in code unit order, and the input strings + * are quick-checked for FCD. + * + * - UNORM_INPUT_IS_FCD + * Set if the caller knows that both s1 and s2 fulfill the FCD conditions. + * If not set, the function will quickCheck for FCD + * and normalize if necessary. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_COMPARE_IGNORE_CASE + * Set to compare strings case-insensitively using case folding, + * instead of case-sensitively. + * If set, then the following case folding options are used. + * + * - Options as used with case-insensitive comparisons, currently: + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * (see u_strCaseCompare for details) + * + * - regular normalization options shifted left by UNORM_COMPARE_NORM_OPTIONS_SHIFT + * + * @param pErrorCode ICU error code in/out parameter. + * Must fulfill U_SUCCESS before the function call. + * @return <0 or 0 or >0 as usual for string comparisons + * + * @see unorm_normalize + * @see UNORM_FCD + * @see u_strCompare + * @see u_strCaseCompare + * + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +unorm_compare(const UChar *s1, int32_t length1, + const UChar *s2, int32_t length2, + uint32_t options, + UErrorCode *pErrorCode); + +#endif /* #if !UCONFIG_NO_NORMALIZATION */ + +#endif diff --git a/utils/openttd/unicode/uobject.h b/utils/openttd/unicode/uobject.h new file mode 100644 index 00000000000..3d8b96ebec2 --- /dev/null +++ b/utils/openttd/unicode/uobject.h @@ -0,0 +1,308 @@ +/* +****************************************************************************** +* +* Copyright (C) 2002-2007, International Business Machines +* Corporation and others. All Rights Reserved. +* +****************************************************************************** +* file name: uobject.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2002jun26 +* created by: Markus W. Scherer +*/ + +#ifndef __UOBJECT_H__ +#define __UOBJECT_H__ + +#include "unicode/utypes.h" + +U_NAMESPACE_BEGIN + +/** + * \file + * \brief C++ API: Common ICU base class UObject. + */ + +/** U_OVERRIDE_CXX_ALLOCATION - Define this to override operator new and + * delete in UMemory. Enabled by default for ICU. + * + * Enabling forces all allocation of ICU object types to use ICU's + * memory allocation. On Windows, this allows the ICU DLL to be used by + * applications that statically link the C Runtime library, meaning that + * the app and ICU will be using different heaps. + * + * @stable ICU 2.2 + */ +#ifndef U_OVERRIDE_CXX_ALLOCATION +#define U_OVERRIDE_CXX_ALLOCATION 1 +#endif + +/** U_HAVE_PLACEMENT_NEW - Define this to define the placement new and + * delete in UMemory for STL. + * + * @stable ICU 2.6 + */ +#ifndef U_HAVE_PLACEMENT_NEW +#define U_HAVE_PLACEMENT_NEW 1 +#endif + + +/** U_HAVE_DEBUG_LOCATION_NEW - Define this to define the MFC debug + * version of the operator new. + * + * @stable ICU 3.4 + */ +#ifndef U_HAVE_DEBUG_LOCATION_NEW +#define U_HAVE_DEBUG_LOCATION_NEW 0 +#endif + +/** + * UMemory is the common ICU base class. + * All other ICU C++ classes are derived from UMemory (starting with ICU 2.4). + * + * This is primarily to make it possible and simple to override the + * C++ memory management by adding new/delete operators to this base class. + * + * To override ALL ICU memory management, including that from plain C code, + * replace the allocation functions declared in cmemory.h + * + * UMemory does not contain any virtual functions. + * Common "boilerplate" functions are defined in UObject. + * + * @stable ICU 2.4 + */ +class U_COMMON_API UMemory { +public: + +#if U_OVERRIDE_CXX_ALLOCATION + /** + * Override for ICU4C C++ memory management. + * simple, non-class types are allocated using the macros in common/cmemory.h + * (uprv_malloc(), uprv_free(), uprv_realloc()); + * they or something else could be used here to implement C++ new/delete + * for ICU4C C++ classes + * @stable ICU 2.4 + */ + static void * U_EXPORT2 operator new(size_t size); + + /** + * Override for ICU4C C++ memory management. + * See new(). + * @stable ICU 2.4 + */ + static void * U_EXPORT2 operator new[](size_t size); + + /** + * Override for ICU4C C++ memory management. + * simple, non-class types are allocated using the macros in common/cmemory.h + * (uprv_malloc(), uprv_free(), uprv_realloc()); + * they or something else could be used here to implement C++ new/delete + * for ICU4C C++ classes + * @stable ICU 2.4 + */ + static void U_EXPORT2 operator delete(void *p); + + /** + * Override for ICU4C C++ memory management. + * See delete(). + * @stable ICU 2.4 + */ + static void U_EXPORT2 operator delete[](void *p); + +#if U_HAVE_PLACEMENT_NEW + /** + * Override for ICU4C C++ memory management for STL. + * See new(). + * @stable ICU 2.6 + */ + static inline void * U_EXPORT2 operator new(size_t, void *ptr) { return ptr; } + + /** + * Override for ICU4C C++ memory management for STL. + * See delete(). + * @stable ICU 2.6 + */ + static inline void U_EXPORT2 operator delete(void *, void *) {} +#endif /* U_HAVE_PLACEMENT_NEW */ +#if U_HAVE_DEBUG_LOCATION_NEW + /** + * This method overrides the MFC debug version of the operator new + * + * @param size The requested memory size + * @param file The file where the allocation was requested + * @param line The line where the allocation was requested + */ + static void * U_EXPORT2 operator new(size_t size, const char* file, int line); + /** + * This method provides a matching delete for the MFC debug new + * + * @param p The pointer to the allocated memory + * @param file The file where the allocation was requested + * @param line The line where the allocation was requested + */ + static void U_EXPORT2 operator delete(void* p, const char* file, int line); +#endif /* U_HAVE_DEBUG_LOCATION_NEW */ +#endif /* U_OVERRIDE_CXX_ALLOCATION */ + + /* + * Assignment operator not declared. The compiler will provide one + * which does nothing since this class does not contain any data members. + * API/code coverage may show the assignment operator as present and + * untested - ignore. + * Subclasses need this assignment operator if they use compiler-provided + * assignment operators of their own. An alternative to not declaring one + * here would be to declare and empty-implement a protected or public one. + UMemory &UMemory::operator=(const UMemory &); + */ +}; + +/** + * UObject is the common ICU "boilerplate" class. + * UObject inherits UMemory (starting with ICU 2.4), + * and all other public ICU C++ classes + * are derived from UObject (starting with ICU 2.2). + * + * UObject contains common virtual functions like for ICU's "poor man's RTTI". + * It does not contain default implementations of virtual methods + * like getDynamicClassID to allow derived classes such as Format + * to declare these as pure virtual. + * + * The clone() function is not available in UObject because it is not + * implemented by all ICU classes. + * Many ICU services provide a clone() function for their class trees, + * defined on the service's C++ base class, and all subclasses within that + * service class tree return a pointer to the service base class + * (which itself is a subclass of UObject). + * This is because some compilers do not support covariant (same-as-this) + * return types; cast to the appropriate subclass if necessary. + * + * @stable ICU 2.2 + */ +class U_COMMON_API UObject : public UMemory { +public: + /** + * Destructor. + * + * @stable ICU 2.2 + */ + virtual ~UObject(); + + /** + * ICU4C "poor man's RTTI", returns a UClassID for the actual ICU class. + * + * @stable ICU 2.2 + */ + virtual UClassID getDynamicClassID() const = 0; + +protected: + // the following functions are protected to prevent instantiation and + // direct use of UObject itself + + // default constructor + // commented out because UObject is abstract (see getDynamicClassID) + // inline UObject() {} + + // copy constructor + // commented out because UObject is abstract (see getDynamicClassID) + // inline UObject(const UObject &other) {} + +#if 0 + // TODO Sometime in the future. Implement operator==(). + // (This comment inserted in 2.2) + // some or all of the following "boilerplate" functions may be made public + // in a future ICU4C release when all subclasses implement them + + // assignment operator + // (not virtual, see "Taligent's Guide to Designing Programs" pp.73..74) + // commented out because the implementation is the same as a compiler's default + // UObject &operator=(const UObject &other) { return *this; } + + // comparison operators + virtual inline UBool operator==(const UObject &other) const { return this==&other; } + inline UBool operator!=(const UObject &other) const { return !operator==(other); } + + // clone() commented out from the base class: + // some compilers do not support co-variant return types + // (i.e., subclasses would have to return UObject * as well, instead of SubClass *) + // see also UObject class documentation. + // virtual UObject *clone() const; +#endif + + /* + * Assignment operator not declared. The compiler will provide one + * which does nothing since this class does not contain any data members. + * API/code coverage may show the assignment operator as present and + * untested - ignore. + * Subclasses need this assignment operator if they use compiler-provided + * assignment operators of their own. An alternative to not declaring one + * here would be to declare and empty-implement a protected or public one. + UObject &UObject::operator=(const UObject &); + */ + +// Future implementation for RTTI that support subtyping. [alan] +// +// public: +// /** +// * @internal +// */ +// static UClassID getStaticClassID(); +// +// /** +// * @internal +// */ +// UBool instanceOf(UClassID type) const; +}; + +/** + * This is a simple macro to add ICU RTTI to an ICU object implementation. + * This does not go into the header. This should only be used in *.cpp files. + * + * @param myClass The name of the class that needs RTTI defined. + * @internal + */ +#define UOBJECT_DEFINE_RTTI_IMPLEMENTATION(myClass) \ + UClassID U_EXPORT2 myClass::getStaticClassID() { \ + static char classID = 0; \ + return (UClassID)&classID; \ + } \ + UClassID myClass::getDynamicClassID() const \ + { return myClass::getStaticClassID(); } + + +/** + * This macro adds ICU RTTI to an ICU abstract class implementation. + * This macro should be invoked in *.cpp files. The corresponding + * header should declare getStaticClassID. + * + * @param myClass The name of the class that needs RTTI defined. + * @internal + */ +#define UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(myClass) \ + UClassID U_EXPORT2 myClass::getStaticClassID() { \ + static char classID = 0; \ + return (UClassID)&classID; \ + } + +// /** +// * This macro adds ICU RTTI to an ICU concrete class implementation. +// * This macro should be invoked in *.cpp files. The corresponding +// * header should declare getDynamicClassID and getStaticClassID. +// * +// * @param myClass The name of the class that needs RTTI defined. +// * @param myParent The name of the myClass's parent. +// * @internal +// */ +/*#define UOBJECT_DEFINE_RTTI_IMPLEMENTATION(myClass, myParent) \ + UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(myClass, myParent) \ + UClassID myClass::getDynamicClassID() const { \ + return myClass::getStaticClassID(); \ + } +*/ + + +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/uobslete.h b/utils/openttd/unicode/uobslete.h new file mode 100644 index 00000000000..91be2437669 --- /dev/null +++ b/utils/openttd/unicode/uobslete.h @@ -0,0 +1,32 @@ +/* +******************************************************************************* +* Copyright (C) 2004-2008, International Business Machines +* Corporation and others. All Rights Reserved. +******************************************************************************* +* +* file name: +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* Created by: genheaders.pl, a perl script written by Ram Viswanadha +* +* Contains data for commenting out APIs. +* Gets included by umachine.h +* +* THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT +* YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN! +*/ + +#ifndef UOBSLETE_H +#define UOBSLETE_H + +#ifdef U_HIDE_OBSOLETE_API + +# if U_DISABLE_RENAMING +# else +# endif /* U_DISABLE_RENAMING */ + +#endif /* U_HIDE_OBSOLETE_API */ +#endif /* UOBSLETE_H */ + diff --git a/utils/openttd/unicode/urename.h b/utils/openttd/unicode/urename.h new file mode 100644 index 00000000000..52829584e6d --- /dev/null +++ b/utils/openttd/unicode/urename.h @@ -0,0 +1,1775 @@ +/* +******************************************************************************* +* Copyright (C) 2002-2008, International Business Machines +* Corporation and others. All Rights Reserved. +******************************************************************************* +* +* file name: urename.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* Created by: Perl script written by Vladimir Weinstein +* +* Contains data for renaming ICU exports. +* Gets included by umachine.h +* +* THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT +* YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN! +*/ + +#ifndef URENAME_H +#define URENAME_H + +/* Uncomment the following line to disable renaming on platforms + that do not use Autoconf. */ +/* #define U_DISABLE_RENAMING 1 */ + +#if !U_DISABLE_RENAMING + +/* C exports renaming data */ + +#define T_CString_int64ToString T_CString_int64ToString_4_0 +#define T_CString_integerToString T_CString_integerToString_4_0 +#define T_CString_stricmp T_CString_stricmp_4_0 +#define T_CString_stringToInteger T_CString_stringToInteger_4_0 +#define T_CString_strnicmp T_CString_strnicmp_4_0 +#define T_CString_toLowerCase T_CString_toLowerCase_4_0 +#define T_CString_toUpperCase T_CString_toUpperCase_4_0 +#define UCNV_FROM_U_CALLBACK_ESCAPE UCNV_FROM_U_CALLBACK_ESCAPE_4_0 +#define UCNV_FROM_U_CALLBACK_SKIP UCNV_FROM_U_CALLBACK_SKIP_4_0 +#define UCNV_FROM_U_CALLBACK_STOP UCNV_FROM_U_CALLBACK_STOP_4_0 +#define UCNV_FROM_U_CALLBACK_SUBSTITUTE UCNV_FROM_U_CALLBACK_SUBSTITUTE_4_0 +#define UCNV_TO_U_CALLBACK_ESCAPE UCNV_TO_U_CALLBACK_ESCAPE_4_0 +#define UCNV_TO_U_CALLBACK_SKIP UCNV_TO_U_CALLBACK_SKIP_4_0 +#define UCNV_TO_U_CALLBACK_STOP UCNV_TO_U_CALLBACK_STOP_4_0 +#define UCNV_TO_U_CALLBACK_SUBSTITUTE UCNV_TO_U_CALLBACK_SUBSTITUTE_4_0 +#define UDataMemory_createNewInstance UDataMemory_createNewInstance_4_0 +#define UDataMemory_init UDataMemory_init_4_0 +#define UDataMemory_isLoaded UDataMemory_isLoaded_4_0 +#define UDataMemory_normalizeDataPointer UDataMemory_normalizeDataPointer_4_0 +#define UDataMemory_setData UDataMemory_setData_4_0 +#define UDatamemory_assign UDatamemory_assign_4_0 +#define _ASCIIData _ASCIIData_4_0 +#define _Bocu1Data _Bocu1Data_4_0 +#define _CESU8Data _CESU8Data_4_0 +#define _HZData _HZData_4_0 +#define _IMAPData _IMAPData_4_0 +#define _ISCIIData _ISCIIData_4_0 +#define _ISO2022Data _ISO2022Data_4_0 +#define _LMBCSData1 _LMBCSData1_4_0 +#define _LMBCSData11 _LMBCSData11_4_0 +#define _LMBCSData16 _LMBCSData16_4_0 +#define _LMBCSData17 _LMBCSData17_4_0 +#define _LMBCSData18 _LMBCSData18_4_0 +#define _LMBCSData19 _LMBCSData19_4_0 +#define _LMBCSData2 _LMBCSData2_4_0 +#define _LMBCSData3 _LMBCSData3_4_0 +#define _LMBCSData4 _LMBCSData4_4_0 +#define _LMBCSData5 _LMBCSData5_4_0 +#define _LMBCSData6 _LMBCSData6_4_0 +#define _LMBCSData8 _LMBCSData8_4_0 +#define _Latin1Data _Latin1Data_4_0 +#define _MBCSData _MBCSData_4_0 +#define _SCSUData _SCSUData_4_0 +#define _UTF16BEData _UTF16BEData_4_0 +#define _UTF16Data _UTF16Data_4_0 +#define _UTF16LEData _UTF16LEData_4_0 +#define _UTF32BEData _UTF32BEData_4_0 +#define _UTF32Data _UTF32Data_4_0 +#define _UTF32LEData _UTF32LEData_4_0 +#define _UTF7Data _UTF7Data_4_0 +#define _UTF8Data _UTF8Data_4_0 +#define cmemory_cleanup cmemory_cleanup_4_0 +#define cmemory_inUse cmemory_inUse_4_0 +#define le_close le_close_4_0 +#define le_create le_create_4_0 +#define le_getCharIndices le_getCharIndices_4_0 +#define le_getCharIndicesWithBase le_getCharIndicesWithBase_4_0 +#define le_getGlyphCount le_getGlyphCount_4_0 +#define le_getGlyphPosition le_getGlyphPosition_4_0 +#define le_getGlyphPositions le_getGlyphPositions_4_0 +#define le_getGlyphs le_getGlyphs_4_0 +#define le_layoutChars le_layoutChars_4_0 +#define le_reset le_reset_4_0 +#define locale_getKeywords locale_getKeywords_4_0 +#define locale_get_default locale_get_default_4_0 +#define locale_set_default locale_set_default_4_0 +#define pl_addFontRun pl_addFontRun_4_0 +#define pl_addLocaleRun pl_addLocaleRun_4_0 +#define pl_addValueRun pl_addValueRun_4_0 +#define pl_close pl_close_4_0 +#define pl_closeFontRuns pl_closeFontRuns_4_0 +#define pl_closeLine pl_closeLine_4_0 +#define pl_closeLocaleRuns pl_closeLocaleRuns_4_0 +#define pl_closeValueRuns pl_closeValueRuns_4_0 +#define pl_countLineRuns pl_countLineRuns_4_0 +#define pl_create pl_create_4_0 +#define pl_getAscent pl_getAscent_4_0 +#define pl_getDescent pl_getDescent_4_0 +#define pl_getFontRunCount pl_getFontRunCount_4_0 +#define pl_getFontRunFont pl_getFontRunFont_4_0 +#define pl_getFontRunLastLimit pl_getFontRunLastLimit_4_0 +#define pl_getFontRunLimit pl_getFontRunLimit_4_0 +#define pl_getLeading pl_getLeading_4_0 +#define pl_getLineAscent pl_getLineAscent_4_0 +#define pl_getLineDescent pl_getLineDescent_4_0 +#define pl_getLineLeading pl_getLineLeading_4_0 +#define pl_getLineVisualRun pl_getLineVisualRun_4_0 +#define pl_getLineWidth pl_getLineWidth_4_0 +#define pl_getLocaleRunCount pl_getLocaleRunCount_4_0 +#define pl_getLocaleRunLastLimit pl_getLocaleRunLastLimit_4_0 +#define pl_getLocaleRunLimit pl_getLocaleRunLimit_4_0 +#define pl_getLocaleRunLocale pl_getLocaleRunLocale_4_0 +#define pl_getParagraphLevel pl_getParagraphLevel_4_0 +#define pl_getTextDirection pl_getTextDirection_4_0 +#define pl_getValueRunCount pl_getValueRunCount_4_0 +#define pl_getValueRunLastLimit pl_getValueRunLastLimit_4_0 +#define pl_getValueRunLimit pl_getValueRunLimit_4_0 +#define pl_getValueRunValue pl_getValueRunValue_4_0 +#define pl_getVisualRunAscent pl_getVisualRunAscent_4_0 +#define pl_getVisualRunDescent pl_getVisualRunDescent_4_0 +#define pl_getVisualRunDirection pl_getVisualRunDirection_4_0 +#define pl_getVisualRunFont pl_getVisualRunFont_4_0 +#define pl_getVisualRunGlyphCount pl_getVisualRunGlyphCount_4_0 +#define pl_getVisualRunGlyphToCharMap pl_getVisualRunGlyphToCharMap_4_0 +#define pl_getVisualRunGlyphs pl_getVisualRunGlyphs_4_0 +#define pl_getVisualRunLeading pl_getVisualRunLeading_4_0 +#define pl_getVisualRunPositions pl_getVisualRunPositions_4_0 +#define pl_isComplex pl_isComplex_4_0 +#define pl_nextLine pl_nextLine_4_0 +#define pl_openEmptyFontRuns pl_openEmptyFontRuns_4_0 +#define pl_openEmptyLocaleRuns pl_openEmptyLocaleRuns_4_0 +#define pl_openEmptyValueRuns pl_openEmptyValueRuns_4_0 +#define pl_openFontRuns pl_openFontRuns_4_0 +#define pl_openLocaleRuns pl_openLocaleRuns_4_0 +#define pl_openValueRuns pl_openValueRuns_4_0 +#define pl_reflow pl_reflow_4_0 +#define pl_resetFontRuns pl_resetFontRuns_4_0 +#define pl_resetLocaleRuns pl_resetLocaleRuns_4_0 +#define pl_resetValueRuns pl_resetValueRuns_4_0 +#define res_countArrayItems res_countArrayItems_4_0 +#define res_findResource res_findResource_4_0 +#define res_getAlias res_getAlias_4_0 +#define res_getArrayItem res_getArrayItem_4_0 +#define res_getBinary res_getBinary_4_0 +#define res_getIntVector res_getIntVector_4_0 +#define res_getResource res_getResource_4_0 +#define res_getString res_getString_4_0 +#define res_getTableItemByIndex res_getTableItemByIndex_4_0 +#define res_getTableItemByKey res_getTableItemByKey_4_0 +#define res_load res_load_4_0 +#define res_unload res_unload_4_0 +#define transliterator_cleanup transliterator_cleanup_4_0 +#define triedict_swap triedict_swap_4_0 +#define u_UCharsToChars u_UCharsToChars_4_0 +#define u_austrcpy u_austrcpy_4_0 +#define u_austrncpy u_austrncpy_4_0 +#define u_catclose u_catclose_4_0 +#define u_catgets u_catgets_4_0 +#define u_catopen u_catopen_4_0 +#define u_charAge u_charAge_4_0 +#define u_charDigitValue u_charDigitValue_4_0 +#define u_charDirection u_charDirection_4_0 +#define u_charFromName u_charFromName_4_0 +#define u_charMirror u_charMirror_4_0 +#define u_charName u_charName_4_0 +#define u_charType u_charType_4_0 +#define u_charsToUChars u_charsToUChars_4_0 +#define u_cleanup u_cleanup_4_0 +#define u_countChar32 u_countChar32_4_0 +#define u_digit u_digit_4_0 +#define u_enumCharNames u_enumCharNames_4_0 +#define u_enumCharTypes u_enumCharTypes_4_0 +#define u_errorName u_errorName_4_0 +#define u_fclose u_fclose_4_0 +#define u_feof u_feof_4_0 +#define u_fflush u_fflush_4_0 +#define u_fgetConverter u_fgetConverter_4_0 +#define u_fgetc u_fgetc_4_0 +#define u_fgetcodepage u_fgetcodepage_4_0 +#define u_fgetcx u_fgetcx_4_0 +#define u_fgetfile u_fgetfile_4_0 +#define u_fgetlocale u_fgetlocale_4_0 +#define u_fgets u_fgets_4_0 +#define u_file_read u_file_read_4_0 +#define u_file_write u_file_write_4_0 +#define u_file_write_flush u_file_write_flush_4_0 +#define u_finit u_finit_4_0 +#define u_foldCase u_foldCase_4_0 +#define u_fopen u_fopen_4_0 +#define u_forDigit u_forDigit_4_0 +#define u_formatMessage u_formatMessage_4_0 +#define u_formatMessageWithError u_formatMessageWithError_4_0 +#define u_fprintf u_fprintf_4_0 +#define u_fprintf_u u_fprintf_u_4_0 +#define u_fputc u_fputc_4_0 +#define u_fputs u_fputs_4_0 +#define u_frewind u_frewind_4_0 +#define u_fscanf u_fscanf_4_0 +#define u_fscanf_u u_fscanf_u_4_0 +#define u_fsetcodepage u_fsetcodepage_4_0 +#define u_fsetlocale u_fsetlocale_4_0 +#define u_fsettransliterator u_fsettransliterator_4_0 +#define u_fstropen u_fstropen_4_0 +#define u_fungetc u_fungetc_4_0 +#define u_getCombiningClass u_getCombiningClass_4_0 +#define u_getDataDirectory u_getDataDirectory_4_0 +#define u_getDefaultConverter u_getDefaultConverter_4_0 +#define u_getFC_NFKC_Closure u_getFC_NFKC_Closure_4_0 +#define u_getISOComment u_getISOComment_4_0 +#define u_getIntPropertyMaxValue u_getIntPropertyMaxValue_4_0 +#define u_getIntPropertyMinValue u_getIntPropertyMinValue_4_0 +#define u_getIntPropertyValue u_getIntPropertyValue_4_0 +#define u_getNumericValue u_getNumericValue_4_0 +#define u_getPropertyEnum u_getPropertyEnum_4_0 +#define u_getPropertyName u_getPropertyName_4_0 +#define u_getPropertyValueEnum u_getPropertyValueEnum_4_0 +#define u_getPropertyValueName u_getPropertyValueName_4_0 +#define u_getUnicodeProperties u_getUnicodeProperties_4_0 +#define u_getUnicodeVersion u_getUnicodeVersion_4_0 +#define u_getVersion u_getVersion_4_0 +#define u_growBufferFromStatic u_growBufferFromStatic_4_0 +#define u_hasBinaryProperty u_hasBinaryProperty_4_0 +#define u_init u_init_4_0 +#define u_isIDIgnorable u_isIDIgnorable_4_0 +#define u_isIDPart u_isIDPart_4_0 +#define u_isIDStart u_isIDStart_4_0 +#define u_isISOControl u_isISOControl_4_0 +#define u_isJavaIDPart u_isJavaIDPart_4_0 +#define u_isJavaIDStart u_isJavaIDStart_4_0 +#define u_isJavaSpaceChar u_isJavaSpaceChar_4_0 +#define u_isMirrored u_isMirrored_4_0 +#define u_isUAlphabetic u_isUAlphabetic_4_0 +#define u_isULowercase u_isULowercase_4_0 +#define u_isUUppercase u_isUUppercase_4_0 +#define u_isUWhiteSpace u_isUWhiteSpace_4_0 +#define u_isWhitespace u_isWhitespace_4_0 +#define u_isalnum u_isalnum_4_0 +#define u_isalnumPOSIX u_isalnumPOSIX_4_0 +#define u_isalpha u_isalpha_4_0 +#define u_isbase u_isbase_4_0 +#define u_isblank u_isblank_4_0 +#define u_iscntrl u_iscntrl_4_0 +#define u_isdefined u_isdefined_4_0 +#define u_isdigit u_isdigit_4_0 +#define u_isgraph u_isgraph_4_0 +#define u_isgraphPOSIX u_isgraphPOSIX_4_0 +#define u_islower u_islower_4_0 +#define u_isprint u_isprint_4_0 +#define u_isprintPOSIX u_isprintPOSIX_4_0 +#define u_ispunct u_ispunct_4_0 +#define u_isspace u_isspace_4_0 +#define u_istitle u_istitle_4_0 +#define u_isupper u_isupper_4_0 +#define u_isxdigit u_isxdigit_4_0 +#define u_lengthOfIdenticalLevelRun u_lengthOfIdenticalLevelRun_4_0 +#define u_locbund_close u_locbund_close_4_0 +#define u_locbund_getNumberFormat u_locbund_getNumberFormat_4_0 +#define u_locbund_init u_locbund_init_4_0 +#define u_memcasecmp u_memcasecmp_4_0 +#define u_memchr u_memchr_4_0 +#define u_memchr32 u_memchr32_4_0 +#define u_memcmp u_memcmp_4_0 +#define u_memcmpCodePointOrder u_memcmpCodePointOrder_4_0 +#define u_memcpy u_memcpy_4_0 +#define u_memmove u_memmove_4_0 +#define u_memrchr u_memrchr_4_0 +#define u_memrchr32 u_memrchr32_4_0 +#define u_memset u_memset_4_0 +#define u_parseMessage u_parseMessage_4_0 +#define u_parseMessageWithError u_parseMessageWithError_4_0 +#define u_printf_parse u_printf_parse_4_0 +#define u_releaseDefaultConverter u_releaseDefaultConverter_4_0 +#define u_scanf_parse u_scanf_parse_4_0 +#define u_setAtomicIncDecFunctions u_setAtomicIncDecFunctions_4_0 +#define u_setDataDirectory u_setDataDirectory_4_0 +#define u_setMemoryFunctions u_setMemoryFunctions_4_0 +#define u_setMutexFunctions u_setMutexFunctions_4_0 +#define u_shapeArabic u_shapeArabic_4_0 +#define u_snprintf u_snprintf_4_0 +#define u_snprintf_u u_snprintf_u_4_0 +#define u_sprintf u_sprintf_4_0 +#define u_sprintf_u u_sprintf_u_4_0 +#define u_sscanf u_sscanf_4_0 +#define u_sscanf_u u_sscanf_u_4_0 +#define u_strCaseCompare u_strCaseCompare_4_0 +#define u_strCompare u_strCompare_4_0 +#define u_strCompareIter u_strCompareIter_4_0 +#define u_strFindFirst u_strFindFirst_4_0 +#define u_strFindLast u_strFindLast_4_0 +#define u_strFoldCase u_strFoldCase_4_0 +#define u_strFromPunycode u_strFromPunycode_4_0 +#define u_strFromUTF32 u_strFromUTF32_4_0 +#define u_strFromUTF8 u_strFromUTF8_4_0 +#define u_strFromUTF8Lenient u_strFromUTF8Lenient_4_0 +#define u_strFromUTF8WithSub u_strFromUTF8WithSub_4_0 +#define u_strFromWCS u_strFromWCS_4_0 +#define u_strHasMoreChar32Than u_strHasMoreChar32Than_4_0 +#define u_strToLower u_strToLower_4_0 +#define u_strToPunycode u_strToPunycode_4_0 +#define u_strToTitle u_strToTitle_4_0 +#define u_strToUTF32 u_strToUTF32_4_0 +#define u_strToUTF8 u_strToUTF8_4_0 +#define u_strToUTF8WithSub u_strToUTF8WithSub_4_0 +#define u_strToUpper u_strToUpper_4_0 +#define u_strToWCS u_strToWCS_4_0 +#define u_strcasecmp u_strcasecmp_4_0 +#define u_strcat u_strcat_4_0 +#define u_strchr u_strchr_4_0 +#define u_strchr32 u_strchr32_4_0 +#define u_strcmp u_strcmp_4_0 +#define u_strcmpCodePointOrder u_strcmpCodePointOrder_4_0 +#define u_strcmpFold u_strcmpFold_4_0 +#define u_strcpy u_strcpy_4_0 +#define u_strcspn u_strcspn_4_0 +#define u_strlen u_strlen_4_0 +#define u_strncasecmp u_strncasecmp_4_0 +#define u_strncat u_strncat_4_0 +#define u_strncmp u_strncmp_4_0 +#define u_strncmpCodePointOrder u_strncmpCodePointOrder_4_0 +#define u_strncpy u_strncpy_4_0 +#define u_strpbrk u_strpbrk_4_0 +#define u_strrchr u_strrchr_4_0 +#define u_strrchr32 u_strrchr32_4_0 +#define u_strrstr u_strrstr_4_0 +#define u_strspn u_strspn_4_0 +#define u_strstr u_strstr_4_0 +#define u_strtok_r u_strtok_r_4_0 +#define u_terminateChars u_terminateChars_4_0 +#define u_terminateUChar32s u_terminateUChar32s_4_0 +#define u_terminateUChars u_terminateUChars_4_0 +#define u_terminateWChars u_terminateWChars_4_0 +#define u_tolower u_tolower_4_0 +#define u_totitle u_totitle_4_0 +#define u_toupper u_toupper_4_0 +#define u_uastrcpy u_uastrcpy_4_0 +#define u_uastrncpy u_uastrncpy_4_0 +#define u_unescape u_unescape_4_0 +#define u_unescapeAt u_unescapeAt_4_0 +#define u_versionFromString u_versionFromString_4_0 +#define u_versionToString u_versionToString_4_0 +#define u_vformatMessage u_vformatMessage_4_0 +#define u_vformatMessageWithError u_vformatMessageWithError_4_0 +#define u_vfprintf u_vfprintf_4_0 +#define u_vfprintf_u u_vfprintf_u_4_0 +#define u_vfscanf u_vfscanf_4_0 +#define u_vfscanf_u u_vfscanf_u_4_0 +#define u_vparseMessage u_vparseMessage_4_0 +#define u_vparseMessageWithError u_vparseMessageWithError_4_0 +#define u_vsnprintf u_vsnprintf_4_0 +#define u_vsnprintf_u u_vsnprintf_u_4_0 +#define u_vsprintf u_vsprintf_4_0 +#define u_vsprintf_u u_vsprintf_u_4_0 +#define u_vsscanf u_vsscanf_4_0 +#define u_vsscanf_u u_vsscanf_u_4_0 +#define u_writeDiff u_writeDiff_4_0 +#define u_writeIdenticalLevelRun u_writeIdenticalLevelRun_4_0 +#define u_writeIdenticalLevelRunTwoChars u_writeIdenticalLevelRunTwoChars_4_0 +#define ubidi_addPropertyStarts ubidi_addPropertyStarts_4_0 +#define ubidi_close ubidi_close_4_0 +#define ubidi_closeProps ubidi_closeProps_4_0 +#define ubidi_countParagraphs ubidi_countParagraphs_4_0 +#define ubidi_countRuns ubidi_countRuns_4_0 +#define ubidi_getClass ubidi_getClass_4_0 +#define ubidi_getClassCallback ubidi_getClassCallback_4_0 +#define ubidi_getCustomizedClass ubidi_getCustomizedClass_4_0 +#define ubidi_getDirection ubidi_getDirection_4_0 +#define ubidi_getJoiningGroup ubidi_getJoiningGroup_4_0 +#define ubidi_getJoiningType ubidi_getJoiningType_4_0 +#define ubidi_getLength ubidi_getLength_4_0 +#define ubidi_getLevelAt ubidi_getLevelAt_4_0 +#define ubidi_getLevels ubidi_getLevels_4_0 +#define ubidi_getLogicalIndex ubidi_getLogicalIndex_4_0 +#define ubidi_getLogicalMap ubidi_getLogicalMap_4_0 +#define ubidi_getLogicalRun ubidi_getLogicalRun_4_0 +#define ubidi_getMaxValue ubidi_getMaxValue_4_0 +#define ubidi_getMemory ubidi_getMemory_4_0 +#define ubidi_getMirror ubidi_getMirror_4_0 +#define ubidi_getParaLevel ubidi_getParaLevel_4_0 +#define ubidi_getParagraph ubidi_getParagraph_4_0 +#define ubidi_getParagraphByIndex ubidi_getParagraphByIndex_4_0 +#define ubidi_getProcessedLength ubidi_getProcessedLength_4_0 +#define ubidi_getReorderingMode ubidi_getReorderingMode_4_0 +#define ubidi_getReorderingOptions ubidi_getReorderingOptions_4_0 +#define ubidi_getResultLength ubidi_getResultLength_4_0 +#define ubidi_getRuns ubidi_getRuns_4_0 +#define ubidi_getSingleton ubidi_getSingleton_4_0 +#define ubidi_getText ubidi_getText_4_0 +#define ubidi_getVisualIndex ubidi_getVisualIndex_4_0 +#define ubidi_getVisualMap ubidi_getVisualMap_4_0 +#define ubidi_getVisualRun ubidi_getVisualRun_4_0 +#define ubidi_invertMap ubidi_invertMap_4_0 +#define ubidi_isBidiControl ubidi_isBidiControl_4_0 +#define ubidi_isInverse ubidi_isInverse_4_0 +#define ubidi_isJoinControl ubidi_isJoinControl_4_0 +#define ubidi_isMirrored ubidi_isMirrored_4_0 +#define ubidi_isOrderParagraphsLTR ubidi_isOrderParagraphsLTR_4_0 +#define ubidi_open ubidi_open_4_0 +#define ubidi_openSized ubidi_openSized_4_0 +#define ubidi_orderParagraphsLTR ubidi_orderParagraphsLTR_4_0 +#define ubidi_reorderLogical ubidi_reorderLogical_4_0 +#define ubidi_reorderVisual ubidi_reorderVisual_4_0 +#define ubidi_setClassCallback ubidi_setClassCallback_4_0 +#define ubidi_setInverse ubidi_setInverse_4_0 +#define ubidi_setLine ubidi_setLine_4_0 +#define ubidi_setPara ubidi_setPara_4_0 +#define ubidi_setReorderingMode ubidi_setReorderingMode_4_0 +#define ubidi_setReorderingOptions ubidi_setReorderingOptions_4_0 +#define ubidi_writeReordered ubidi_writeReordered_4_0 +#define ubidi_writeReverse ubidi_writeReverse_4_0 +#define ublock_getCode ublock_getCode_4_0 +#define ubrk_close ubrk_close_4_0 +#define ubrk_countAvailable ubrk_countAvailable_4_0 +#define ubrk_current ubrk_current_4_0 +#define ubrk_first ubrk_first_4_0 +#define ubrk_following ubrk_following_4_0 +#define ubrk_getAvailable ubrk_getAvailable_4_0 +#define ubrk_getLocaleByType ubrk_getLocaleByType_4_0 +#define ubrk_getRuleStatus ubrk_getRuleStatus_4_0 +#define ubrk_getRuleStatusVec ubrk_getRuleStatusVec_4_0 +#define ubrk_isBoundary ubrk_isBoundary_4_0 +#define ubrk_last ubrk_last_4_0 +#define ubrk_next ubrk_next_4_0 +#define ubrk_open ubrk_open_4_0 +#define ubrk_openRules ubrk_openRules_4_0 +#define ubrk_preceding ubrk_preceding_4_0 +#define ubrk_previous ubrk_previous_4_0 +#define ubrk_safeClone ubrk_safeClone_4_0 +#define ubrk_setText ubrk_setText_4_0 +#define ubrk_setUText ubrk_setUText_4_0 +#define ubrk_swap ubrk_swap_4_0 +#define ucal_add ucal_add_4_0 +#define ucal_clear ucal_clear_4_0 +#define ucal_clearField ucal_clearField_4_0 +#define ucal_clone ucal_clone_4_0 +#define ucal_close ucal_close_4_0 +#define ucal_countAvailable ucal_countAvailable_4_0 +#define ucal_equivalentTo ucal_equivalentTo_4_0 +#define ucal_get ucal_get_4_0 +#define ucal_getAttribute ucal_getAttribute_4_0 +#define ucal_getAvailable ucal_getAvailable_4_0 +#define ucal_getCanonicalTimeZoneID ucal_getCanonicalTimeZoneID_4_0 +#define ucal_getDSTSavings ucal_getDSTSavings_4_0 +#define ucal_getDefaultTimeZone ucal_getDefaultTimeZone_4_0 +#define ucal_getGregorianChange ucal_getGregorianChange_4_0 +#define ucal_getLimit ucal_getLimit_4_0 +#define ucal_getLocaleByType ucal_getLocaleByType_4_0 +#define ucal_getMillis ucal_getMillis_4_0 +#define ucal_getNow ucal_getNow_4_0 +#define ucal_getTZDataVersion ucal_getTZDataVersion_4_0 +#define ucal_getTimeZoneDisplayName ucal_getTimeZoneDisplayName_4_0 +#define ucal_inDaylightTime ucal_inDaylightTime_4_0 +#define ucal_isSet ucal_isSet_4_0 +#define ucal_open ucal_open_4_0 +#define ucal_openCountryTimeZones ucal_openCountryTimeZones_4_0 +#define ucal_openTimeZones ucal_openTimeZones_4_0 +#define ucal_roll ucal_roll_4_0 +#define ucal_set ucal_set_4_0 +#define ucal_setAttribute ucal_setAttribute_4_0 +#define ucal_setDate ucal_setDate_4_0 +#define ucal_setDateTime ucal_setDateTime_4_0 +#define ucal_setDefaultTimeZone ucal_setDefaultTimeZone_4_0 +#define ucal_setGregorianChange ucal_setGregorianChange_4_0 +#define ucal_setMillis ucal_setMillis_4_0 +#define ucal_setTimeZone ucal_setTimeZone_4_0 +#define ucase_addCaseClosure ucase_addCaseClosure_4_0 +#define ucase_addPropertyStarts ucase_addPropertyStarts_4_0 +#define ucase_addStringCaseClosure ucase_addStringCaseClosure_4_0 +#define ucase_close ucase_close_4_0 +#define ucase_fold ucase_fold_4_0 +#define ucase_getCaseLocale ucase_getCaseLocale_4_0 +#define ucase_getSingleton ucase_getSingleton_4_0 +#define ucase_getType ucase_getType_4_0 +#define ucase_getTypeOrIgnorable ucase_getTypeOrIgnorable_4_0 +#define ucase_hasBinaryProperty ucase_hasBinaryProperty_4_0 +#define ucase_isCaseSensitive ucase_isCaseSensitive_4_0 +#define ucase_isSoftDotted ucase_isSoftDotted_4_0 +#define ucase_toFullFolding ucase_toFullFolding_4_0 +#define ucase_toFullLower ucase_toFullLower_4_0 +#define ucase_toFullTitle ucase_toFullTitle_4_0 +#define ucase_toFullUpper ucase_toFullUpper_4_0 +#define ucase_tolower ucase_tolower_4_0 +#define ucase_totitle ucase_totitle_4_0 +#define ucase_toupper ucase_toupper_4_0 +#define ucasemap_close ucasemap_close_4_0 +#define ucasemap_getBreakIterator ucasemap_getBreakIterator_4_0 +#define ucasemap_getLocale ucasemap_getLocale_4_0 +#define ucasemap_getOptions ucasemap_getOptions_4_0 +#define ucasemap_open ucasemap_open_4_0 +#define ucasemap_setBreakIterator ucasemap_setBreakIterator_4_0 +#define ucasemap_setLocale ucasemap_setLocale_4_0 +#define ucasemap_setOptions ucasemap_setOptions_4_0 +#define ucasemap_toTitle ucasemap_toTitle_4_0 +#define ucasemap_utf8FoldCase ucasemap_utf8FoldCase_4_0 +#define ucasemap_utf8ToLower ucasemap_utf8ToLower_4_0 +#define ucasemap_utf8ToTitle ucasemap_utf8ToTitle_4_0 +#define ucasemap_utf8ToUpper ucasemap_utf8ToUpper_4_0 +#define uchar_addPropertyStarts uchar_addPropertyStarts_4_0 +#define uchar_getHST uchar_getHST_4_0 +#define uchar_swapNames uchar_swapNames_4_0 +#define ucln_common_registerCleanup ucln_common_registerCleanup_4_0 +#define ucln_i18n_registerCleanup ucln_i18n_registerCleanup_4_0 +#define ucln_io_registerCleanup ucln_io_registerCleanup_4_0 +#define ucln_lib_cleanup ucln_lib_cleanup_4_0 +#define ucln_registerCleanup ucln_registerCleanup_4_0 +#define ucnv_MBCSFromUChar32 ucnv_MBCSFromUChar32_4_0 +#define ucnv_MBCSFromUnicodeWithOffsets ucnv_MBCSFromUnicodeWithOffsets_4_0 +#define ucnv_MBCSGetFilteredUnicodeSetForUnicode ucnv_MBCSGetFilteredUnicodeSetForUnicode_4_0 +#define ucnv_MBCSGetType ucnv_MBCSGetType_4_0 +#define ucnv_MBCSGetUnicodeSetForUnicode ucnv_MBCSGetUnicodeSetForUnicode_4_0 +#define ucnv_MBCSIsLeadByte ucnv_MBCSIsLeadByte_4_0 +#define ucnv_MBCSSimpleGetNextUChar ucnv_MBCSSimpleGetNextUChar_4_0 +#define ucnv_MBCSToUnicodeWithOffsets ucnv_MBCSToUnicodeWithOffsets_4_0 +#define ucnv_bld_countAvailableConverters ucnv_bld_countAvailableConverters_4_0 +#define ucnv_bld_getAvailableConverter ucnv_bld_getAvailableConverter_4_0 +#define ucnv_cbFromUWriteBytes ucnv_cbFromUWriteBytes_4_0 +#define ucnv_cbFromUWriteSub ucnv_cbFromUWriteSub_4_0 +#define ucnv_cbFromUWriteUChars ucnv_cbFromUWriteUChars_4_0 +#define ucnv_cbToUWriteSub ucnv_cbToUWriteSub_4_0 +#define ucnv_cbToUWriteUChars ucnv_cbToUWriteUChars_4_0 +#define ucnv_close ucnv_close_4_0 +#define ucnv_compareNames ucnv_compareNames_4_0 +#define ucnv_convert ucnv_convert_4_0 +#define ucnv_convertEx ucnv_convertEx_4_0 +#define ucnv_countAliases ucnv_countAliases_4_0 +#define ucnv_countAvailable ucnv_countAvailable_4_0 +#define ucnv_countStandards ucnv_countStandards_4_0 +#define ucnv_createAlgorithmicConverter ucnv_createAlgorithmicConverter_4_0 +#define ucnv_createConverter ucnv_createConverter_4_0 +#define ucnv_createConverterFromPackage ucnv_createConverterFromPackage_4_0 +#define ucnv_createConverterFromSharedData ucnv_createConverterFromSharedData_4_0 +#define ucnv_detectUnicodeSignature ucnv_detectUnicodeSignature_4_0 +#define ucnv_extContinueMatchFromU ucnv_extContinueMatchFromU_4_0 +#define ucnv_extContinueMatchToU ucnv_extContinueMatchToU_4_0 +#define ucnv_extGetUnicodeSet ucnv_extGetUnicodeSet_4_0 +#define ucnv_extInitialMatchFromU ucnv_extInitialMatchFromU_4_0 +#define ucnv_extInitialMatchToU ucnv_extInitialMatchToU_4_0 +#define ucnv_extSimpleMatchFromU ucnv_extSimpleMatchFromU_4_0 +#define ucnv_extSimpleMatchToU ucnv_extSimpleMatchToU_4_0 +#define ucnv_fixFileSeparator ucnv_fixFileSeparator_4_0 +#define ucnv_flushCache ucnv_flushCache_4_0 +#define ucnv_fromAlgorithmic ucnv_fromAlgorithmic_4_0 +#define ucnv_fromUChars ucnv_fromUChars_4_0 +#define ucnv_fromUCountPending ucnv_fromUCountPending_4_0 +#define ucnv_fromUWriteBytes ucnv_fromUWriteBytes_4_0 +#define ucnv_fromUnicode ucnv_fromUnicode_4_0 +#define ucnv_fromUnicode_UTF8 ucnv_fromUnicode_UTF8_4_0 +#define ucnv_fromUnicode_UTF8_OFFSETS_LOGIC ucnv_fromUnicode_UTF8_OFFSETS_LOGIC_4_0 +#define ucnv_getAlias ucnv_getAlias_4_0 +#define ucnv_getAliases ucnv_getAliases_4_0 +#define ucnv_getAvailableName ucnv_getAvailableName_4_0 +#define ucnv_getCCSID ucnv_getCCSID_4_0 +#define ucnv_getCanonicalName ucnv_getCanonicalName_4_0 +#define ucnv_getCompleteUnicodeSet ucnv_getCompleteUnicodeSet_4_0 +#define ucnv_getDefaultName ucnv_getDefaultName_4_0 +#define ucnv_getDisplayName ucnv_getDisplayName_4_0 +#define ucnv_getFromUCallBack ucnv_getFromUCallBack_4_0 +#define ucnv_getInvalidChars ucnv_getInvalidChars_4_0 +#define ucnv_getInvalidUChars ucnv_getInvalidUChars_4_0 +#define ucnv_getMaxCharSize ucnv_getMaxCharSize_4_0 +#define ucnv_getMinCharSize ucnv_getMinCharSize_4_0 +#define ucnv_getName ucnv_getName_4_0 +#define ucnv_getNextUChar ucnv_getNextUChar_4_0 +#define ucnv_getNonSurrogateUnicodeSet ucnv_getNonSurrogateUnicodeSet_4_0 +#define ucnv_getPlatform ucnv_getPlatform_4_0 +#define ucnv_getStandard ucnv_getStandard_4_0 +#define ucnv_getStandardName ucnv_getStandardName_4_0 +#define ucnv_getStarters ucnv_getStarters_4_0 +#define ucnv_getSubstChars ucnv_getSubstChars_4_0 +#define ucnv_getToUCallBack ucnv_getToUCallBack_4_0 +#define ucnv_getType ucnv_getType_4_0 +#define ucnv_getUnicodeSet ucnv_getUnicodeSet_4_0 +#define ucnv_incrementRefCount ucnv_incrementRefCount_4_0 +#define ucnv_io_countKnownConverters ucnv_io_countKnownConverters_4_0 +#define ucnv_io_getConverterName ucnv_io_getConverterName_4_0 +#define ucnv_io_stripASCIIForCompare ucnv_io_stripASCIIForCompare_4_0 +#define ucnv_io_stripEBCDICForCompare ucnv_io_stripEBCDICForCompare_4_0 +#define ucnv_isAmbiguous ucnv_isAmbiguous_4_0 +#define ucnv_load ucnv_load_4_0 +#define ucnv_loadSharedData ucnv_loadSharedData_4_0 +#define ucnv_open ucnv_open_4_0 +#define ucnv_openAllNames ucnv_openAllNames_4_0 +#define ucnv_openCCSID ucnv_openCCSID_4_0 +#define ucnv_openPackage ucnv_openPackage_4_0 +#define ucnv_openStandardNames ucnv_openStandardNames_4_0 +#define ucnv_openU ucnv_openU_4_0 +#define ucnv_reset ucnv_reset_4_0 +#define ucnv_resetFromUnicode ucnv_resetFromUnicode_4_0 +#define ucnv_resetToUnicode ucnv_resetToUnicode_4_0 +#define ucnv_safeClone ucnv_safeClone_4_0 +#define ucnv_setDefaultName ucnv_setDefaultName_4_0 +#define ucnv_setFallback ucnv_setFallback_4_0 +#define ucnv_setFromUCallBack ucnv_setFromUCallBack_4_0 +#define ucnv_setSubstChars ucnv_setSubstChars_4_0 +#define ucnv_setSubstString ucnv_setSubstString_4_0 +#define ucnv_setToUCallBack ucnv_setToUCallBack_4_0 +#define ucnv_swap ucnv_swap_4_0 +#define ucnv_swapAliases ucnv_swapAliases_4_0 +#define ucnv_toAlgorithmic ucnv_toAlgorithmic_4_0 +#define ucnv_toUChars ucnv_toUChars_4_0 +#define ucnv_toUCountPending ucnv_toUCountPending_4_0 +#define ucnv_toUWriteCodePoint ucnv_toUWriteCodePoint_4_0 +#define ucnv_toUWriteUChars ucnv_toUWriteUChars_4_0 +#define ucnv_toUnicode ucnv_toUnicode_4_0 +#define ucnv_unload ucnv_unload_4_0 +#define ucnv_unloadSharedDataIfReady ucnv_unloadSharedDataIfReady_4_0 +#define ucnv_usesFallback ucnv_usesFallback_4_0 +#define ucol_allocWeights ucol_allocWeights_4_0 +#define ucol_assembleTailoringTable ucol_assembleTailoringTable_4_0 +#define ucol_calcSortKey ucol_calcSortKey_4_0 +#define ucol_calcSortKeySimpleTertiary ucol_calcSortKeySimpleTertiary_4_0 +#define ucol_cloneBinary ucol_cloneBinary_4_0 +#define ucol_cloneRuleData ucol_cloneRuleData_4_0 +#define ucol_close ucol_close_4_0 +#define ucol_closeElements ucol_closeElements_4_0 +#define ucol_countAvailable ucol_countAvailable_4_0 +#define ucol_createElements ucol_createElements_4_0 +#define ucol_doCE ucol_doCE_4_0 +#define ucol_equal ucol_equal_4_0 +#define ucol_equals ucol_equals_4_0 +#define ucol_forgetUCA ucol_forgetUCA_4_0 +#define ucol_getAttribute ucol_getAttribute_4_0 +#define ucol_getAttributeOrDefault ucol_getAttributeOrDefault_4_0 +#define ucol_getAvailable ucol_getAvailable_4_0 +#define ucol_getBound ucol_getBound_4_0 +#define ucol_getCEStrengthDifference ucol_getCEStrengthDifference_4_0 +#define ucol_getContractions ucol_getContractions_4_0 +#define ucol_getContractionsAndExpansions ucol_getContractionsAndExpansions_4_0 +#define ucol_getDisplayName ucol_getDisplayName_4_0 +#define ucol_getFirstCE ucol_getFirstCE_4_0 +#define ucol_getFunctionalEquivalent ucol_getFunctionalEquivalent_4_0 +#define ucol_getKeywordValues ucol_getKeywordValues_4_0 +#define ucol_getKeywords ucol_getKeywords_4_0 +#define ucol_getLocale ucol_getLocale_4_0 +#define ucol_getLocaleByType ucol_getLocaleByType_4_0 +#define ucol_getMaxExpansion ucol_getMaxExpansion_4_0 +#define ucol_getNextCE ucol_getNextCE_4_0 +#define ucol_getOffset ucol_getOffset_4_0 +#define ucol_getPrevCE ucol_getPrevCE_4_0 +#define ucol_getRules ucol_getRules_4_0 +#define ucol_getRulesEx ucol_getRulesEx_4_0 +#define ucol_getShortDefinitionString ucol_getShortDefinitionString_4_0 +#define ucol_getSortKey ucol_getSortKey_4_0 +#define ucol_getSortKeySize ucol_getSortKeySize_4_0 +#define ucol_getSortKeyWithAllocation ucol_getSortKeyWithAllocation_4_0 +#define ucol_getStrength ucol_getStrength_4_0 +#define ucol_getTailoredSet ucol_getTailoredSet_4_0 +#define ucol_getUCAVersion ucol_getUCAVersion_4_0 +#define ucol_getUnsafeSet ucol_getUnsafeSet_4_0 +#define ucol_getVariableTop ucol_getVariableTop_4_0 +#define ucol_getVersion ucol_getVersion_4_0 +#define ucol_greater ucol_greater_4_0 +#define ucol_greaterOrEqual ucol_greaterOrEqual_4_0 +#define ucol_initBuffers ucol_initBuffers_4_0 +#define ucol_initCollator ucol_initCollator_4_0 +#define ucol_initInverseUCA ucol_initInverseUCA_4_0 +#define ucol_initUCA ucol_initUCA_4_0 +#define ucol_inv_getNextCE ucol_inv_getNextCE_4_0 +#define ucol_inv_getPrevCE ucol_inv_getPrevCE_4_0 +#define ucol_isTailored ucol_isTailored_4_0 +#define ucol_keyHashCode ucol_keyHashCode_4_0 +#define ucol_mergeSortkeys ucol_mergeSortkeys_4_0 +#define ucol_next ucol_next_4_0 +#define ucol_nextProcessed ucol_nextProcessed_4_0 +#define ucol_nextSortKeyPart ucol_nextSortKeyPart_4_0 +#define ucol_nextWeight ucol_nextWeight_4_0 +#define ucol_normalizeShortDefinitionString ucol_normalizeShortDefinitionString_4_0 +#define ucol_open ucol_open_4_0 +#define ucol_openAvailableLocales ucol_openAvailableLocales_4_0 +#define ucol_openBinary ucol_openBinary_4_0 +#define ucol_openElements ucol_openElements_4_0 +#define ucol_openFromShortString ucol_openFromShortString_4_0 +#define ucol_openRules ucol_openRules_4_0 +#define ucol_open_internal ucol_open_internal_4_0 +#define ucol_prepareShortStringOpen ucol_prepareShortStringOpen_4_0 +#define ucol_previous ucol_previous_4_0 +#define ucol_previousProcessed ucol_previousProcessed_4_0 +#define ucol_primaryOrder ucol_primaryOrder_4_0 +#define ucol_prv_getSpecialCE ucol_prv_getSpecialCE_4_0 +#define ucol_prv_getSpecialPrevCE ucol_prv_getSpecialPrevCE_4_0 +#define ucol_reset ucol_reset_4_0 +#define ucol_restoreVariableTop ucol_restoreVariableTop_4_0 +#define ucol_safeClone ucol_safeClone_4_0 +#define ucol_secondaryOrder ucol_secondaryOrder_4_0 +#define ucol_setAttribute ucol_setAttribute_4_0 +#define ucol_setOffset ucol_setOffset_4_0 +#define ucol_setOptionsFromHeader ucol_setOptionsFromHeader_4_0 +#define ucol_setReqValidLocales ucol_setReqValidLocales_4_0 +#define ucol_setStrength ucol_setStrength_4_0 +#define ucol_setText ucol_setText_4_0 +#define ucol_setVariableTop ucol_setVariableTop_4_0 +#define ucol_strcoll ucol_strcoll_4_0 +#define ucol_strcollIter ucol_strcollIter_4_0 +#define ucol_swap ucol_swap_4_0 +#define ucol_swapBinary ucol_swapBinary_4_0 +#define ucol_swapInverseUCA ucol_swapInverseUCA_4_0 +#define ucol_tertiaryOrder ucol_tertiaryOrder_4_0 +#define ucol_tok_assembleTokenList ucol_tok_assembleTokenList_4_0 +#define ucol_tok_closeTokenList ucol_tok_closeTokenList_4_0 +#define ucol_tok_getNextArgument ucol_tok_getNextArgument_4_0 +#define ucol_tok_initTokenList ucol_tok_initTokenList_4_0 +#define ucol_tok_parseNextToken ucol_tok_parseNextToken_4_0 +#define ucol_updateInternalState ucol_updateInternalState_4_0 +#define ucsdet_close ucsdet_close_4_0 +#define ucsdet_detect ucsdet_detect_4_0 +#define ucsdet_detectAll ucsdet_detectAll_4_0 +#define ucsdet_enableInputFilter ucsdet_enableInputFilter_4_0 +#define ucsdet_getAllDetectableCharsets ucsdet_getAllDetectableCharsets_4_0 +#define ucsdet_getConfidence ucsdet_getConfidence_4_0 +#define ucsdet_getLanguage ucsdet_getLanguage_4_0 +#define ucsdet_getName ucsdet_getName_4_0 +#define ucsdet_getUChars ucsdet_getUChars_4_0 +#define ucsdet_isInputFilterEnabled ucsdet_isInputFilterEnabled_4_0 +#define ucsdet_open ucsdet_open_4_0 +#define ucsdet_setDeclaredEncoding ucsdet_setDeclaredEncoding_4_0 +#define ucsdet_setText ucsdet_setText_4_0 +#define ucurr_countCurrencies ucurr_countCurrencies_4_0 +#define ucurr_forLocale ucurr_forLocale_4_0 +#define ucurr_forLocaleAndDate ucurr_forLocaleAndDate_4_0 +#define ucurr_getDefaultFractionDigits ucurr_getDefaultFractionDigits_4_0 +#define ucurr_getName ucurr_getName_4_0 +#define ucurr_getRoundingIncrement ucurr_getRoundingIncrement_4_0 +#define ucurr_openISOCurrencies ucurr_openISOCurrencies_4_0 +#define ucurr_register ucurr_register_4_0 +#define ucurr_unregister ucurr_unregister_4_0 +#define udat_applyPattern udat_applyPattern_4_0 +#define udat_clone udat_clone_4_0 +#define udat_close udat_close_4_0 +#define udat_countAvailable udat_countAvailable_4_0 +#define udat_countSymbols udat_countSymbols_4_0 +#define udat_format udat_format_4_0 +#define udat_get2DigitYearStart udat_get2DigitYearStart_4_0 +#define udat_getAvailable udat_getAvailable_4_0 +#define udat_getCalendar udat_getCalendar_4_0 +#define udat_getLocaleByType udat_getLocaleByType_4_0 +#define udat_getNumberFormat udat_getNumberFormat_4_0 +#define udat_getSymbols udat_getSymbols_4_0 +#define udat_isLenient udat_isLenient_4_0 +#define udat_open udat_open_4_0 +#define udat_parse udat_parse_4_0 +#define udat_parseCalendar udat_parseCalendar_4_0 +#define udat_set2DigitYearStart udat_set2DigitYearStart_4_0 +#define udat_setCalendar udat_setCalendar_4_0 +#define udat_setLenient udat_setLenient_4_0 +#define udat_setNumberFormat udat_setNumberFormat_4_0 +#define udat_setSymbols udat_setSymbols_4_0 +#define udat_toPattern udat_toPattern_4_0 +#define udata_checkCommonData udata_checkCommonData_4_0 +#define udata_close udata_close_4_0 +#define udata_closeSwapper udata_closeSwapper_4_0 +#define udata_getHeaderSize udata_getHeaderSize_4_0 +#define udata_getInfo udata_getInfo_4_0 +#define udata_getInfoSize udata_getInfoSize_4_0 +#define udata_getLength udata_getLength_4_0 +#define udata_getMemory udata_getMemory_4_0 +#define udata_getRawMemory udata_getRawMemory_4_0 +#define udata_open udata_open_4_0 +#define udata_openChoice udata_openChoice_4_0 +#define udata_openSwapper udata_openSwapper_4_0 +#define udata_openSwapperForInputData udata_openSwapperForInputData_4_0 +#define udata_printError udata_printError_4_0 +#define udata_readInt16 udata_readInt16_4_0 +#define udata_readInt32 udata_readInt32_4_0 +#define udata_setAppData udata_setAppData_4_0 +#define udata_setCommonData udata_setCommonData_4_0 +#define udata_setFileAccess udata_setFileAccess_4_0 +#define udata_swapDataHeader udata_swapDataHeader_4_0 +#define udata_swapInvStringBlock udata_swapInvStringBlock_4_0 +#define udatpg_addPattern udatpg_addPattern_4_0 +#define udatpg_clone udatpg_clone_4_0 +#define udatpg_close udatpg_close_4_0 +#define udatpg_getAppendItemFormat udatpg_getAppendItemFormat_4_0 +#define udatpg_getAppendItemName udatpg_getAppendItemName_4_0 +#define udatpg_getBaseSkeleton udatpg_getBaseSkeleton_4_0 +#define udatpg_getBestPattern udatpg_getBestPattern_4_0 +#define udatpg_getDateTimeFormat udatpg_getDateTimeFormat_4_0 +#define udatpg_getDecimal udatpg_getDecimal_4_0 +#define udatpg_getPatternForSkeleton udatpg_getPatternForSkeleton_4_0 +#define udatpg_getSkeleton udatpg_getSkeleton_4_0 +#define udatpg_open udatpg_open_4_0 +#define udatpg_openBaseSkeletons udatpg_openBaseSkeletons_4_0 +#define udatpg_openEmpty udatpg_openEmpty_4_0 +#define udatpg_openSkeletons udatpg_openSkeletons_4_0 +#define udatpg_replaceFieldTypes udatpg_replaceFieldTypes_4_0 +#define udatpg_setAppendItemFormat udatpg_setAppendItemFormat_4_0 +#define udatpg_setAppendItemName udatpg_setAppendItemName_4_0 +#define udatpg_setDateTimeFormat udatpg_setDateTimeFormat_4_0 +#define udatpg_setDecimal udatpg_setDecimal_4_0 +#define uenum_close uenum_close_4_0 +#define uenum_count uenum_count_4_0 +#define uenum_next uenum_next_4_0 +#define uenum_nextDefault uenum_nextDefault_4_0 +#define uenum_openCharStringsEnumeration uenum_openCharStringsEnumeration_4_0 +#define uenum_openStringEnumeration uenum_openStringEnumeration_4_0 +#define uenum_reset uenum_reset_4_0 +#define uenum_unext uenum_unext_4_0 +#define uenum_unextDefault uenum_unextDefault_4_0 +#define ufile_close_translit ufile_close_translit_4_0 +#define ufile_fill_uchar_buffer ufile_fill_uchar_buffer_4_0 +#define ufile_flush_translit ufile_flush_translit_4_0 +#define ufile_getch ufile_getch_4_0 +#define ufile_getch32 ufile_getch32_4_0 +#define ufmt_64tou ufmt_64tou_4_0 +#define ufmt_defaultCPToUnicode ufmt_defaultCPToUnicode_4_0 +#define ufmt_digitvalue ufmt_digitvalue_4_0 +#define ufmt_isdigit ufmt_isdigit_4_0 +#define ufmt_ptou ufmt_ptou_4_0 +#define ufmt_uto64 ufmt_uto64_4_0 +#define ufmt_utop ufmt_utop_4_0 +#define uhash_close uhash_close_4_0 +#define uhash_compareCaselessUnicodeString uhash_compareCaselessUnicodeString_4_0 +#define uhash_compareChars uhash_compareChars_4_0 +#define uhash_compareIChars uhash_compareIChars_4_0 +#define uhash_compareLong uhash_compareLong_4_0 +#define uhash_compareUChars uhash_compareUChars_4_0 +#define uhash_compareUnicodeString uhash_compareUnicodeString_4_0 +#define uhash_count uhash_count_4_0 +#define uhash_deleteHashtable uhash_deleteHashtable_4_0 +#define uhash_deleteUVector uhash_deleteUVector_4_0 +#define uhash_deleteUnicodeString uhash_deleteUnicodeString_4_0 +#define uhash_equals uhash_equals_4_0 +#define uhash_find uhash_find_4_0 +#define uhash_freeBlock uhash_freeBlock_4_0 +#define uhash_get uhash_get_4_0 +#define uhash_geti uhash_geti_4_0 +#define uhash_hashCaselessUnicodeString uhash_hashCaselessUnicodeString_4_0 +#define uhash_hashChars uhash_hashChars_4_0 +#define uhash_hashIChars uhash_hashIChars_4_0 +#define uhash_hashLong uhash_hashLong_4_0 +#define uhash_hashUChars uhash_hashUChars_4_0 +#define uhash_hashUCharsN uhash_hashUCharsN_4_0 +#define uhash_hashUnicodeString uhash_hashUnicodeString_4_0 +#define uhash_iget uhash_iget_4_0 +#define uhash_igeti uhash_igeti_4_0 +#define uhash_init uhash_init_4_0 +#define uhash_iput uhash_iput_4_0 +#define uhash_iputi uhash_iputi_4_0 +#define uhash_iremove uhash_iremove_4_0 +#define uhash_iremovei uhash_iremovei_4_0 +#define uhash_nextElement uhash_nextElement_4_0 +#define uhash_open uhash_open_4_0 +#define uhash_openSize uhash_openSize_4_0 +#define uhash_put uhash_put_4_0 +#define uhash_puti uhash_puti_4_0 +#define uhash_remove uhash_remove_4_0 +#define uhash_removeAll uhash_removeAll_4_0 +#define uhash_removeElement uhash_removeElement_4_0 +#define uhash_removei uhash_removei_4_0 +#define uhash_setKeyComparator uhash_setKeyComparator_4_0 +#define uhash_setKeyDeleter uhash_setKeyDeleter_4_0 +#define uhash_setKeyHasher uhash_setKeyHasher_4_0 +#define uhash_setResizePolicy uhash_setResizePolicy_4_0 +#define uhash_setValueComparator uhash_setValueComparator_4_0 +#define uhash_setValueDeleter uhash_setValueDeleter_4_0 +#define uhst_addPropertyStarts uhst_addPropertyStarts_4_0 +#define uidna_IDNToASCII uidna_IDNToASCII_4_0 +#define uidna_IDNToUnicode uidna_IDNToUnicode_4_0 +#define uidna_compare uidna_compare_4_0 +#define uidna_toASCII uidna_toASCII_4_0 +#define uidna_toUnicode uidna_toUnicode_4_0 +#define uiter_current32 uiter_current32_4_0 +#define uiter_getState uiter_getState_4_0 +#define uiter_next32 uiter_next32_4_0 +#define uiter_previous32 uiter_previous32_4_0 +#define uiter_setCharacterIterator uiter_setCharacterIterator_4_0 +#define uiter_setReplaceable uiter_setReplaceable_4_0 +#define uiter_setState uiter_setState_4_0 +#define uiter_setString uiter_setString_4_0 +#define uiter_setUTF16BE uiter_setUTF16BE_4_0 +#define uiter_setUTF8 uiter_setUTF8_4_0 +#define uloc_acceptLanguage uloc_acceptLanguage_4_0 +#define uloc_acceptLanguageFromHTTP uloc_acceptLanguageFromHTTP_4_0 +#define uloc_addLikelySubtags uloc_addLikelySubtags_4_0 +#define uloc_canonicalize uloc_canonicalize_4_0 +#define uloc_countAvailable uloc_countAvailable_4_0 +#define uloc_getAvailable uloc_getAvailable_4_0 +#define uloc_getBaseName uloc_getBaseName_4_0 +#define uloc_getCharacterOrientation uloc_getCharacterOrientation_4_0 +#define uloc_getCountry uloc_getCountry_4_0 +#define uloc_getDefault uloc_getDefault_4_0 +#define uloc_getDisplayCountry uloc_getDisplayCountry_4_0 +#define uloc_getDisplayKeyword uloc_getDisplayKeyword_4_0 +#define uloc_getDisplayKeywordValue uloc_getDisplayKeywordValue_4_0 +#define uloc_getDisplayLanguage uloc_getDisplayLanguage_4_0 +#define uloc_getDisplayName uloc_getDisplayName_4_0 +#define uloc_getDisplayScript uloc_getDisplayScript_4_0 +#define uloc_getDisplayVariant uloc_getDisplayVariant_4_0 +#define uloc_getISO3Country uloc_getISO3Country_4_0 +#define uloc_getISO3Language uloc_getISO3Language_4_0 +#define uloc_getISOCountries uloc_getISOCountries_4_0 +#define uloc_getISOLanguages uloc_getISOLanguages_4_0 +#define uloc_getKeywordValue uloc_getKeywordValue_4_0 +#define uloc_getLCID uloc_getLCID_4_0 +#define uloc_getLanguage uloc_getLanguage_4_0 +#define uloc_getLineOrientation uloc_getLineOrientation_4_0 +#define uloc_getLocaleForLCID uloc_getLocaleForLCID_4_0 +#define uloc_getName uloc_getName_4_0 +#define uloc_getParent uloc_getParent_4_0 +#define uloc_getScript uloc_getScript_4_0 +#define uloc_getVariant uloc_getVariant_4_0 +#define uloc_minimizeSubtags uloc_minimizeSubtags_4_0 +#define uloc_openKeywordList uloc_openKeywordList_4_0 +#define uloc_openKeywords uloc_openKeywords_4_0 +#define uloc_setDefault uloc_setDefault_4_0 +#define uloc_setKeywordValue uloc_setKeywordValue_4_0 +#define ulocdata_close ulocdata_close_4_0 +#define ulocdata_getDelimiter ulocdata_getDelimiter_4_0 +#define ulocdata_getExemplarSet ulocdata_getExemplarSet_4_0 +#define ulocdata_getMeasurementSystem ulocdata_getMeasurementSystem_4_0 +#define ulocdata_getNoSubstitute ulocdata_getNoSubstitute_4_0 +#define ulocdata_getPaperSize ulocdata_getPaperSize_4_0 +#define ulocdata_open ulocdata_open_4_0 +#define ulocdata_setNoSubstitute ulocdata_setNoSubstitute_4_0 +#define umsg_applyPattern umsg_applyPattern_4_0 +#define umsg_autoQuoteApostrophe umsg_autoQuoteApostrophe_4_0 +#define umsg_clone umsg_clone_4_0 +#define umsg_close umsg_close_4_0 +#define umsg_format umsg_format_4_0 +#define umsg_getLocale umsg_getLocale_4_0 +#define umsg_open umsg_open_4_0 +#define umsg_parse umsg_parse_4_0 +#define umsg_setLocale umsg_setLocale_4_0 +#define umsg_toPattern umsg_toPattern_4_0 +#define umsg_vformat umsg_vformat_4_0 +#define umsg_vparse umsg_vparse_4_0 +#define umtx_atomic_dec umtx_atomic_dec_4_0 +#define umtx_atomic_inc umtx_atomic_inc_4_0 +#define umtx_cleanup umtx_cleanup_4_0 +#define umtx_destroy umtx_destroy_4_0 +#define umtx_init umtx_init_4_0 +#define umtx_lock umtx_lock_4_0 +#define umtx_unlock umtx_unlock_4_0 +#define unorm_addPropertyStarts unorm_addPropertyStarts_4_0 +#define unorm_closeIter unorm_closeIter_4_0 +#define unorm_compare unorm_compare_4_0 +#define unorm_compose unorm_compose_4_0 +#define unorm_concatenate unorm_concatenate_4_0 +#define unorm_decompose unorm_decompose_4_0 +#define unorm_getCanonStartSet unorm_getCanonStartSet_4_0 +#define unorm_getCanonicalDecomposition unorm_getCanonicalDecomposition_4_0 +#define unorm_getDecomposition unorm_getDecomposition_4_0 +#define unorm_getFCD16FromCodePoint unorm_getFCD16FromCodePoint_4_0 +#define unorm_getFCDTrie unorm_getFCDTrie_4_0 +#define unorm_getNX unorm_getNX_4_0 +#define unorm_getQuickCheck unorm_getQuickCheck_4_0 +#define unorm_getUnicodeVersion unorm_getUnicodeVersion_4_0 +#define unorm_haveData unorm_haveData_4_0 +#define unorm_internalIsFullCompositionExclusion unorm_internalIsFullCompositionExclusion_4_0 +#define unorm_internalNormalize unorm_internalNormalize_4_0 +#define unorm_internalNormalizeWithNX unorm_internalNormalizeWithNX_4_0 +#define unorm_internalQuickCheck unorm_internalQuickCheck_4_0 +#define unorm_isCanonSafeStart unorm_isCanonSafeStart_4_0 +#define unorm_isNFSkippable unorm_isNFSkippable_4_0 +#define unorm_isNormalized unorm_isNormalized_4_0 +#define unorm_isNormalizedWithOptions unorm_isNormalizedWithOptions_4_0 +#define unorm_next unorm_next_4_0 +#define unorm_normalize unorm_normalize_4_0 +#define unorm_openIter unorm_openIter_4_0 +#define unorm_previous unorm_previous_4_0 +#define unorm_quickCheck unorm_quickCheck_4_0 +#define unorm_quickCheckWithOptions unorm_quickCheckWithOptions_4_0 +#define unorm_setIter unorm_setIter_4_0 +#define unum_applyPattern unum_applyPattern_4_0 +#define unum_clone unum_clone_4_0 +#define unum_close unum_close_4_0 +#define unum_countAvailable unum_countAvailable_4_0 +#define unum_format unum_format_4_0 +#define unum_formatDouble unum_formatDouble_4_0 +#define unum_formatDoubleCurrency unum_formatDoubleCurrency_4_0 +#define unum_formatInt64 unum_formatInt64_4_0 +#define unum_getAttribute unum_getAttribute_4_0 +#define unum_getAvailable unum_getAvailable_4_0 +#define unum_getDoubleAttribute unum_getDoubleAttribute_4_0 +#define unum_getLocaleByType unum_getLocaleByType_4_0 +#define unum_getSymbol unum_getSymbol_4_0 +#define unum_getTextAttribute unum_getTextAttribute_4_0 +#define unum_open unum_open_4_0 +#define unum_parse unum_parse_4_0 +#define unum_parseDouble unum_parseDouble_4_0 +#define unum_parseDoubleCurrency unum_parseDoubleCurrency_4_0 +#define unum_parseInt64 unum_parseInt64_4_0 +#define unum_setAttribute unum_setAttribute_4_0 +#define unum_setDoubleAttribute unum_setDoubleAttribute_4_0 +#define unum_setSymbol unum_setSymbol_4_0 +#define unum_setTextAttribute unum_setTextAttribute_4_0 +#define unum_toPattern unum_toPattern_4_0 +#define upname_swap upname_swap_4_0 +#define uprops_getSource uprops_getSource_4_0 +#define upropsvec_addPropertyStarts upropsvec_addPropertyStarts_4_0 +#define uprv_asciiFromEbcdic uprv_asciiFromEbcdic_4_0 +#define uprv_asciitolower uprv_asciitolower_4_0 +#define uprv_ceil uprv_ceil_4_0 +#define uprv_cnttab_addContraction uprv_cnttab_addContraction_4_0 +#define uprv_cnttab_changeContraction uprv_cnttab_changeContraction_4_0 +#define uprv_cnttab_changeLastCE uprv_cnttab_changeLastCE_4_0 +#define uprv_cnttab_clone uprv_cnttab_clone_4_0 +#define uprv_cnttab_close uprv_cnttab_close_4_0 +#define uprv_cnttab_constructTable uprv_cnttab_constructTable_4_0 +#define uprv_cnttab_findCE uprv_cnttab_findCE_4_0 +#define uprv_cnttab_findCP uprv_cnttab_findCP_4_0 +#define uprv_cnttab_getCE uprv_cnttab_getCE_4_0 +#define uprv_cnttab_insertContraction uprv_cnttab_insertContraction_4_0 +#define uprv_cnttab_isTailored uprv_cnttab_isTailored_4_0 +#define uprv_cnttab_open uprv_cnttab_open_4_0 +#define uprv_cnttab_setContraction uprv_cnttab_setContraction_4_0 +#define uprv_compareASCIIPropertyNames uprv_compareASCIIPropertyNames_4_0 +#define uprv_compareEBCDICPropertyNames uprv_compareEBCDICPropertyNames_4_0 +#define uprv_compareInvAscii uprv_compareInvAscii_4_0 +#define uprv_compareInvEbcdic uprv_compareInvEbcdic_4_0 +#define uprv_convertToLCID uprv_convertToLCID_4_0 +#define uprv_convertToPosix uprv_convertToPosix_4_0 +#define uprv_copyAscii uprv_copyAscii_4_0 +#define uprv_copyEbcdic uprv_copyEbcdic_4_0 +#define uprv_ebcdicFromAscii uprv_ebcdicFromAscii_4_0 +#define uprv_ebcdictolower uprv_ebcdictolower_4_0 +#define uprv_fabs uprv_fabs_4_0 +#define uprv_floor uprv_floor_4_0 +#define uprv_fmax uprv_fmax_4_0 +#define uprv_fmin uprv_fmin_4_0 +#define uprv_fmod uprv_fmod_4_0 +#define uprv_free uprv_free_4_0 +#define uprv_getCharNameCharacters uprv_getCharNameCharacters_4_0 +#define uprv_getDefaultCodepage uprv_getDefaultCodepage_4_0 +#define uprv_getDefaultLocaleID uprv_getDefaultLocaleID_4_0 +#define uprv_getInfinity uprv_getInfinity_4_0 +#define uprv_getMaxCharNameLength uprv_getMaxCharNameLength_4_0 +#define uprv_getMaxValues uprv_getMaxValues_4_0 +#define uprv_getNaN uprv_getNaN_4_0 +#define uprv_getStaticCurrencyName uprv_getStaticCurrencyName_4_0 +#define uprv_getUTCtime uprv_getUTCtime_4_0 +#define uprv_haveProperties uprv_haveProperties_4_0 +#define uprv_init_collIterate uprv_init_collIterate_4_0 +#define uprv_init_pce uprv_init_pce_4_0 +#define uprv_int32Comparator uprv_int32Comparator_4_0 +#define uprv_isInfinite uprv_isInfinite_4_0 +#define uprv_isInvariantString uprv_isInvariantString_4_0 +#define uprv_isInvariantUString uprv_isInvariantUString_4_0 +#define uprv_isNaN uprv_isNaN_4_0 +#define uprv_isNegativeInfinity uprv_isNegativeInfinity_4_0 +#define uprv_isPositiveInfinity uprv_isPositiveInfinity_4_0 +#define uprv_isRuleWhiteSpace uprv_isRuleWhiteSpace_4_0 +#define uprv_itou uprv_itou_4_0 +#define uprv_log uprv_log_4_0 +#define uprv_malloc uprv_malloc_4_0 +#define uprv_mapFile uprv_mapFile_4_0 +#define uprv_max uprv_max_4_0 +#define uprv_maxMantissa uprv_maxMantissa_4_0 +#define uprv_maximumPtr uprv_maximumPtr_4_0 +#define uprv_min uprv_min_4_0 +#define uprv_modf uprv_modf_4_0 +#define uprv_openRuleWhiteSpaceSet uprv_openRuleWhiteSpaceSet_4_0 +#define uprv_parseCurrency uprv_parseCurrency_4_0 +#define uprv_pathIsAbsolute uprv_pathIsAbsolute_4_0 +#define uprv_pow uprv_pow_4_0 +#define uprv_pow10 uprv_pow10_4_0 +#define uprv_realloc uprv_realloc_4_0 +#define uprv_round uprv_round_4_0 +#define uprv_sortArray uprv_sortArray_4_0 +#define uprv_strCompare uprv_strCompare_4_0 +#define uprv_strdup uprv_strdup_4_0 +#define uprv_strndup uprv_strndup_4_0 +#define uprv_syntaxError uprv_syntaxError_4_0 +#define uprv_timezone uprv_timezone_4_0 +#define uprv_toupper uprv_toupper_4_0 +#define uprv_trunc uprv_trunc_4_0 +#define uprv_tzname uprv_tzname_4_0 +#define uprv_tzset uprv_tzset_4_0 +#define uprv_uca_addAnElement uprv_uca_addAnElement_4_0 +#define uprv_uca_assembleTable uprv_uca_assembleTable_4_0 +#define uprv_uca_canonicalClosure uprv_uca_canonicalClosure_4_0 +#define uprv_uca_closeTempTable uprv_uca_closeTempTable_4_0 +#define uprv_uca_getCodePointFromRaw uprv_uca_getCodePointFromRaw_4_0 +#define uprv_uca_getImplicitFromRaw uprv_uca_getImplicitFromRaw_4_0 +#define uprv_uca_getRawFromCodePoint uprv_uca_getRawFromCodePoint_4_0 +#define uprv_uca_getRawFromImplicit uprv_uca_getRawFromImplicit_4_0 +#define uprv_uca_initImplicitConstants uprv_uca_initImplicitConstants_4_0 +#define uprv_uca_initTempTable uprv_uca_initTempTable_4_0 +#define uprv_uint16Comparator uprv_uint16Comparator_4_0 +#define uprv_uint32Comparator uprv_uint32Comparator_4_0 +#define uprv_unmapFile uprv_unmapFile_4_0 +#define uregex_appendReplacement uregex_appendReplacement_4_0 +#define uregex_appendTail uregex_appendTail_4_0 +#define uregex_clone uregex_clone_4_0 +#define uregex_close uregex_close_4_0 +#define uregex_end uregex_end_4_0 +#define uregex_find uregex_find_4_0 +#define uregex_findNext uregex_findNext_4_0 +#define uregex_flags uregex_flags_4_0 +#define uregex_getMatchCallback uregex_getMatchCallback_4_0 +#define uregex_getStackLimit uregex_getStackLimit_4_0 +#define uregex_getText uregex_getText_4_0 +#define uregex_getTimeLimit uregex_getTimeLimit_4_0 +#define uregex_group uregex_group_4_0 +#define uregex_groupCount uregex_groupCount_4_0 +#define uregex_hasAnchoringBounds uregex_hasAnchoringBounds_4_0 +#define uregex_hasTransparentBounds uregex_hasTransparentBounds_4_0 +#define uregex_hitEnd uregex_hitEnd_4_0 +#define uregex_lookingAt uregex_lookingAt_4_0 +#define uregex_matches uregex_matches_4_0 +#define uregex_open uregex_open_4_0 +#define uregex_openC uregex_openC_4_0 +#define uregex_pattern uregex_pattern_4_0 +#define uregex_regionEnd uregex_regionEnd_4_0 +#define uregex_regionStart uregex_regionStart_4_0 +#define uregex_replaceAll uregex_replaceAll_4_0 +#define uregex_replaceFirst uregex_replaceFirst_4_0 +#define uregex_requireEnd uregex_requireEnd_4_0 +#define uregex_reset uregex_reset_4_0 +#define uregex_setMatchCallback uregex_setMatchCallback_4_0 +#define uregex_setRegion uregex_setRegion_4_0 +#define uregex_setStackLimit uregex_setStackLimit_4_0 +#define uregex_setText uregex_setText_4_0 +#define uregex_setTimeLimit uregex_setTimeLimit_4_0 +#define uregex_split uregex_split_4_0 +#define uregex_start uregex_start_4_0 +#define uregex_useAnchoringBounds uregex_useAnchoringBounds_4_0 +#define uregex_useTransparentBounds uregex_useTransparentBounds_4_0 +#define ures_close ures_close_4_0 +#define ures_copyResb ures_copyResb_4_0 +#define ures_countArrayItems ures_countArrayItems_4_0 +#define ures_findResource ures_findResource_4_0 +#define ures_findSubResource ures_findSubResource_4_0 +#define ures_getBinary ures_getBinary_4_0 +#define ures_getByIndex ures_getByIndex_4_0 +#define ures_getByKey ures_getByKey_4_0 +#define ures_getByKeyWithFallback ures_getByKeyWithFallback_4_0 +#define ures_getFunctionalEquivalent ures_getFunctionalEquivalent_4_0 +#define ures_getInt ures_getInt_4_0 +#define ures_getIntVector ures_getIntVector_4_0 +#define ures_getKey ures_getKey_4_0 +#define ures_getKeywordValues ures_getKeywordValues_4_0 +#define ures_getLocale ures_getLocale_4_0 +#define ures_getLocaleByType ures_getLocaleByType_4_0 +#define ures_getName ures_getName_4_0 +#define ures_getNextResource ures_getNextResource_4_0 +#define ures_getNextString ures_getNextString_4_0 +#define ures_getSize ures_getSize_4_0 +#define ures_getString ures_getString_4_0 +#define ures_getStringByIndex ures_getStringByIndex_4_0 +#define ures_getStringByKey ures_getStringByKey_4_0 +#define ures_getStringByKeyWithFallback ures_getStringByKeyWithFallback_4_0 +#define ures_getType ures_getType_4_0 +#define ures_getUInt ures_getUInt_4_0 +#define ures_getUTF8String ures_getUTF8String_4_0 +#define ures_getUTF8StringByIndex ures_getUTF8StringByIndex_4_0 +#define ures_getUTF8StringByKey ures_getUTF8StringByKey_4_0 +#define ures_getVersion ures_getVersion_4_0 +#define ures_getVersionNumber ures_getVersionNumber_4_0 +#define ures_hasNext ures_hasNext_4_0 +#define ures_initStackObject ures_initStackObject_4_0 +#define ures_open ures_open_4_0 +#define ures_openAvailableLocales ures_openAvailableLocales_4_0 +#define ures_openDirect ures_openDirect_4_0 +#define ures_openFillIn ures_openFillIn_4_0 +#define ures_openU ures_openU_4_0 +#define ures_resetIterator ures_resetIterator_4_0 +#define ures_swap ures_swap_4_0 +#define uscript_closeRun uscript_closeRun_4_0 +#define uscript_getCode uscript_getCode_4_0 +#define uscript_getName uscript_getName_4_0 +#define uscript_getScript uscript_getScript_4_0 +#define uscript_getShortName uscript_getShortName_4_0 +#define uscript_nextRun uscript_nextRun_4_0 +#define uscript_openRun uscript_openRun_4_0 +#define uscript_resetRun uscript_resetRun_4_0 +#define uscript_setRunText uscript_setRunText_4_0 +#define usearch_close usearch_close_4_0 +#define usearch_first usearch_first_4_0 +#define usearch_following usearch_following_4_0 +#define usearch_getAttribute usearch_getAttribute_4_0 +#define usearch_getBreakIterator usearch_getBreakIterator_4_0 +#define usearch_getCollator usearch_getCollator_4_0 +#define usearch_getMatchedLength usearch_getMatchedLength_4_0 +#define usearch_getMatchedStart usearch_getMatchedStart_4_0 +#define usearch_getMatchedText usearch_getMatchedText_4_0 +#define usearch_getOffset usearch_getOffset_4_0 +#define usearch_getPattern usearch_getPattern_4_0 +#define usearch_getText usearch_getText_4_0 +#define usearch_handleNextCanonical usearch_handleNextCanonical_4_0 +#define usearch_handleNextExact usearch_handleNextExact_4_0 +#define usearch_handlePreviousCanonical usearch_handlePreviousCanonical_4_0 +#define usearch_handlePreviousExact usearch_handlePreviousExact_4_0 +#define usearch_last usearch_last_4_0 +#define usearch_next usearch_next_4_0 +#define usearch_open usearch_open_4_0 +#define usearch_openFromCollator usearch_openFromCollator_4_0 +#define usearch_preceding usearch_preceding_4_0 +#define usearch_previous usearch_previous_4_0 +#define usearch_reset usearch_reset_4_0 +#define usearch_search usearch_search_4_0 +#define usearch_searchBackwards usearch_searchBackwards_4_0 +#define usearch_setAttribute usearch_setAttribute_4_0 +#define usearch_setBreakIterator usearch_setBreakIterator_4_0 +#define usearch_setCollator usearch_setCollator_4_0 +#define usearch_setOffset usearch_setOffset_4_0 +#define usearch_setPattern usearch_setPattern_4_0 +#define usearch_setText usearch_setText_4_0 +#define uset_add uset_add_4_0 +#define uset_addAll uset_addAll_4_0 +#define uset_addAllCodePoints uset_addAllCodePoints_4_0 +#define uset_addRange uset_addRange_4_0 +#define uset_addString uset_addString_4_0 +#define uset_applyIntPropertyValue uset_applyIntPropertyValue_4_0 +#define uset_applyPattern uset_applyPattern_4_0 +#define uset_applyPropertyAlias uset_applyPropertyAlias_4_0 +#define uset_charAt uset_charAt_4_0 +#define uset_clear uset_clear_4_0 +#define uset_clone uset_clone_4_0 +#define uset_cloneAsThawed uset_cloneAsThawed_4_0 +#define uset_close uset_close_4_0 +#define uset_compact uset_compact_4_0 +#define uset_complement uset_complement_4_0 +#define uset_complementAll uset_complementAll_4_0 +#define uset_contains uset_contains_4_0 +#define uset_containsAll uset_containsAll_4_0 +#define uset_containsAllCodePoints uset_containsAllCodePoints_4_0 +#define uset_containsNone uset_containsNone_4_0 +#define uset_containsRange uset_containsRange_4_0 +#define uset_containsSome uset_containsSome_4_0 +#define uset_containsString uset_containsString_4_0 +#define uset_equals uset_equals_4_0 +#define uset_freeze uset_freeze_4_0 +#define uset_getItem uset_getItem_4_0 +#define uset_getItemCount uset_getItemCount_4_0 +#define uset_getSerializedRange uset_getSerializedRange_4_0 +#define uset_getSerializedRangeCount uset_getSerializedRangeCount_4_0 +#define uset_getSerializedSet uset_getSerializedSet_4_0 +#define uset_indexOf uset_indexOf_4_0 +#define uset_isEmpty uset_isEmpty_4_0 +#define uset_isFrozen uset_isFrozen_4_0 +#define uset_open uset_open_4_0 +#define uset_openPattern uset_openPattern_4_0 +#define uset_openPatternOptions uset_openPatternOptions_4_0 +#define uset_remove uset_remove_4_0 +#define uset_removeAll uset_removeAll_4_0 +#define uset_removeRange uset_removeRange_4_0 +#define uset_removeString uset_removeString_4_0 +#define uset_resemblesPattern uset_resemblesPattern_4_0 +#define uset_retain uset_retain_4_0 +#define uset_retainAll uset_retainAll_4_0 +#define uset_serialize uset_serialize_4_0 +#define uset_serializedContains uset_serializedContains_4_0 +#define uset_set uset_set_4_0 +#define uset_setSerializedToOne uset_setSerializedToOne_4_0 +#define uset_size uset_size_4_0 +#define uset_span uset_span_4_0 +#define uset_spanBack uset_spanBack_4_0 +#define uset_spanBackUTF8 uset_spanBackUTF8_4_0 +#define uset_spanUTF8 uset_spanUTF8_4_0 +#define uset_toPattern uset_toPattern_4_0 +#define usprep_close usprep_close_4_0 +#define usprep_open usprep_open_4_0 +#define usprep_prepare usprep_prepare_4_0 +#define usprep_swap usprep_swap_4_0 +#define ustr_foldCase ustr_foldCase_4_0 +#define ustr_toLower ustr_toLower_4_0 +#define ustr_toTitle ustr_toTitle_4_0 +#define ustr_toUpper ustr_toUpper_4_0 +#define utext_char32At utext_char32At_4_0 +#define utext_clone utext_clone_4_0 +#define utext_close utext_close_4_0 +#define utext_copy utext_copy_4_0 +#define utext_current32 utext_current32_4_0 +#define utext_equals utext_equals_4_0 +#define utext_extract utext_extract_4_0 +#define utext_freeze utext_freeze_4_0 +#define utext_getNativeIndex utext_getNativeIndex_4_0 +#define utext_getPreviousNativeIndex utext_getPreviousNativeIndex_4_0 +#define utext_hasMetaData utext_hasMetaData_4_0 +#define utext_isLengthExpensive utext_isLengthExpensive_4_0 +#define utext_isWritable utext_isWritable_4_0 +#define utext_moveIndex32 utext_moveIndex32_4_0 +#define utext_nativeLength utext_nativeLength_4_0 +#define utext_next32 utext_next32_4_0 +#define utext_next32From utext_next32From_4_0 +#define utext_openCharacterIterator utext_openCharacterIterator_4_0 +#define utext_openConstUnicodeString utext_openConstUnicodeString_4_0 +#define utext_openReplaceable utext_openReplaceable_4_0 +#define utext_openUChars utext_openUChars_4_0 +#define utext_openUTF8 utext_openUTF8_4_0 +#define utext_openUnicodeString utext_openUnicodeString_4_0 +#define utext_previous32 utext_previous32_4_0 +#define utext_previous32From utext_previous32From_4_0 +#define utext_replace utext_replace_4_0 +#define utext_setNativeIndex utext_setNativeIndex_4_0 +#define utext_setup utext_setup_4_0 +#define utf8_appendCharSafeBody utf8_appendCharSafeBody_4_0 +#define utf8_back1SafeBody utf8_back1SafeBody_4_0 +#define utf8_countTrailBytes utf8_countTrailBytes_4_0 +#define utf8_nextCharSafeBody utf8_nextCharSafeBody_4_0 +#define utf8_prevCharSafeBody utf8_prevCharSafeBody_4_0 +#define utmscale_fromInt64 utmscale_fromInt64_4_0 +#define utmscale_getTimeScaleValue utmscale_getTimeScaleValue_4_0 +#define utmscale_toInt64 utmscale_toInt64_4_0 +#define utrace_cleanup utrace_cleanup_4_0 +#define utrace_data utrace_data_4_0 +#define utrace_entry utrace_entry_4_0 +#define utrace_exit utrace_exit_4_0 +#define utrace_format utrace_format_4_0 +#define utrace_functionName utrace_functionName_4_0 +#define utrace_getFunctions utrace_getFunctions_4_0 +#define utrace_getLevel utrace_getLevel_4_0 +#define utrace_level utrace_level_4_0 +#define utrace_setFunctions utrace_setFunctions_4_0 +#define utrace_setLevel utrace_setLevel_4_0 +#define utrace_vformat utrace_vformat_4_0 +#define utrans_clone utrans_clone_4_0 +#define utrans_close utrans_close_4_0 +#define utrans_countAvailableIDs utrans_countAvailableIDs_4_0 +#define utrans_getAvailableID utrans_getAvailableID_4_0 +#define utrans_getID utrans_getID_4_0 +#define utrans_getUnicodeID utrans_getUnicodeID_4_0 +#define utrans_open utrans_open_4_0 +#define utrans_openIDs utrans_openIDs_4_0 +#define utrans_openInverse utrans_openInverse_4_0 +#define utrans_openU utrans_openU_4_0 +#define utrans_register utrans_register_4_0 +#define utrans_rep_caseContextIterator utrans_rep_caseContextIterator_4_0 +#define utrans_setFilter utrans_setFilter_4_0 +#define utrans_stripRules utrans_stripRules_4_0 +#define utrans_trans utrans_trans_4_0 +#define utrans_transIncremental utrans_transIncremental_4_0 +#define utrans_transIncrementalUChars utrans_transIncrementalUChars_4_0 +#define utrans_transUChars utrans_transUChars_4_0 +#define utrans_unregister utrans_unregister_4_0 +#define utrans_unregisterID utrans_unregisterID_4_0 +#define utrie_clone utrie_clone_4_0 +#define utrie_close utrie_close_4_0 +#define utrie_defaultGetFoldingOffset utrie_defaultGetFoldingOffset_4_0 +#define utrie_enum utrie_enum_4_0 +#define utrie_get32 utrie_get32_4_0 +#define utrie_getData utrie_getData_4_0 +#define utrie_open utrie_open_4_0 +#define utrie_serialize utrie_serialize_4_0 +#define utrie_set32 utrie_set32_4_0 +#define utrie_setRange32 utrie_setRange32_4_0 +#define utrie_swap utrie_swap_4_0 +#define utrie_unserialize utrie_unserialize_4_0 +#define utrie_unserializeDummy utrie_unserializeDummy_4_0 +/* C++ class names renaming defines */ + +#ifdef XP_CPLUSPLUS +#if !U_HAVE_NAMESPACE + +#define AbsoluteValueSubstitution AbsoluteValueSubstitution_4_0 +#define AlternateSubstitutionSubtable AlternateSubstitutionSubtable_4_0 +#define AnchorTable AnchorTable_4_0 +#define AndConstraint AndConstraint_4_0 +#define AnnualTimeZoneRule AnnualTimeZoneRule_4_0 +#define AnyTransliterator AnyTransliterator_4_0 +#define ArabicOpenTypeLayoutEngine ArabicOpenTypeLayoutEngine_4_0 +#define ArabicShaping ArabicShaping_4_0 +#define BMPSet BMPSet_4_0 +#define BasicCalendarFactory BasicCalendarFactory_4_0 +#define BasicTimeZone BasicTimeZone_4_0 +#define BinarySearchLookupTable BinarySearchLookupTable_4_0 +#define BreakIterator BreakIterator_4_0 +#define BreakTransliterator BreakTransliterator_4_0 +#define BuddhistCalendar BuddhistCalendar_4_0 +#define BuildCompactTrieHorizontalNode BuildCompactTrieHorizontalNode_4_0 +#define BuildCompactTrieNode BuildCompactTrieNode_4_0 +#define BuildCompactTrieVerticalNode BuildCompactTrieVerticalNode_4_0 +#define CEBuffer CEBuffer_4_0 +#define CECalendar CECalendar_4_0 +#define CFactory CFactory_4_0 +#define Calendar Calendar_4_0 +#define CalendarAstronomer CalendarAstronomer_4_0 +#define CalendarCache CalendarCache_4_0 +#define CalendarData CalendarData_4_0 +#define CalendarService CalendarService_4_0 +#define CanonMarkFilter CanonMarkFilter_4_0 +#define CanonShaping CanonShaping_4_0 +#define CanonicalIterator CanonicalIterator_4_0 +#define CaseMapTransliterator CaseMapTransliterator_4_0 +#define ChainingContextualSubstitutionFormat1Subtable ChainingContextualSubstitutionFormat1Subtable_4_0 +#define ChainingContextualSubstitutionFormat2Subtable ChainingContextualSubstitutionFormat2Subtable_4_0 +#define ChainingContextualSubstitutionFormat3Subtable ChainingContextualSubstitutionFormat3Subtable_4_0 +#define ChainingContextualSubstitutionSubtable ChainingContextualSubstitutionSubtable_4_0 +#define CharSubstitutionFilter CharSubstitutionFilter_4_0 +#define CharacterIterator CharacterIterator_4_0 +#define CharacterNode CharacterNode_4_0 +#define CharsetDetector CharsetDetector_4_0 +#define CharsetMatch CharsetMatch_4_0 +#define CharsetRecog_2022 CharsetRecog_2022_4_0 +#define CharsetRecog_2022CN CharsetRecog_2022CN_4_0 +#define CharsetRecog_2022JP CharsetRecog_2022JP_4_0 +#define CharsetRecog_2022KR CharsetRecog_2022KR_4_0 +#define CharsetRecog_8859_1 CharsetRecog_8859_1_4_0 +#define CharsetRecog_8859_1_da CharsetRecog_8859_1_da_4_0 +#define CharsetRecog_8859_1_de CharsetRecog_8859_1_de_4_0 +#define CharsetRecog_8859_1_en CharsetRecog_8859_1_en_4_0 +#define CharsetRecog_8859_1_es CharsetRecog_8859_1_es_4_0 +#define CharsetRecog_8859_1_fr CharsetRecog_8859_1_fr_4_0 +#define CharsetRecog_8859_1_it CharsetRecog_8859_1_it_4_0 +#define CharsetRecog_8859_1_nl CharsetRecog_8859_1_nl_4_0 +#define CharsetRecog_8859_1_no CharsetRecog_8859_1_no_4_0 +#define CharsetRecog_8859_1_pt CharsetRecog_8859_1_pt_4_0 +#define CharsetRecog_8859_1_sv CharsetRecog_8859_1_sv_4_0 +#define CharsetRecog_8859_2 CharsetRecog_8859_2_4_0 +#define CharsetRecog_8859_2_cs CharsetRecog_8859_2_cs_4_0 +#define CharsetRecog_8859_2_hu CharsetRecog_8859_2_hu_4_0 +#define CharsetRecog_8859_2_pl CharsetRecog_8859_2_pl_4_0 +#define CharsetRecog_8859_2_ro CharsetRecog_8859_2_ro_4_0 +#define CharsetRecog_8859_5 CharsetRecog_8859_5_4_0 +#define CharsetRecog_8859_5_ru CharsetRecog_8859_5_ru_4_0 +#define CharsetRecog_8859_6 CharsetRecog_8859_6_4_0 +#define CharsetRecog_8859_6_ar CharsetRecog_8859_6_ar_4_0 +#define CharsetRecog_8859_7 CharsetRecog_8859_7_4_0 +#define CharsetRecog_8859_7_el CharsetRecog_8859_7_el_4_0 +#define CharsetRecog_8859_8 CharsetRecog_8859_8_4_0 +#define CharsetRecog_8859_8_I_he CharsetRecog_8859_8_I_he_4_0 +#define CharsetRecog_8859_8_he CharsetRecog_8859_8_he_4_0 +#define CharsetRecog_8859_9 CharsetRecog_8859_9_4_0 +#define CharsetRecog_8859_9_tr CharsetRecog_8859_9_tr_4_0 +#define CharsetRecog_KOI8_R CharsetRecog_KOI8_R_4_0 +#define CharsetRecog_UTF8 CharsetRecog_UTF8_4_0 +#define CharsetRecog_UTF_16_BE CharsetRecog_UTF_16_BE_4_0 +#define CharsetRecog_UTF_16_LE CharsetRecog_UTF_16_LE_4_0 +#define CharsetRecog_UTF_32 CharsetRecog_UTF_32_4_0 +#define CharsetRecog_UTF_32_BE CharsetRecog_UTF_32_BE_4_0 +#define CharsetRecog_UTF_32_LE CharsetRecog_UTF_32_LE_4_0 +#define CharsetRecog_Unicode CharsetRecog_Unicode_4_0 +#define CharsetRecog_big5 CharsetRecog_big5_4_0 +#define CharsetRecog_euc CharsetRecog_euc_4_0 +#define CharsetRecog_euc_jp CharsetRecog_euc_jp_4_0 +#define CharsetRecog_euc_kr CharsetRecog_euc_kr_4_0 +#define CharsetRecog_gb_18030 CharsetRecog_gb_18030_4_0 +#define CharsetRecog_mbcs CharsetRecog_mbcs_4_0 +#define CharsetRecog_sbcs CharsetRecog_sbcs_4_0 +#define CharsetRecog_sjis CharsetRecog_sjis_4_0 +#define CharsetRecog_windows_1251 CharsetRecog_windows_1251_4_0 +#define CharsetRecog_windows_1256 CharsetRecog_windows_1256_4_0 +#define CharsetRecognizer CharsetRecognizer_4_0 +#define ChineseCalendar ChineseCalendar_4_0 +#define ChoiceFormat ChoiceFormat_4_0 +#define ClassDefFormat1Table ClassDefFormat1Table_4_0 +#define ClassDefFormat2Table ClassDefFormat2Table_4_0 +#define ClassDefinitionTable ClassDefinitionTable_4_0 +#define CollationElementIterator CollationElementIterator_4_0 +#define CollationKey CollationKey_4_0 +#define CollationLocaleListEnumeration CollationLocaleListEnumeration_4_0 +#define Collator Collator_4_0 +#define CollatorFactory CollatorFactory_4_0 +#define CompactTrieDictionary CompactTrieDictionary_4_0 +#define CompactTrieEnumeration CompactTrieEnumeration_4_0 +#define CompoundTransliterator CompoundTransliterator_4_0 +#define ContextualGlyphSubstitutionProcessor ContextualGlyphSubstitutionProcessor_4_0 +#define ContextualSubstitutionBase ContextualSubstitutionBase_4_0 +#define ContextualSubstitutionFormat1Subtable ContextualSubstitutionFormat1Subtable_4_0 +#define ContextualSubstitutionFormat2Subtable ContextualSubstitutionFormat2Subtable_4_0 +#define ContextualSubstitutionFormat3Subtable ContextualSubstitutionFormat3Subtable_4_0 +#define ContextualSubstitutionSubtable ContextualSubstitutionSubtable_4_0 +#define CopticCalendar CopticCalendar_4_0 +#define CoverageFormat1Table CoverageFormat1Table_4_0 +#define CoverageFormat2Table CoverageFormat2Table_4_0 +#define CoverageTable CoverageTable_4_0 +#define CurrencyAmount CurrencyAmount_4_0 +#define CurrencyFormat CurrencyFormat_4_0 +#define CurrencyUnit CurrencyUnit_4_0 +#define CursiveAttachmentSubtable CursiveAttachmentSubtable_4_0 +#define DTRedundantEnumeration DTRedundantEnumeration_4_0 +#define DTSkeletonEnumeration DTSkeletonEnumeration_4_0 +#define DateFormat DateFormat_4_0 +#define DateFormatSymbols DateFormatSymbols_4_0 +#define DateInterval DateInterval_4_0 +#define DateIntervalFormat DateIntervalFormat_4_0 +#define DateIntervalInfo DateIntervalInfo_4_0 +#define DateTimeMatcher DateTimeMatcher_4_0 +#define DateTimePatternGenerator DateTimePatternGenerator_4_0 +#define DateTimeRule DateTimeRule_4_0 +#define DecimalFormat DecimalFormat_4_0 +#define DecimalFormatSymbols DecimalFormatSymbols_4_0 +#define DefaultCalendarFactory DefaultCalendarFactory_4_0 +#define DefaultCharMapper DefaultCharMapper_4_0 +#define DeviceTable DeviceTable_4_0 +#define DictionaryBreakEngine DictionaryBreakEngine_4_0 +#define DigitList DigitList_4_0 +#define DistanceInfo DistanceInfo_4_0 +#define Entry Entry_4_0 +#define EnumToOffset EnumToOffset_4_0 +#define EscapeTransliterator EscapeTransliterator_4_0 +#define EthiopicCalendar EthiopicCalendar_4_0 +#define EventListener EventListener_4_0 +#define ExtensionSubtable ExtensionSubtable_4_0 +#define FeatureListTable FeatureListTable_4_0 +#define FieldPosition FieldPosition_4_0 +#define FontRuns FontRuns_4_0 +#define Format Format_4_0 +#define Format1AnchorTable Format1AnchorTable_4_0 +#define Format2AnchorTable Format2AnchorTable_4_0 +#define Format3AnchorTable Format3AnchorTable_4_0 +#define FormatNameEnumeration FormatNameEnumeration_4_0 +#define FormatParser FormatParser_4_0 +#define Formattable Formattable_4_0 +#define ForwardCharacterIterator ForwardCharacterIterator_4_0 +#define FractionalPartSubstitution FractionalPartSubstitution_4_0 +#define FunctionReplacer FunctionReplacer_4_0 +#define GDEFMarkFilter GDEFMarkFilter_4_0 +#define GXLayoutEngine GXLayoutEngine_4_0 +#define GlyphDefinitionTableHeader GlyphDefinitionTableHeader_4_0 +#define GlyphIterator GlyphIterator_4_0 +#define GlyphLookupTableHeader GlyphLookupTableHeader_4_0 +#define GlyphPositionAdjustments GlyphPositionAdjustments_4_0 +#define GlyphPositioningLookupProcessor GlyphPositioningLookupProcessor_4_0 +#define GlyphPositioningTableHeader GlyphPositioningTableHeader_4_0 +#define GlyphSubstitutionLookupProcessor GlyphSubstitutionLookupProcessor_4_0 +#define GlyphSubstitutionTableHeader GlyphSubstitutionTableHeader_4_0 +#define Grego Grego_4_0 +#define GregorianCalendar GregorianCalendar_4_0 +#define HanOpenTypeLayoutEngine HanOpenTypeLayoutEngine_4_0 +#define HangulOpenTypeLayoutEngine HangulOpenTypeLayoutEngine_4_0 +#define HebrewCalendar HebrewCalendar_4_0 +#define ICUBreakIteratorFactory ICUBreakIteratorFactory_4_0 +#define ICUBreakIteratorService ICUBreakIteratorService_4_0 +#define ICUCollatorFactory ICUCollatorFactory_4_0 +#define ICUCollatorService ICUCollatorService_4_0 +#define ICULanguageBreakFactory ICULanguageBreakFactory_4_0 +#define ICULocaleService ICULocaleService_4_0 +#define ICUNotifier ICUNotifier_4_0 +#define ICUNumberFormatFactory ICUNumberFormatFactory_4_0 +#define ICUNumberFormatService ICUNumberFormatService_4_0 +#define ICUResourceBundleFactory ICUResourceBundleFactory_4_0 +#define ICUService ICUService_4_0 +#define ICUServiceFactory ICUServiceFactory_4_0 +#define ICUServiceKey ICUServiceKey_4_0 +#define ICU_Utility ICU_Utility_4_0 +#define IndianCalendar IndianCalendar_4_0 +#define IndicClassTable IndicClassTable_4_0 +#define IndicOpenTypeLayoutEngine IndicOpenTypeLayoutEngine_4_0 +#define IndicRearrangementProcessor IndicRearrangementProcessor_4_0 +#define IndicReordering IndicReordering_4_0 +#define InitialTimeZoneRule InitialTimeZoneRule_4_0 +#define InputText InputText_4_0 +#define IntegralPartSubstitution IntegralPartSubstitution_4_0 +#define IslamicCalendar IslamicCalendar_4_0 +#define IteratedChar IteratedChar_4_0 +#define JapaneseCalendar JapaneseCalendar_4_0 +#define KernTable KernTable_4_0 +#define KeywordEnumeration KeywordEnumeration_4_0 +#define KhmerClassTable KhmerClassTable_4_0 +#define KhmerOpenTypeLayoutEngine KhmerOpenTypeLayoutEngine_4_0 +#define KhmerReordering KhmerReordering_4_0 +#define LECharMapper LECharMapper_4_0 +#define LEFontInstance LEFontInstance_4_0 +#define LEGlyphFilter LEGlyphFilter_4_0 +#define LEGlyphStorage LEGlyphStorage_4_0 +#define LEInsertionCallback LEInsertionCallback_4_0 +#define LEInsertionList LEInsertionList_4_0 +#define LXUtilities LXUtilities_4_0 +#define LanguageBreakEngine LanguageBreakEngine_4_0 +#define LanguageBreakFactory LanguageBreakFactory_4_0 +#define LayoutEngine LayoutEngine_4_0 +#define LigatureSubstitutionProcessor LigatureSubstitutionProcessor_4_0 +#define LigatureSubstitutionSubtable LigatureSubstitutionSubtable_4_0 +#define LocDataParser LocDataParser_4_0 +#define Locale Locale_4_0 +#define LocaleBased LocaleBased_4_0 +#define LocaleKey LocaleKey_4_0 +#define LocaleKeyFactory LocaleKeyFactory_4_0 +#define LocaleRuns LocaleRuns_4_0 +#define LocaleUtility LocaleUtility_4_0 +#define LocalizationInfo LocalizationInfo_4_0 +#define LookupListTable LookupListTable_4_0 +#define LookupProcessor LookupProcessor_4_0 +#define LookupSubtable LookupSubtable_4_0 +#define LookupTable LookupTable_4_0 +#define LowercaseTransliterator LowercaseTransliterator_4_0 +#define MPreFixups MPreFixups_4_0 +#define MarkArray MarkArray_4_0 +#define MarkToBasePositioningSubtable MarkToBasePositioningSubtable_4_0 +#define MarkToLigaturePositioningSubtable MarkToLigaturePositioningSubtable_4_0 +#define MarkToMarkPositioningSubtable MarkToMarkPositioningSubtable_4_0 +#define Math Math_4_0 +#define Measure Measure_4_0 +#define MeasureFormat MeasureFormat_4_0 +#define MeasureUnit MeasureUnit_4_0 +#define MessageFormat MessageFormat_4_0 +#define MessageFormatAdapter MessageFormatAdapter_4_0 +#define ModulusSubstitution ModulusSubstitution_4_0 +#define MoonRiseSetCoordFunc MoonRiseSetCoordFunc_4_0 +#define MoonTimeAngleFunc MoonTimeAngleFunc_4_0 +#define MorphSubtableHeader MorphSubtableHeader_4_0 +#define MorphTableHeader MorphTableHeader_4_0 +#define MultipleSubstitutionSubtable MultipleSubstitutionSubtable_4_0 +#define MultiplierSubstitution MultiplierSubstitution_4_0 +#define MutableTrieDictionary MutableTrieDictionary_4_0 +#define MutableTrieEnumeration MutableTrieEnumeration_4_0 +#define NFFactory NFFactory_4_0 +#define NFRule NFRule_4_0 +#define NFRuleSet NFRuleSet_4_0 +#define NFSubstitution NFSubstitution_4_0 +#define NGramParser NGramParser_4_0 +#define NameToEnum NameToEnum_4_0 +#define NameUnicodeTransliterator NameUnicodeTransliterator_4_0 +#define NonContextualGlyphSubstitutionProcessor NonContextualGlyphSubstitutionProcessor_4_0 +#define NonContiguousEnumToOffset NonContiguousEnumToOffset_4_0 +#define NormalizationTransliterator NormalizationTransliterator_4_0 +#define Normalizer Normalizer_4_0 +#define NullSubstitution NullSubstitution_4_0 +#define NullTransliterator NullTransliterator_4_0 +#define NumberFormat NumberFormat_4_0 +#define NumberFormatFactory NumberFormatFactory_4_0 +#define NumeratorSubstitution NumeratorSubstitution_4_0 +#define OlsonTimeZone OlsonTimeZone_4_0 +#define OpenTypeLayoutEngine OpenTypeLayoutEngine_4_0 +#define OpenTypeUtilities OpenTypeUtilities_4_0 +#define OrConstraint OrConstraint_4_0 +#define PCEBuffer PCEBuffer_4_0 +#define PairPositioningFormat1Subtable PairPositioningFormat1Subtable_4_0 +#define PairPositioningFormat2Subtable PairPositioningFormat2Subtable_4_0 +#define PairPositioningSubtable PairPositioningSubtable_4_0 +#define ParagraphLayout ParagraphLayout_4_0 +#define ParseData ParseData_4_0 +#define ParsePosition ParsePosition_4_0 +#define PatternMap PatternMap_4_0 +#define PatternMapIterator PatternMapIterator_4_0 +#define PersianCalendar PersianCalendar_4_0 +#define PluralFormat PluralFormat_4_0 +#define PluralKeywordEnumeration PluralKeywordEnumeration_4_0 +#define PluralRules PluralRules_4_0 +#define PropertyAliases PropertyAliases_4_0 +#define PtnElem PtnElem_4_0 +#define PtnSkeleton PtnSkeleton_4_0 +#define Quantifier Quantifier_4_0 +#define RBBIDataWrapper RBBIDataWrapper_4_0 +#define RBBINode RBBINode_4_0 +#define RBBIRuleBuilder RBBIRuleBuilder_4_0 +#define RBBIRuleScanner RBBIRuleScanner_4_0 +#define RBBISetBuilder RBBISetBuilder_4_0 +#define RBBIStateDescriptor RBBIStateDescriptor_4_0 +#define RBBISymbolTable RBBISymbolTable_4_0 +#define RBBISymbolTableEntry RBBISymbolTableEntry_4_0 +#define RBBITableBuilder RBBITableBuilder_4_0 +#define RCEBuffer RCEBuffer_4_0 +#define RangeDescriptor RangeDescriptor_4_0 +#define RegexCImpl RegexCImpl_4_0 +#define RegexCompile RegexCompile_4_0 +#define RegexMatcher RegexMatcher_4_0 +#define RegexPattern RegexPattern_4_0 +#define RegexStaticSets RegexStaticSets_4_0 +#define RelativeDateFormat RelativeDateFormat_4_0 +#define RemoveTransliterator RemoveTransliterator_4_0 +#define Replaceable Replaceable_4_0 +#define ReplaceableGlue ReplaceableGlue_4_0 +#define ResourceBundle ResourceBundle_4_0 +#define RiseSetCoordFunc RiseSetCoordFunc_4_0 +#define RuleBasedBreakIterator RuleBasedBreakIterator_4_0 +#define RuleBasedCollator RuleBasedCollator_4_0 +#define RuleBasedNumberFormat RuleBasedNumberFormat_4_0 +#define RuleBasedTimeZone RuleBasedTimeZone_4_0 +#define RuleBasedTransliterator RuleBasedTransliterator_4_0 +#define RuleChain RuleChain_4_0 +#define RuleCharacterIterator RuleCharacterIterator_4_0 +#define RuleHalf RuleHalf_4_0 +#define RuleParser RuleParser_4_0 +#define RunArray RunArray_4_0 +#define SafeZoneStringFormatPtr SafeZoneStringFormatPtr_4_0 +#define SameValueSubstitution SameValueSubstitution_4_0 +#define ScriptListTable ScriptListTable_4_0 +#define ScriptRunIterator ScriptRunIterator_4_0 +#define ScriptTable ScriptTable_4_0 +#define SearchIterator SearchIterator_4_0 +#define SegmentArrayProcessor SegmentArrayProcessor_4_0 +#define SegmentSingleProcessor SegmentSingleProcessor_4_0 +#define ServiceEnumeration ServiceEnumeration_4_0 +#define ServiceListener ServiceListener_4_0 +#define SimpleArrayProcessor SimpleArrayProcessor_4_0 +#define SimpleDateFormat SimpleDateFormat_4_0 +#define SimpleFactory SimpleFactory_4_0 +#define SimpleLocaleKeyFactory SimpleLocaleKeyFactory_4_0 +#define SimpleNumberFormatFactory SimpleNumberFormatFactory_4_0 +#define SimpleTimeZone SimpleTimeZone_4_0 +#define SinglePositioningFormat1Subtable SinglePositioningFormat1Subtable_4_0 +#define SinglePositioningFormat2Subtable SinglePositioningFormat2Subtable_4_0 +#define SinglePositioningSubtable SinglePositioningSubtable_4_0 +#define SingleSubstitutionFormat1Subtable SingleSubstitutionFormat1Subtable_4_0 +#define SingleSubstitutionFormat2Subtable SingleSubstitutionFormat2Subtable_4_0 +#define SingleSubstitutionSubtable SingleSubstitutionSubtable_4_0 +#define SingleTableProcessor SingleTableProcessor_4_0 +#define Spec Spec_4_0 +#define StateTableProcessor StateTableProcessor_4_0 +#define StringCharacterIterator StringCharacterIterator_4_0 +#define StringEnumeration StringEnumeration_4_0 +#define StringLocalizationInfo StringLocalizationInfo_4_0 +#define StringMatcher StringMatcher_4_0 +#define StringPair StringPair_4_0 +#define StringReplacer StringReplacer_4_0 +#define StringSearch StringSearch_4_0 +#define StyleRuns StyleRuns_4_0 +#define SubstitutionLookup SubstitutionLookup_4_0 +#define SubtableProcessor SubtableProcessor_4_0 +#define SunTimeAngleFunc SunTimeAngleFunc_4_0 +#define SymbolTable SymbolTable_4_0 +#define TZEnumeration TZEnumeration_4_0 +#define TaiwanCalendar TaiwanCalendar_4_0 +#define TernaryNode TernaryNode_4_0 +#define TextTrieMap TextTrieMap_4_0 +#define TextTrieMapSearchResultHandler TextTrieMapSearchResultHandler_4_0 +#define ThaiBreakEngine ThaiBreakEngine_4_0 +#define ThaiLayoutEngine ThaiLayoutEngine_4_0 +#define ThaiShaping ThaiShaping_4_0 +#define TibetanClassTable TibetanClassTable_4_0 +#define TibetanOpenTypeLayoutEngine TibetanOpenTypeLayoutEngine_4_0 +#define TibetanReordering TibetanReordering_4_0 +#define TimeArrayTimeZoneRule TimeArrayTimeZoneRule_4_0 +#define TimeZone TimeZone_4_0 +#define TimeZoneRule TimeZoneRule_4_0 +#define TimeZoneTransition TimeZoneTransition_4_0 +#define TitlecaseTransliterator TitlecaseTransliterator_4_0 +#define TransliterationRule TransliterationRule_4_0 +#define TransliterationRuleData TransliterationRuleData_4_0 +#define TransliterationRuleSet TransliterationRuleSet_4_0 +#define Transliterator Transliterator_4_0 +#define TransliteratorAlias TransliteratorAlias_4_0 +#define TransliteratorIDParser TransliteratorIDParser_4_0 +#define TransliteratorParser TransliteratorParser_4_0 +#define TransliteratorRegistry TransliteratorRegistry_4_0 +#define TrieWordDictionary TrieWordDictionary_4_0 +#define TrimmedArrayProcessor TrimmedArrayProcessor_4_0 +#define UCharCharacterIterator UCharCharacterIterator_4_0 +#define UCollationPCE UCollationPCE_4_0 +#define ULocRuns ULocRuns_4_0 +#define UMemory UMemory_4_0 +#define UObject UObject_4_0 +#define URegularExpression URegularExpression_4_0 +#define UStack UStack_4_0 +#define UStringEnumeration UStringEnumeration_4_0 +#define UVector UVector_4_0 +#define UVector32 UVector32_4_0 +#define UnescapeTransliterator UnescapeTransliterator_4_0 +#define UnhandledEngine UnhandledEngine_4_0 +#define UnicodeArabicOpenTypeLayoutEngine UnicodeArabicOpenTypeLayoutEngine_4_0 +#define UnicodeFilter UnicodeFilter_4_0 +#define UnicodeFunctor UnicodeFunctor_4_0 +#define UnicodeMatcher UnicodeMatcher_4_0 +#define UnicodeNameTransliterator UnicodeNameTransliterator_4_0 +#define UnicodeReplacer UnicodeReplacer_4_0 +#define UnicodeSet UnicodeSet_4_0 +#define UnicodeSetIterator UnicodeSetIterator_4_0 +#define UnicodeSetStringSpan UnicodeSetStringSpan_4_0 +#define UnicodeString UnicodeString_4_0 +#define UppercaseTransliterator UppercaseTransliterator_4_0 +#define VTZReader VTZReader_4_0 +#define VTZWriter VTZWriter_4_0 +#define VTimeZone VTimeZone_4_0 +#define ValueRecord ValueRecord_4_0 +#define ValueRuns ValueRuns_4_0 +#define ZSFCache ZSFCache_4_0 +#define ZSFCacheEntry ZSFCacheEntry_4_0 +#define ZoneMeta ZoneMeta_4_0 +#define ZoneStringFormat ZoneStringFormat_4_0 +#define ZoneStringInfo ZoneStringInfo_4_0 +#define ZoneStringSearchResultHandler ZoneStringSearchResultHandler_4_0 +#define ZoneStrings ZoneStrings_4_0 +#define locale_set_default_internal locale_set_default_internal_4_0 +#define util64_fromDouble util64_fromDouble_4_0 +#define util64_pow util64_pow_4_0 +#define util64_tou util64_tou_4_0 + +#endif +#endif + +#endif + +#endif diff --git a/utils/openttd/unicode/urep.h b/utils/openttd/unicode/urep.h new file mode 100644 index 00000000000..57b547c8783 --- /dev/null +++ b/utils/openttd/unicode/urep.h @@ -0,0 +1,155 @@ +/* +****************************************************************************** +* Copyright (C) 1997-2005, International Business Machines +* Corporation and others. All Rights Reserved. +****************************************************************************** +* Date Name Description +* 06/23/00 aliu Creation. +****************************************************************************** +*/ + +#ifndef __UREP_H +#define __UREP_H + +#include "unicode/utypes.h" + +U_CDECL_BEGIN + +/******************************************************************** + * General Notes + ******************************************************************** + * TODO + * Add usage scenario + * Add test code + * Talk about pinning + * Talk about "can truncate result if out of memory" + */ + +/******************************************************************** + * Data Structures + ********************************************************************/ +/** + * \file + * \brief C API: Callbacks for UReplacebale + */ +/** + * An opaque replaceable text object. This will be manipulated only + * through the caller-supplied UReplaceableFunctor struct. Related + * to the C++ class Replaceable. + * This is currently only used in the Transliterator C API, see utrans.h . + * @stable ICU 2.0 + */ +typedef void* UReplaceable; + +/** + * A set of function pointers that transliterators use to manipulate a + * UReplaceable. The caller should supply the required functions to + * manipulate their text appropriately. Related to the C++ class + * Replaceable. + * @stable ICU 2.0 + */ +typedef struct UReplaceableCallbacks { + + /** + * Function pointer that returns the number of UChar code units in + * this text. + * + * @param rep A pointer to "this" UReplaceable object. + * @return The length of the text. + * @stable ICU 2.0 + */ + int32_t (*length)(const UReplaceable* rep); + + /** + * Function pointer that returns a UChar code units at the given + * offset into this text; 0 <= offset < n, where n is the value + * returned by (*length)(rep). See unistr.h for a description of + * charAt() vs. char32At(). + * + * @param rep A pointer to "this" UReplaceable object. + * @param offset The index at which to fetch the UChar (code unit). + * @return The UChar (code unit) at offset, or U+FFFF if the offset is out of bounds. + * @stable ICU 2.0 + */ + UChar (*charAt)(const UReplaceable* rep, + int32_t offset); + + /** + * Function pointer that returns a UChar32 code point at the given + * offset into this text. See unistr.h for a description of + * charAt() vs. char32At(). + * + * @param rep A pointer to "this" UReplaceable object. + * @param offset The index at which to fetch the UChar32 (code point). + * @return The UChar32 (code point) at offset, or U+FFFF if the offset is out of bounds. + * @stable ICU 2.0 + */ + UChar32 (*char32At)(const UReplaceable* rep, + int32_t offset); + + /** + * Function pointer that replaces text between start and limit in + * this text with the given text. Attributes (out of band info) + * should be retained. + * + * @param rep A pointer to "this" UReplaceable object. + * @param start the starting index of the text to be replaced, + * inclusive. + * @param limit the ending index of the text to be replaced, + * exclusive. + * @param text the new text to replace the UChars from + * start..limit-1. + * @param textLength the number of UChars at text, or -1 if text + * is null-terminated. + * @stable ICU 2.0 + */ + void (*replace)(UReplaceable* rep, + int32_t start, + int32_t limit, + const UChar* text, + int32_t textLength); + + /** + * Function pointer that copies the characters in the range + * [<tt>start</tt>, <tt>limit</tt>) into the array <tt>dst</tt>. + * + * @param rep A pointer to "this" UReplaceable object. + * @param start offset of first character which will be copied + * into the array + * @param limit offset immediately following the last character to + * be copied + * @param dst array in which to copy characters. The length of + * <tt>dst</tt> must be at least <tt>(limit - start)</tt>. + * @stable ICU 2.1 + */ + void (*extract)(UReplaceable* rep, + int32_t start, + int32_t limit, + UChar* dst); + + /** + * Function pointer that copies text between start and limit in + * this text to another index in the text. Attributes (out of + * band info) should be retained. After this call, there will be + * (at least) two copies of the characters originally located at + * start..limit-1. + * + * @param rep A pointer to "this" UReplaceable object. + * @param start the starting index of the text to be copied, + * inclusive. + * @param limit the ending index of the text to be copied, + * exclusive. + * @param dest the index at which the copy of the UChars should be + * inserted. + * @stable ICU 2.0 + */ + void (*copy)(UReplaceable* rep, + int32_t start, + int32_t limit, + int32_t dest); + +} UReplaceableCallbacks; + +U_CDECL_END + +#endif diff --git a/utils/openttd/unicode/ures.h b/utils/openttd/unicode/ures.h new file mode 100644 index 00000000000..9cc2e89cf68 --- /dev/null +++ b/utils/openttd/unicode/ures.h @@ -0,0 +1,871 @@ +/* +********************************************************************** +* Copyright (C) 1997-2007, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* +* File URES.H (formerly CRESBUND.H) +* +* Modification History: +* +* Date Name Description +* 04/01/97 aliu Creation. +* 02/22/99 damiba overhaul. +* 04/04/99 helena Fixed internal header inclusion. +* 04/15/99 Madhu Updated Javadoc +* 06/14/99 stephen Removed functions taking a filename suffix. +* 07/20/99 stephen Language-independent ypedef to void* +* 11/09/99 weiv Added ures_getLocale() +* 06/24/02 weiv Added support for resource sharing +****************************************************************************** +*/ + +#ifndef URES_H +#define URES_H + +#include "unicode/utypes.h" +#include "unicode/uloc.h" + +/** + * \file + * \brief C API: Resource Bundle + * + * <h2>C API: Resource Bundle</h2> + * + * C API representing a collection of resource information pertaining to a given + * locale. A resource bundle provides a way of accessing locale- specific information in + * a data file. You create a resource bundle that manages the resources for a given + * locale and then ask it for individual resources. + * <P> + * Resource bundles in ICU4C are currently defined using text files which conform to the following + * <a href="http://source.icu-project.org/repos/icu/icuhtml/trunk/design/bnf_rb.txt">BNF definition</a>. + * More on resource bundle concepts and syntax can be found in the + * <a href="http://icu-project.org/userguide/ResourceManagement.html">Users Guide</a>. + * <P> + */ + +/** + * UResourceBundle is an opaque type for handles for resource bundles in C APIs. + * @stable ICU 2.0 + */ +struct UResourceBundle; + +/** + * @stable ICU 2.0 + */ +typedef struct UResourceBundle UResourceBundle; + +/** + * Numeric constants for types of resource items. + * @see ures_getType + * @stable ICU 2.0 + */ +typedef enum { + /** Resource type constant for "no resource". @stable ICU 2.6 */ + URES_NONE=-1, + + /** Resource type constant for 16-bit Unicode strings. @stable ICU 2.6 */ + URES_STRING=0, + + /** Resource type constant for binary data. @stable ICU 2.6 */ + URES_BINARY=1, + + /** Resource type constant for tables of key-value pairs. @stable ICU 2.6 */ + URES_TABLE=2, + + /** + * Resource type constant for aliases; + * internally stores a string which identifies the actual resource + * storing the data (can be in a different resource bundle). + * Resolved internally before delivering the actual resource through the API. + * @stable ICU 2.6 + */ + URES_ALIAS=3, + +#ifndef U_HIDE_INTERNAL_API + + /** + * Internal use only. + * Alternative resource type constant for tables of key-value pairs. + * Never returned by ures_getType(). + * @internal + */ + URES_TABLE32=4, + +#endif /* U_HIDE_INTERNAL_API */ + + /** + * Resource type constant for a single 28-bit integer, interpreted as + * signed or unsigned by the ures_getInt() or ures_getUInt() function. + * @see ures_getInt + * @see ures_getUInt + * @stable ICU 2.6 + */ + URES_INT=7, + + /** Resource type constant for arrays of resources. @stable ICU 2.6 */ + URES_ARRAY=8, + + /** + * Resource type constant for vectors of 32-bit integers. + * @see ures_getIntVector + * @stable ICU 2.6 + */ + URES_INT_VECTOR = 14, +#ifndef U_HIDE_DEPRECATED_API + /** @deprecated ICU 2.6 Use the URES_ constant instead. */ + RES_NONE=URES_NONE, + /** @deprecated ICU 2.6 Use the URES_ constant instead. */ + RES_STRING=URES_STRING, + /** @deprecated ICU 2.6 Use the URES_ constant instead. */ + RES_BINARY=URES_BINARY, + /** @deprecated ICU 2.6 Use the URES_ constant instead. */ + RES_TABLE=URES_TABLE, + /** @deprecated ICU 2.6 Use the URES_ constant instead. */ + RES_ALIAS=URES_ALIAS, + /** @deprecated ICU 2.6 Use the URES_ constant instead. */ + RES_INT=URES_INT, + /** @deprecated ICU 2.6 Use the URES_ constant instead. */ + RES_ARRAY=URES_ARRAY, + /** @deprecated ICU 2.6 Use the URES_ constant instead. */ + RES_INT_VECTOR=URES_INT_VECTOR, + /** @deprecated ICU 2.6 Not used. */ + RES_RESERVED=15, +#endif /* U_HIDE_DEPRECATED_API */ + + URES_LIMIT = 16 +} UResType; + +/* + * Functions to create and destroy resource bundles. + */ + +/** + * Opens a UResourceBundle, from which users can extract strings by using + * their corresponding keys. + * Note that the caller is responsible of calling <TT>ures_close</TT> on each succesfully + * opened resource bundle. + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by <code> udata_open( packageName, "res", locale, err) </code> + * or equivalent. Typically, packageName will refer to a (.dat) file, or to + * a package registered with udata_setAppData(). Using a full file or directory + * pathname for packageName is deprecated. If NULL, ICU data will be used. + * @param locale specifies the locale for which we want to open the resource + * if NULL, the default locale will be used. If strlen(locale) == 0 + * root locale will be used. + * + * @param status fills in the outgoing error code. + * The UErrorCode err parameter is used to return status information to the user. To + * check whether the construction succeeded or not, you should check the value of + * U_SUCCESS(err). If you wish more detailed information, you can check for + * informational status results which still indicate success. U_USING_FALLBACK_WARNING + * indicates that a fall back locale was used. For example, 'de_CH' was requested, + * but nothing was found there, so 'de' was used. U_USING_DEFAULT_WARNING indicates that + * the default locale data or root locale data was used; neither the requested locale + * nor any of its fall back locales could be found. Please see the users guide for more + * information on this topic. + * @return a newly allocated resource bundle. + * @see ures_close + * @stable ICU 2.0 + */ +U_STABLE UResourceBundle* U_EXPORT2 +ures_open(const char* packageName, + const char* locale, + UErrorCode* status); + + +/** This function does not care what kind of localeID is passed in. It simply opens a bundle with + * that name. Fallback mechanism is disabled for the new bundle. If the requested bundle contains + * an %%ALIAS directive, the results are undefined. + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by <code> udata_open( packageName, "res", locale, err) </code> + * or equivalent. Typically, packageName will refer to a (.dat) file, or to + * a package registered with udata_setAppData(). Using a full file or directory + * pathname for packageName is deprecated. If NULL, ICU data will be used. + * @param locale specifies the locale for which we want to open the resource + * if NULL, the default locale will be used. If strlen(locale) == 0 + * root locale will be used. + * + * @param status fills in the outgoing error code. Either U_ZERO_ERROR or U_MISSING_RESOURCE_ERROR + * @return a newly allocated resource bundle or NULL if it doesn't exist. + * @see ures_close + * @stable ICU 2.0 + */ +U_STABLE UResourceBundle* U_EXPORT2 +ures_openDirect(const char* packageName, + const char* locale, + UErrorCode* status); + +/** + * Same as ures_open() but takes a const UChar *path. + * This path will be converted to char * using the default converter, + * then ures_open() is called. + * + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by <code> udata_open( packageName, "res", locale, err) </code> + * or equivalent. Typically, packageName will refer to a (.dat) file, or to + * a package registered with udata_setAppData(). Using a full file or directory + * pathname for packageName is deprecated. If NULL, ICU data will be used. + * @param locale specifies the locale for which we want to open the resource + * if NULL, the default locale will be used. If strlen(locale) == 0 + * root locale will be used. + * @param status fills in the outgoing error code. + * @return a newly allocated resource bundle. + * @see ures_open + * @stable ICU 2.0 + */ +U_STABLE UResourceBundle* U_EXPORT2 +ures_openU(const UChar* packageName, + const char* locale, + UErrorCode* status); + +/** + * Returns the number of strings/arrays in resource bundles. + * Better to use ures_getSize, as this function will be deprecated. + * + *@param resourceBundle resource bundle containing the desired strings + *@param resourceKey key tagging the resource + *@param err fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * could be a non-failing error + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_FALLBACK_WARNING </TT> + *@return: for <STRONG>Arrays</STRONG>: returns the number of resources in the array + * <STRONG>Tables</STRONG>: returns the number of resources in the table + * <STRONG>single string</STRONG>: returns 1 + *@see ures_getSize + * @deprecated ICU 2.8 User ures_getSize instead + */ +U_DEPRECATED int32_t U_EXPORT2 +ures_countArrayItems(const UResourceBundle* resourceBundle, + const char* resourceKey, + UErrorCode* err); +/** + * Close a resource bundle, all pointers returned from the various ures_getXXX calls + * on this particular bundle should be considered invalid henceforth. + * + * @param resourceBundle a pointer to a resourceBundle struct. Can be NULL. + * @see ures_open + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ures_close(UResourceBundle* resourceBundle); + +/** + * Return the version number associated with this ResourceBundle as a string. Please + * use ures_getVersion as this function is going to be deprecated. + * + * @param resourceBundle The resource bundle for which the version is checked. + * @return A version number string as specified in the resource bundle or its parent. + * The caller does not own this string. + * @see ures_getVersion + * @deprecated ICU 2.8 Use ures_getVersion instead. + */ +U_DEPRECATED const char* U_EXPORT2 +ures_getVersionNumber(const UResourceBundle* resourceBundle); + +/** + * Return the version number associated with this ResourceBundle as an + * UVersionInfo array. + * + * @param resB The resource bundle for which the version is checked. + * @param versionInfo A UVersionInfo array that is filled with the version number + * as specified in the resource bundle or its parent. + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ures_getVersion(const UResourceBundle* resB, + UVersionInfo versionInfo); + +/** + * Return the name of the Locale associated with this ResourceBundle. This API allows + * you to query for the real locale of the resource. For example, if you requested + * "en_US_CALIFORNIA" and only "en_US" bundle exists, "en_US" will be returned. + * For subresources, the locale where this resource comes from will be returned. + * If fallback has occured, getLocale will reflect this. + * + * @param resourceBundle resource bundle in question + * @param status just for catching illegal arguments + * @return A Locale name + * @deprecated ICU 2.8 Use ures_getLocaleByType instead. + */ +U_DEPRECATED const char* U_EXPORT2 +ures_getLocale(const UResourceBundle* resourceBundle, + UErrorCode* status); + + +/** + * Return the name of the Locale associated with this ResourceBundle. + * You can choose between requested, valid and real locale. + * + * @param resourceBundle resource bundle in question + * @param type You can choose between requested, valid and actual + * locale. For description see the definition of + * ULocDataLocaleType in uloc.h + * @param status just for catching illegal arguments + * @return A Locale name + * @stable ICU 2.8 + */ +U_STABLE const char* U_EXPORT2 +ures_getLocaleByType(const UResourceBundle* resourceBundle, + ULocDataLocaleType type, + UErrorCode* status); + + +/** + * Same as ures_open() but uses the fill-in parameter instead of allocating + * a bundle, if r!=NULL. + * TODO need to revisit usefulness of this function + * and usage model for fillIn parameters without knowing sizeof(UResourceBundle) + * @param r The resourcebundle to open + * @param packageName The packageName and locale together point to an ICU udata object, + * as defined by <code> udata_open( packageName, "res", locale, err) </code> + * or equivalent. Typically, packageName will refer to a (.dat) file, or to + * a package registered with udata_setAppData(). Using a full file or directory + * pathname for packageName is deprecated. If NULL, ICU data will be used. + * @param localeID specifies the locale for which we want to open the resource + * @param status The error code + * @return a newly allocated resource bundle or NULL if it doesn't exist. + * @internal + */ +U_INTERNAL void U_EXPORT2 +ures_openFillIn(UResourceBundle *r, + const char* packageName, + const char* localeID, + UErrorCode* status); + +/** + * Returns a string from a string resource type + * + * @param resourceBundle a string resource + * @param len fills in the length of resulting string + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * Always check the value of status. Don't count on returning NULL. + * could be a non-failing error + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. + * @see ures_getBinary + * @see ures_getIntVector + * @see ures_getInt + * @see ures_getUInt + * @stable ICU 2.0 + */ +U_STABLE const UChar* U_EXPORT2 +ures_getString(const UResourceBundle* resourceBundle, + int32_t* len, + UErrorCode* status); + +/** + * Returns a UTF-8 string from a string resource. + * The UTF-8 string may be returnable directly as a pointer, or + * it may need to be copied, or transformed from UTF-16 using u_strToUTF8() + * or equivalent. + * + * If forceCopy==TRUE, then the string is always written to the dest buffer + * and dest is returned. + * + * If forceCopy==FALSE, then the string is returned as a pointer if possible, + * without needing a dest buffer (it can be NULL). If the string needs to be + * copied or transformed, then it may be placed into dest at an arbitrary offset. + * + * If the string is to be written to dest, then U_BUFFER_OVERFLOW_ERROR and + * U_STRING_NOT_TERMINATED_WARNING are set if appropriate, as usual. + * + * If the string is transformed from UTF-16, then a conversion error may occur + * if an unpaired surrogate is encountered. If the function is successful, then + * the output UTF-8 string is always well-formed. + * + * @param resB Resource bundle. + * @param dest Destination buffer. Can be NULL only if capacity=*length==0. + * @param length Input: Capacity of destination buffer. + * Output: Actual length of the UTF-8 string, not counting the + * terminating NUL, even in case of U_BUFFER_OVERFLOW_ERROR. + * Can be NULL, meaning capacity=0 and the string length is not + * returned to the caller. + * @param forceCopy If TRUE, then the output string will always be written to + * dest, with U_BUFFER_OVERFLOW_ERROR and + * U_STRING_NOT_TERMINATED_WARNING set if appropriate. + * If FALSE, then the dest buffer may or may not contain a + * copy of the string. dest may or may not be modified. + * If a copy needs to be written, then the UErrorCode parameter + * indicates overflow etc. as usual. + * @param status Pointer to a standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @return The pointer to the UTF-8 string. It may be dest, or at some offset + * from dest (only if !forceCopy), or in unrelated memory. + * Always NUL-terminated unless the string was written to dest and + * length==capacity (in which case U_STRING_NOT_TERMINATED_WARNING is set). + * + * @see ures_getString + * @see u_strToUTF8 + * @stable ICU 3.6 + */ +U_STABLE const char * U_EXPORT2 +ures_getUTF8String(const UResourceBundle *resB, + char *dest, int32_t *length, + UBool forceCopy, + UErrorCode *status); + +/** + * Returns a binary data from a binary resource. + * + * @param resourceBundle a string resource + * @param len fills in the length of resulting byte chunk + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * Always check the value of status. Don't count on returning NULL. + * could be a non-failing error + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return a pointer to a chuck of unsigned bytes which live in a memory mapped/DLL file. + * @see ures_getString + * @see ures_getIntVector + * @see ures_getInt + * @see ures_getUInt + * @stable ICU 2.0 + */ +U_STABLE const uint8_t* U_EXPORT2 +ures_getBinary(const UResourceBundle* resourceBundle, + int32_t* len, + UErrorCode* status); + +/** + * Returns a 32 bit integer array from a resource. + * + * @param resourceBundle an int vector resource + * @param len fills in the length of resulting byte chunk + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * Always check the value of status. Don't count on returning NULL. + * could be a non-failing error + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return a pointer to a chunk of unsigned bytes which live in a memory mapped/DLL file. + * @see ures_getBinary + * @see ures_getString + * @see ures_getInt + * @see ures_getUInt + * @stable ICU 2.0 + */ +U_STABLE const int32_t* U_EXPORT2 +ures_getIntVector(const UResourceBundle* resourceBundle, + int32_t* len, + UErrorCode* status); + +/** + * Returns an unsigned integer from a resource. + * This integer is originally 28 bits. + * + * @param resourceBundle a string resource + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * could be a non-failing error + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return an integer value + * @see ures_getInt + * @see ures_getIntVector + * @see ures_getBinary + * @see ures_getString + * @stable ICU 2.0 + */ +U_STABLE uint32_t U_EXPORT2 +ures_getUInt(const UResourceBundle* resourceBundle, + UErrorCode *status); + +/** + * Returns a signed integer from a resource. + * This integer is originally 28 bit and the sign gets propagated. + * + * @param resourceBundle a string resource + * @param status fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * could be a non-failing error + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return an integer value + * @see ures_getUInt + * @see ures_getIntVector + * @see ures_getBinary + * @see ures_getString + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ures_getInt(const UResourceBundle* resourceBundle, + UErrorCode *status); + +/** + * Returns the size of a resource. Size for scalar types is always 1, + * and for vector/table types is the number of child resources. + * @warning Integer array is treated as a scalar type. There are no + * APIs to access individual members of an integer array. It + * is always returned as a whole. + * @param resourceBundle a resource + * @return number of resources in a given resource. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +ures_getSize(const UResourceBundle *resourceBundle); + +/** + * Returns the type of a resource. Available types are defined in enum UResType + * + * @param resourceBundle a resource + * @return type of the given resource. + * @see UResType + * @stable ICU 2.0 + */ +U_STABLE UResType U_EXPORT2 +ures_getType(const UResourceBundle *resourceBundle); + +/** + * Returns the key associated with a given resource. Not all the resources have a key - only + * those that are members of a table. + * + * @param resourceBundle a resource + * @return a key associated to this resource, or NULL if it doesn't have a key + * @stable ICU 2.0 + */ +U_STABLE const char * U_EXPORT2 +ures_getKey(const UResourceBundle *resourceBundle); + +/* ITERATION API + This API provides means for iterating through a resource +*/ + +/** + * Resets the internal context of a resource so that iteration starts from the first element. + * + * @param resourceBundle a resource + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +ures_resetIterator(UResourceBundle *resourceBundle); + +/** + * Checks whether the given resource has another element to iterate over. + * + * @param resourceBundle a resource + * @return TRUE if there are more elements, FALSE if there is no more elements + * @stable ICU 2.0 + */ +U_STABLE UBool U_EXPORT2 +ures_hasNext(const UResourceBundle *resourceBundle); + +/** + * Returns the next resource in a given resource or NULL if there are no more resources + * to iterate over. Features a fill-in parameter. + * + * @param resourceBundle a resource + * @param fillIn if NULL a new UResourceBundle struct is allocated and must be closed by the caller. + * Alternatively, you can supply a struct to be filled by this function. + * @param status fills in the outgoing error code. You may still get a non NULL result even if an + * error occured. Check status instead. + * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must close it + * @stable ICU 2.0 + */ +U_STABLE UResourceBundle* U_EXPORT2 +ures_getNextResource(UResourceBundle *resourceBundle, + UResourceBundle *fillIn, + UErrorCode *status); + +/** + * Returns the next string in a given resource or NULL if there are no more resources + * to iterate over. + * + * @param resourceBundle a resource + * @param len fill in length of the string + * @param key fill in for key associated with this string. NULL if no key + * @param status fills in the outgoing error code. If an error occured, we may return NULL, but don't + * count on it. Check status instead! + * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. + * @stable ICU 2.0 + */ +U_STABLE const UChar* U_EXPORT2 +ures_getNextString(UResourceBundle *resourceBundle, + int32_t* len, + const char ** key, + UErrorCode *status); + +/** + * Returns the resource in a given resource at the specified index. Features a fill-in parameter. + * + * @param resourceBundle the resource bundle from which to get a sub-resource + * @param indexR an index to the wanted resource. + * @param fillIn if NULL a new UResourceBundle struct is allocated and must be closed by the caller. + * Alternatively, you can supply a struct to be filled by this function. + * @param status fills in the outgoing error code. Don't count on NULL being returned if an error has + * occured. Check status instead. + * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must close it + * @stable ICU 2.0 + */ +U_STABLE UResourceBundle* U_EXPORT2 +ures_getByIndex(const UResourceBundle *resourceBundle, + int32_t indexR, + UResourceBundle *fillIn, + UErrorCode *status); + +/** + * Returns the string in a given resource at the specified index. + * + * @param resourceBundle a resource + * @param indexS an index to the wanted string. + * @param len fill in length of the string + * @param status fills in the outgoing error code. If an error occured, we may return NULL, but don't + * count on it. Check status instead! + * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. + * @stable ICU 2.0 + */ +U_STABLE const UChar* U_EXPORT2 +ures_getStringByIndex(const UResourceBundle *resourceBundle, + int32_t indexS, + int32_t* len, + UErrorCode *status); + +/** + * Returns a UTF-8 string from a resource at the specified index. + * The UTF-8 string may be returnable directly as a pointer, or + * it may need to be copied, or transformed from UTF-16 using u_strToUTF8() + * or equivalent. + * + * If forceCopy==TRUE, then the string is always written to the dest buffer + * and dest is returned. + * + * If forceCopy==FALSE, then the string is returned as a pointer if possible, + * without needing a dest buffer (it can be NULL). If the string needs to be + * copied or transformed, then it may be placed into dest at an arbitrary offset. + * + * If the string is to be written to dest, then U_BUFFER_OVERFLOW_ERROR and + * U_STRING_NOT_TERMINATED_WARNING are set if appropriate, as usual. + * + * If the string is transformed from UTF-16, then a conversion error may occur + * if an unpaired surrogate is encountered. If the function is successful, then + * the output UTF-8 string is always well-formed. + * + * @param resB Resource bundle. + * @param index An index to the wanted string. + * @param dest Destination buffer. Can be NULL only if capacity=*length==0. + * @param pLength Input: Capacity of destination buffer. + * Output: Actual length of the UTF-8 string, not counting the + * terminating NUL, even in case of U_BUFFER_OVERFLOW_ERROR. + * Can be NULL, meaning capacity=0 and the string length is not + * returned to the caller. + * @param forceCopy If TRUE, then the output string will always be written to + * dest, with U_BUFFER_OVERFLOW_ERROR and + * U_STRING_NOT_TERMINATED_WARNING set if appropriate. + * If FALSE, then the dest buffer may or may not contain a + * copy of the string. dest may or may not be modified. + * If a copy needs to be written, then the UErrorCode parameter + * indicates overflow etc. as usual. + * @param status Pointer to a standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @return The pointer to the UTF-8 string. It may be dest, or at some offset + * from dest (only if !forceCopy), or in unrelated memory. + * Always NUL-terminated unless the string was written to dest and + * length==capacity (in which case U_STRING_NOT_TERMINATED_WARNING is set). + * + * @see ures_getStringByIndex + * @see u_strToUTF8 + * @stable ICU 3.6 + */ +U_STABLE const char * U_EXPORT2 +ures_getUTF8StringByIndex(const UResourceBundle *resB, + int32_t index, + char *dest, int32_t *pLength, + UBool forceCopy, + UErrorCode *status); + +/** + * Returns a resource in a given resource that has a given key. This procedure works only with table + * resources. Features a fill-in parameter. + * + * @param resourceBundle a resource + * @param key a key associated with the wanted resource + * @param fillIn if NULL a new UResourceBundle struct is allocated and must be closed by the caller. + * Alternatively, you can supply a struct to be filled by this function. + * @param status fills in the outgoing error code. + * @return a pointer to a UResourceBundle struct. If fill in param was NULL, caller must close it + * @stable ICU 2.0 + */ +U_STABLE UResourceBundle* U_EXPORT2 +ures_getByKey(const UResourceBundle *resourceBundle, + const char* key, + UResourceBundle *fillIn, + UErrorCode *status); + +/** + * Returns a string in a given resource that has a given key. This procedure works only with table + * resources. + * + * @param resB a resource + * @param key a key associated with the wanted string + * @param len fill in length of the string + * @param status fills in the outgoing error code. If an error occured, we may return NULL, but don't + * count on it. Check status instead! + * @return a pointer to a zero-terminated UChar array which lives in a memory mapped/DLL file. + * @stable ICU 2.0 + */ +U_STABLE const UChar* U_EXPORT2 +ures_getStringByKey(const UResourceBundle *resB, + const char* key, + int32_t* len, + UErrorCode *status); + +/** + * Returns a UTF-8 string from a resource and a key. + * This function works only with table resources. + * + * The UTF-8 string may be returnable directly as a pointer, or + * it may need to be copied, or transformed from UTF-16 using u_strToUTF8() + * or equivalent. + * + * If forceCopy==TRUE, then the string is always written to the dest buffer + * and dest is returned. + * + * If forceCopy==FALSE, then the string is returned as a pointer if possible, + * without needing a dest buffer (it can be NULL). If the string needs to be + * copied or transformed, then it may be placed into dest at an arbitrary offset. + * + * If the string is to be written to dest, then U_BUFFER_OVERFLOW_ERROR and + * U_STRING_NOT_TERMINATED_WARNING are set if appropriate, as usual. + * + * If the string is transformed from UTF-16, then a conversion error may occur + * if an unpaired surrogate is encountered. If the function is successful, then + * the output UTF-8 string is always well-formed. + * + * @param resB Resource bundle. + * @param key A key associated with the wanted resource + * @param dest Destination buffer. Can be NULL only if capacity=*length==0. + * @param pLength Input: Capacity of destination buffer. + * Output: Actual length of the UTF-8 string, not counting the + * terminating NUL, even in case of U_BUFFER_OVERFLOW_ERROR. + * Can be NULL, meaning capacity=0 and the string length is not + * returned to the caller. + * @param forceCopy If TRUE, then the output string will always be written to + * dest, with U_BUFFER_OVERFLOW_ERROR and + * U_STRING_NOT_TERMINATED_WARNING set if appropriate. + * If FALSE, then the dest buffer may or may not contain a + * copy of the string. dest may or may not be modified. + * If a copy needs to be written, then the UErrorCode parameter + * indicates overflow etc. as usual. + * @param status Pointer to a standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @return The pointer to the UTF-8 string. It may be dest, or at some offset + * from dest (only if !forceCopy), or in unrelated memory. + * Always NUL-terminated unless the string was written to dest and + * length==capacity (in which case U_STRING_NOT_TERMINATED_WARNING is set). + * + * @see ures_getStringByKey + * @see u_strToUTF8 + * @stable ICU 3.6 + */ +U_STABLE const char * U_EXPORT2 +ures_getUTF8StringByKey(const UResourceBundle *resB, + const char *key, + char *dest, int32_t *pLength, + UBool forceCopy, + UErrorCode *status); + +#ifdef XP_CPLUSPLUS +#include "unicode/unistr.h" + +U_NAMESPACE_BEGIN +/** + * returns a string from a string resource type + * + * @param resB a resource + * @param status: fills in the outgoing error code + * could be <TT>U_MISSING_RESOURCE_ERROR</TT> if the key is not found + * could be a non-failing error + * e.g.: <TT>U_USING_FALLBACK_WARNING</TT>,<TT>U_USING_DEFAULT_WARNING </TT> + * @return a UnicodeString object. If there is an error, string is bogus + * @stable ICU 2.0 + */ +inline UnicodeString +ures_getUnicodeString(const UResourceBundle *resB, + UErrorCode* status) +{ + int32_t len = 0; + const UChar *r = ures_getString(resB, &len, status); + return UnicodeString(TRUE, r, len); +} + +/** + * Returns the next string in a resource or NULL if there are no more resources + * to iterate over. + * + * @param resB a resource + * @param key fill in for key associated with this string + * @param status fills in the outgoing error code + * @return an UnicodeString object. + * @stable ICU 2.0 + */ +inline UnicodeString +ures_getNextUnicodeString(UResourceBundle *resB, + const char ** key, + UErrorCode* status) +{ + int32_t len = 0; + const UChar* r = ures_getNextString(resB, &len, key, status); + return UnicodeString(TRUE, r, len); +} + +/** + * Returns the string in a given resource at the specified index. + * + * @param resB a resource + * @param index an index to the wanted string. + * @param status fills in the outgoing error code + * @return an UnicodeString object. If there is an error, string is bogus + * @stable ICU 2.0 + */ +inline UnicodeString +ures_getUnicodeStringByIndex(const UResourceBundle *resB, + int32_t indexS, + UErrorCode* status) +{ + int32_t len = 0; + const UChar* r = ures_getStringByIndex(resB, indexS, &len, status); + return UnicodeString(TRUE, r, len); +} + +/** + * Returns a string in a resource that has a given key. This procedure works only with table + * resources. + * + * @param resB a resource + * @param key a key associated with the wanted string + * @param status fills in the outgoing error code + * @return an UnicodeString object. If there is an error, string is bogus + * @stable ICU 2.0 + */ +inline UnicodeString +ures_getUnicodeStringByKey(const UResourceBundle *resB, + const char* key, + UErrorCode* status) +{ + int32_t len = 0; + const UChar* r = ures_getStringByKey(resB, key, &len, status); + return UnicodeString(TRUE, r, len); +} + +U_NAMESPACE_END + +#endif + +/** + * Create a string enumerator, owned by the caller, of all locales located within + * the specified resource tree. + * @param packageName name of the tree, such as (NULL) or U_ICUDATA_ALIAS or or "ICUDATA-coll" + * This call is similar to uloc_getAvailable(). + * @param status error code + * @stable ICU 3.2 + */ +U_STABLE UEnumeration* U_EXPORT2 +ures_openAvailableLocales(const char *packageName, UErrorCode *status); + + +#endif /*_URES*/ +/*eof*/ diff --git a/utils/openttd/unicode/uscript.h b/utils/openttd/unicode/uscript.h new file mode 100644 index 00000000000..c915d8dfd42 --- /dev/null +++ b/utils/openttd/unicode/uscript.h @@ -0,0 +1,254 @@ +/* + ********************************************************************** + * Copyright (C) 1997-2008, International Business Machines + * Corporation and others. All Rights Reserved. + ********************************************************************** + * + * File USCRIPT.H + * + * Modification History: + * + * Date Name Description + * 07/06/2001 Ram Creation. + ****************************************************************************** + */ + +#ifndef USCRIPT_H +#define USCRIPT_H +#include "unicode/utypes.h" + +/** + * \file + * \brief C API: Unicode Script Information + */ + +/** + * Constants for ISO 15924 script codes. + * + * Many of these script codes - those from Unicode's ScriptNames.txt - + * are character property values for Unicode's Script property. + * See UAX #24 Script Names (http://www.unicode.org/reports/tr24/). + * + * Starting with ICU 3.6, constants for most ISO 15924 script codes + * are included (currently excluding private-use codes Qaaa..Qabx). + * For scripts for which there are codes in ISO 15924 but which are not + * used in the Unicode Character Database (UCD), there are no Unicode characters + * associated with those scripts. + * + * For example, there are no characters that have a UCD script code of + * Hans or Hant. All Han ideographs have the Hani script code. + * The Hans and Hant script codes are used with CLDR data. + * + * ISO 15924 script codes are included for use with CLDR and similar. + * + * @stable ICU 2.2 + */ +typedef enum UScriptCode { + USCRIPT_INVALID_CODE = -1, + USCRIPT_COMMON = 0 , /* Zyyy */ + USCRIPT_INHERITED = 1, /* Qaai */ + USCRIPT_ARABIC = 2, /* Arab */ + USCRIPT_ARMENIAN = 3, /* Armn */ + USCRIPT_BENGALI = 4, /* Beng */ + USCRIPT_BOPOMOFO = 5, /* Bopo */ + USCRIPT_CHEROKEE = 6, /* Cher */ + USCRIPT_COPTIC = 7, /* Copt */ + USCRIPT_CYRILLIC = 8, /* Cyrl */ + USCRIPT_DESERET = 9, /* Dsrt */ + USCRIPT_DEVANAGARI = 10, /* Deva */ + USCRIPT_ETHIOPIC = 11, /* Ethi */ + USCRIPT_GEORGIAN = 12, /* Geor */ + USCRIPT_GOTHIC = 13, /* Goth */ + USCRIPT_GREEK = 14, /* Grek */ + USCRIPT_GUJARATI = 15, /* Gujr */ + USCRIPT_GURMUKHI = 16, /* Guru */ + USCRIPT_HAN = 17, /* Hani */ + USCRIPT_HANGUL = 18, /* Hang */ + USCRIPT_HEBREW = 19, /* Hebr */ + USCRIPT_HIRAGANA = 20, /* Hira */ + USCRIPT_KANNADA = 21, /* Knda */ + USCRIPT_KATAKANA = 22, /* Kana */ + USCRIPT_KHMER = 23, /* Khmr */ + USCRIPT_LAO = 24, /* Laoo */ + USCRIPT_LATIN = 25, /* Latn */ + USCRIPT_MALAYALAM = 26, /* Mlym */ + USCRIPT_MONGOLIAN = 27, /* Mong */ + USCRIPT_MYANMAR = 28, /* Mymr */ + USCRIPT_OGHAM = 29, /* Ogam */ + USCRIPT_OLD_ITALIC = 30, /* Ital */ + USCRIPT_ORIYA = 31, /* Orya */ + USCRIPT_RUNIC = 32, /* Runr */ + USCRIPT_SINHALA = 33, /* Sinh */ + USCRIPT_SYRIAC = 34, /* Syrc */ + USCRIPT_TAMIL = 35, /* Taml */ + USCRIPT_TELUGU = 36, /* Telu */ + USCRIPT_THAANA = 37, /* Thaa */ + USCRIPT_THAI = 38, /* Thai */ + USCRIPT_TIBETAN = 39, /* Tibt */ + /** Canadian_Aboriginal script. @stable ICU 2.6 */ + USCRIPT_CANADIAN_ABORIGINAL = 40, /* Cans */ + /** Canadian_Aboriginal script (alias). @stable ICU 2.2 */ + USCRIPT_UCAS = USCRIPT_CANADIAN_ABORIGINAL, + USCRIPT_YI = 41, /* Yiii */ + USCRIPT_TAGALOG = 42, /* Tglg */ + USCRIPT_HANUNOO = 43, /* Hano */ + USCRIPT_BUHID = 44, /* Buhd */ + USCRIPT_TAGBANWA = 45, /* Tagb */ + + /* New scripts in Unicode 4 @stable ICU 2.6 */ + USCRIPT_BRAILLE = 46, /* Brai */ + USCRIPT_CYPRIOT = 47, /* Cprt */ + USCRIPT_LIMBU = 48, /* Limb */ + USCRIPT_LINEAR_B = 49, /* Linb */ + USCRIPT_OSMANYA = 50, /* Osma */ + USCRIPT_SHAVIAN = 51, /* Shaw */ + USCRIPT_TAI_LE = 52, /* Tale */ + USCRIPT_UGARITIC = 53, /* Ugar */ + + /** New script code in Unicode 4.0.1 @stable ICU 3.0 */ + USCRIPT_KATAKANA_OR_HIRAGANA = 54,/*Hrkt */ + + /* New scripts in Unicode 4.1 @stable ICU 3.4 */ + USCRIPT_BUGINESE = 55, /* Bugi */ + USCRIPT_GLAGOLITIC = 56, /* Glag */ + USCRIPT_KHAROSHTHI = 57, /* Khar */ + USCRIPT_SYLOTI_NAGRI = 58, /* Sylo */ + USCRIPT_NEW_TAI_LUE = 59, /* Talu */ + USCRIPT_TIFINAGH = 60, /* Tfng */ + USCRIPT_OLD_PERSIAN = 61, /* Xpeo */ + + /* New script codes from ISO 15924 @stable ICU 3.6 */ + USCRIPT_BALINESE = 62, /* Bali */ + USCRIPT_BATAK = 63, /* Batk */ + USCRIPT_BLISSYMBOLS = 64, /* Blis */ + USCRIPT_BRAHMI = 65, /* Brah */ + USCRIPT_CHAM = 66, /* Cham */ + USCRIPT_CIRTH = 67, /* Cirt */ + USCRIPT_OLD_CHURCH_SLAVONIC_CYRILLIC = 68, /* Cyrs */ + USCRIPT_DEMOTIC_EGYPTIAN = 69, /* Egyd */ + USCRIPT_HIERATIC_EGYPTIAN = 70, /* Egyh */ + USCRIPT_EGYPTIAN_HIEROGLYPHS = 71, /* Egyp */ + USCRIPT_KHUTSURI = 72, /* Geok */ + USCRIPT_SIMPLIFIED_HAN = 73, /* Hans */ + USCRIPT_TRADITIONAL_HAN = 74, /* Hant */ + USCRIPT_PAHAWH_HMONG = 75, /* Hmng */ + USCRIPT_OLD_HUNGARIAN = 76, /* Hung */ + USCRIPT_HARAPPAN_INDUS = 77, /* Inds */ + USCRIPT_JAVANESE = 78, /* Java */ + USCRIPT_KAYAH_LI = 79, /* Kali */ + USCRIPT_LATIN_FRAKTUR = 80, /* Latf */ + USCRIPT_LATIN_GAELIC = 81, /* Latg */ + USCRIPT_LEPCHA = 82, /* Lepc */ + USCRIPT_LINEAR_A = 83, /* Lina */ + USCRIPT_MANDAEAN = 84, /* Mand */ + USCRIPT_MAYAN_HIEROGLYPHS = 85, /* Maya */ + USCRIPT_MEROITIC = 86, /* Mero */ + USCRIPT_NKO = 87, /* Nkoo */ + USCRIPT_ORKHON = 88, /* Orkh */ + USCRIPT_OLD_PERMIC = 89, /* Perm */ + USCRIPT_PHAGS_PA = 90, /* Phag */ + USCRIPT_PHOENICIAN = 91, /* Phnx */ + USCRIPT_PHONETIC_POLLARD = 92, /* Plrd */ + USCRIPT_RONGORONGO = 93, /* Roro */ + USCRIPT_SARATI = 94, /* Sara */ + USCRIPT_ESTRANGELO_SYRIAC = 95, /* Syre */ + USCRIPT_WESTERN_SYRIAC = 96, /* Syrj */ + USCRIPT_EASTERN_SYRIAC = 97, /* Syrn */ + USCRIPT_TENGWAR = 98, /* Teng */ + USCRIPT_VAI = 99, /* Vaii */ + USCRIPT_VISIBLE_SPEECH = 100, /* Visp */ + USCRIPT_CUNEIFORM = 101,/* Xsux */ + USCRIPT_UNWRITTEN_LANGUAGES = 102,/* Zxxx */ + USCRIPT_UNKNOWN = 103,/* Zzzz */ /* Unknown="Code for uncoded script", for unassigned code points */ + + /* New script codes from ISO 15924 @stable ICU 4.0 */ + USCRIPT_CARIAN = 104,/* Cari */ + USCRIPT_JAPANESE = 105,/* Jpan */ + USCRIPT_LANNA = 106,/* Lana */ + USCRIPT_LYCIAN = 107,/* Lyci */ + USCRIPT_LYDIAN = 108,/* Lydi */ + USCRIPT_OL_CHIKI = 109,/* Olck */ + USCRIPT_REJANG = 110,/* Rjng */ + USCRIPT_SAURASHTRA = 111,/* Saur */ + USCRIPT_SIGN_WRITING = 112,/* Sgnw */ + USCRIPT_SUNDANESE = 113,/* Sund */ + USCRIPT_MOON = 114,/* Moon */ + USCRIPT_MEITEI_MAYEK = 115,/* Mtei */ + + /* New script codes from ISO 15924 @draft ICU 4.0 */ + USCRIPT_IMPERIAL_ARAMAIC = 116,/* Armi */ + USCRIPT_AVESTAN = 117,/* Avst */ + USCRIPT_CHAKMA = 118,/* Cakm */ + USCRIPT_KOREAN = 119,/* Kore */ + USCRIPT_KAITHI = 120,/* Kthi */ + USCRIPT_MANICHAEAN = 121,/* Mani */ + USCRIPT_INSCRIPTIONAL_PAHLAVI = 122,/* Phli */ + USCRIPT_PSALTER_PAHLAVI = 123,/* Phlp */ + USCRIPT_BOOK_PAHLAVI = 124,/* Phlv */ + USCRIPT_INSCRIPTIONAL_PARTHIAN = 125,/* Prti */ + USCRIPT_SAMARITAN = 126,/* Samr */ + USCRIPT_TAI_VIET = 127,/* Tavt */ + USCRIPT_MATHEMATICAL_NOTATION = 128,/* Zmth */ + USCRIPT_SYMBOLS = 129,/* Zsym */ + + /* Private use codes from Qaaa - Qabx are not supported*/ + USCRIPT_CODE_LIMIT = 130 +} UScriptCode; + +/** + * Gets script codes associated with the given locale or ISO 15924 abbreviation or name. + * Fills in USCRIPT_MALAYALAM given "Malayam" OR "Mlym". + * Fills in USCRIPT_LATIN given "en" OR "en_US" + * If required capacity is greater than capacity of the destination buffer then the error code + * is set to U_BUFFER_OVERFLOW_ERROR and the required capacity is returned + * + * <p>Note: To search by short or long script alias only, use + * u_getPropertyValueEnum(UCHAR_SCRIPT, alias) instead. This does + * a fast lookup with no access of the locale data. + * @param nameOrAbbrOrLocale name of the script, as given in + * PropertyValueAliases.txt, or ISO 15924 code or locale + * @param fillIn the UScriptCode buffer to fill in the script code + * @param capacity the capacity (size) fo UScriptCode buffer passed in. + * @param err the error status code. + * @return The number of script codes filled in the buffer passed in + * @stable ICU 2.4 + */ +U_STABLE int32_t U_EXPORT2 +uscript_getCode(const char* nameOrAbbrOrLocale,UScriptCode* fillIn,int32_t capacity,UErrorCode *err); + +/** + * Gets a script name associated with the given script code. + * Returns "Malayam" given USCRIPT_MALAYALAM + * @param scriptCode UScriptCode enum + * @return script long name as given in + * PropertyValueAliases.txt, or NULL if scriptCode is invalid + * @stable ICU 2.4 + */ +U_STABLE const char* U_EXPORT2 +uscript_getName(UScriptCode scriptCode); + +/** + * Gets a script name associated with the given script code. + * Returns "Mlym" given USCRIPT_MALAYALAM + * @param scriptCode UScriptCode enum + * @return script abbreviated name as given in + * PropertyValueAliases.txt, or NULL if scriptCode is invalid + * @stable ICU 2.4 + */ +U_STABLE const char* U_EXPORT2 +uscript_getShortName(UScriptCode scriptCode); + +/** + * Gets the script code associated with the given codepoint. + * Returns USCRIPT_MALAYALAM given 0x0D02 + * @param codepoint UChar32 codepoint + * @param err the error status code. + * @return The UScriptCode, or 0 if codepoint is invalid + * @stable ICU 2.4 + */ +U_STABLE UScriptCode U_EXPORT2 +uscript_getScript(UChar32 codepoint, UErrorCode *err); + +#endif + + diff --git a/utils/openttd/unicode/uset.h b/utils/openttd/unicode/uset.h new file mode 100644 index 00000000000..8fb09fa4487 --- /dev/null +++ b/utils/openttd/unicode/uset.h @@ -0,0 +1,1056 @@ +/* +******************************************************************************* +* +* Copyright (C) 2002-2008, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: uset.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2002mar07 +* created by: Markus W. Scherer +* +* C version of UnicodeSet. +*/ + + +/** + * \file + * \brief C API: Unicode Set + * + * <p>This is a C wrapper around the C++ UnicodeSet class.</p> + */ + +#ifndef __USET_H__ +#define __USET_H__ + +#include "unicode/utypes.h" +#include "unicode/uchar.h" + +#ifndef UCNV_H +struct USet; +/** + * A UnicodeSet. Use the uset_* API to manipulate. Create with + * uset_open*, and destroy with uset_close. + * @stable ICU 2.4 + */ +typedef struct USet USet; +#endif + +/** + * Bitmask values to be passed to uset_openPatternOptions() or + * uset_applyPattern() taking an option parameter. + * @stable ICU 2.4 + */ +enum { + /** + * Ignore white space within patterns unless quoted or escaped. + * @stable ICU 2.4 + */ + USET_IGNORE_SPACE = 1, + + /** + * Enable case insensitive matching. E.g., "[ab]" with this flag + * will match 'a', 'A', 'b', and 'B'. "[^ab]" with this flag will + * match all except 'a', 'A', 'b', and 'B'. This performs a full + * closure over case mappings, e.g. U+017F for s. + * + * The resulting set is a superset of the input for the code points but + * not for the strings. + * It performs a case mapping closure of the code points and adds + * full case folding strings for the code points, and reduces strings of + * the original set to their full case folding equivalents. + * + * This is designed for case-insensitive matches, for example + * in regular expressions. The full code point case closure allows checking of + * an input character directly against the closure set. + * Strings are matched by comparing the case-folded form from the closure + * set with an incremental case folding of the string in question. + * + * The closure set will also contain single code points if the original + * set contained case-equivalent strings (like U+00DF for "ss" or "Ss" etc.). + * This is not necessary (that is, redundant) for the above matching method + * but results in the same closure sets regardless of whether the original + * set contained the code point or a string. + * + * @stable ICU 2.4 + */ + USET_CASE_INSENSITIVE = 2, + + /** + * Enable case insensitive matching. E.g., "[ab]" with this flag + * will match 'a', 'A', 'b', and 'B'. "[^ab]" with this flag will + * match all except 'a', 'A', 'b', and 'B'. This adds the lower-, + * title-, and uppercase mappings as well as the case folding + * of each existing element in the set. + * @stable ICU 3.2 + */ + USET_ADD_CASE_MAPPINGS = 4, + + /** + * Enough for any single-code point set + * @internal + */ + USET_SERIALIZED_STATIC_ARRAY_CAPACITY=8 +}; + +#ifndef U_HIDE_DRAFT_API + +/** + * Argument values for whether span() and similar functions continue while + * the current character is contained vs. not contained in the set. + * + * The functionality is straightforward for sets with only single code points, + * without strings (which is the common case): + * - USET_SPAN_CONTAINED and USET_SPAN_SIMPLE + * work the same. + * - span() and spanBack() partition any string the same way when + * alternating between span(USET_SPAN_NOT_CONTAINED) and + * span(either "contained" condition). + * - Using a complemented (inverted) set and the opposite span conditions + * yields the same results. + * + * When a set contains multi-code point strings, then these statements may not + * be true, depending on the strings in the set (for example, whether they + * overlap with each other) and the string that is processed. + * For a set with strings: + * - The complement of the set contains the opposite set of code points, + * but the same set of strings. + * Therefore, complementing both the set and the span conditions + * may yield different results. + * - When starting spans at different positions in a string + * (span(s, ...) vs. span(s+1, ...)) the ends of the spans may be different + * because a set string may start before the later position. + * - span(USET_SPAN_SIMPLE) may be shorter than + * span(USET_SPAN_CONTAINED) because it will not recursively try + * all possible paths. + * For example, with a set which contains the three strings "xy", "xya" and "ax", + * span("xyax", USET_SPAN_CONTAINED) will return 4 but + * span("xyax", USET_SPAN_SIMPLE) will return 3. + * span(USET_SPAN_SIMPLE) will never be longer than + * span(USET_SPAN_CONTAINED). + * - With either "contained" condition, span() and spanBack() may partition + * a string in different ways. + * For example, with a set which contains the two strings "ab" and "ba", + * and when processing the string "aba", + * span() will yield contained/not-contained boundaries of { 0, 2, 3 } + * while spanBack() will yield boundaries of { 0, 1, 3 }. + * + * Note: If it is important to get the same boundaries whether iterating forward + * or backward through a string, then either only span() should be used and + * the boundaries cached for backward operation, or an ICU BreakIterator + * could be used. + * + * Note: Unpaired surrogates are treated like surrogate code points. + * Similarly, set strings match only on code point boundaries, + * never in the middle of a surrogate pair. + * Illegal UTF-8 sequences are treated like U+FFFD. + * When processing UTF-8 strings, malformed set strings + * (strings with unpaired surrogates which cannot be converted to UTF-8) + * are ignored. + * + * @stable ICU 4.0 + */ +typedef enum USetSpanCondition { + /** + * Continue a span() while there is no set element at the current position. + * Stops before the first set element (character or string). + * (For code points only, this is like while contains(current)==FALSE). + * + * When span() returns, the substring between where it started and the position + * it returned consists only of characters that are not in the set, + * and none of its strings overlap with the span. + * + * @stable ICU 4.0 + */ + USET_SPAN_NOT_CONTAINED = 0, + /** + * Continue a span() while there is a set element at the current position. + * (For characters only, this is like while contains(current)==TRUE). + * + * When span() returns, the substring between where it started and the position + * it returned consists only of set elements (characters or strings) that are in the set. + * + * If a set contains strings, then the span will be the longest substring + * matching any of the possible concatenations of set elements (characters or strings). + * (There must be a single, non-overlapping concatenation of characters or strings.) + * This is equivalent to a POSIX regular expression for (OR of each set element)*. + * + * @stable ICU 4.0 + */ + USET_SPAN_CONTAINED = 1, + /** + * Continue a span() while there is a set element at the current position. + * (For characters only, this is like while contains(current)==TRUE). + * + * When span() returns, the substring between where it started and the position + * it returned consists only of set elements (characters or strings) that are in the set. + * + * If a set only contains single characters, then this is the same + * as USET_SPAN_CONTAINED. + * + * If a set contains strings, then the span will be the longest substring + * with a match at each position with the longest single set element (character or string). + * + * Use this span condition together with other longest-match algorithms, + * such as ICU converters (ucnv_getUnicodeSet()). + * + * @stable ICU 4.0 + */ + USET_SPAN_SIMPLE = 2, + /** + * One more than the last span condition. + * @stable ICU 4.0 + */ + USET_SPAN_CONDITION_COUNT +} USetSpanCondition; + +#endif /* U_HIDE_DRAFT_API */ + +/** + * A serialized form of a Unicode set. Limited manipulations are + * possible directly on a serialized set. See below. + * @stable ICU 2.4 + */ +typedef struct USerializedSet { + /** + * The serialized Unicode Set. + * @stable ICU 2.4 + */ + const uint16_t *array; + /** + * The length of the array that contains BMP characters. + * @stable ICU 2.4 + */ + int32_t bmpLength; + /** + * The total length of the array. + * @stable ICU 2.4 + */ + int32_t length; + /** + * A small buffer for the array to reduce memory allocations. + * @stable ICU 2.4 + */ + uint16_t staticArray[USET_SERIALIZED_STATIC_ARRAY_CAPACITY]; +} USerializedSet; + +/********************************************************************* + * USet API + *********************************************************************/ + +/** + * Creates a USet object that contains the range of characters + * start..end, inclusive. If <code>start > end</code> + * then an empty set is created. + * @param start first character of the range, inclusive + * @param end last character of the range, inclusive + * @return a newly created USet. The caller must call uset_close() on + * it when done. + * @stable ICU 2.4 + */ +U_STABLE USet* U_EXPORT2 +uset_open(UChar32 start, UChar32 end); + +/** + * Creates a set from the given pattern. See the UnicodeSet class + * description for the syntax of the pattern language. + * @param pattern a string specifying what characters are in the set + * @param patternLength the length of the pattern, or -1 if null + * terminated + * @param ec the error code + * @stable ICU 2.4 + */ +U_STABLE USet* U_EXPORT2 +uset_openPattern(const UChar* pattern, int32_t patternLength, + UErrorCode* ec); + +/** + * Creates a set from the given pattern. See the UnicodeSet class + * description for the syntax of the pattern language. + * @param pattern a string specifying what characters are in the set + * @param patternLength the length of the pattern, or -1 if null + * terminated + * @param options bitmask for options to apply to the pattern. + * Valid options are USET_IGNORE_SPACE and USET_CASE_INSENSITIVE. + * @param ec the error code + * @stable ICU 2.4 + */ +U_STABLE USet* U_EXPORT2 +uset_openPatternOptions(const UChar* pattern, int32_t patternLength, + uint32_t options, + UErrorCode* ec); + +/** + * Disposes of the storage used by a USet object. This function should + * be called exactly once for objects returned by uset_open(). + * @param set the object to dispose of + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +uset_close(USet* set); + +/** + * Returns a copy of this object. + * If this set is frozen, then the clone will be frozen as well. + * Use uset_cloneAsThawed() for a mutable clone of a frozen set. + * @param set the original set + * @return the newly allocated copy of the set + * @see uset_cloneAsThawed + * @stable ICU 4.0 + */ +U_DRAFT USet * U_EXPORT2 +uset_clone(const USet *set); + +/** + * Determines whether the set has been frozen (made immutable) or not. + * See the ICU4J Freezable interface for details. + * @param set the set + * @return TRUE/FALSE for whether the set has been frozen + * @see uset_freeze + * @see uset_cloneAsThawed + * @stable ICU 4.0 + */ +U_DRAFT UBool U_EXPORT2 +uset_isFrozen(const USet *set); + +/** + * Freeze the set (make it immutable). + * Once frozen, it cannot be unfrozen and is therefore thread-safe + * until it is deleted. + * See the ICU4J Freezable interface for details. + * Freezing the set may also make some operations faster, for example + * uset_contains() and uset_span(). + * A frozen set will not be modified. (It remains frozen.) + * @param set the set + * @return the same set, now frozen + * @see uset_isFrozen + * @see uset_cloneAsThawed + * @stable ICU 4.0 + */ +U_DRAFT void U_EXPORT2 +uset_freeze(USet *set); + +/** + * Clone the set and make the clone mutable. + * See the ICU4J Freezable interface for details. + * @param set the set + * @return the mutable clone + * @see uset_freeze + * @see uset_isFrozen + * @see uset_clone + * @stable ICU 4.0 + */ +U_DRAFT USet * U_EXPORT2 +uset_cloneAsThawed(const USet *set); + +/** + * Causes the USet object to represent the range <code>start - end</code>. + * If <code>start > end</code> then this USet is set to an empty range. + * A frozen set will not be modified. + * @param set the object to set to the given range + * @param start first character in the set, inclusive + * @param end last character in the set, inclusive + * @stable ICU 3.2 + */ +U_STABLE void U_EXPORT2 +uset_set(USet* set, + UChar32 start, UChar32 end); + +/** + * Modifies the set to represent the set specified by the given + * pattern. See the UnicodeSet class description for the syntax of + * the pattern language. See also the User Guide chapter about UnicodeSet. + * <em>Empties the set passed before applying the pattern.</em> + * A frozen set will not be modified. + * @param set The set to which the pattern is to be applied. + * @param pattern A pointer to UChar string specifying what characters are in the set. + * The character at pattern[0] must be a '['. + * @param patternLength The length of the UChar string. -1 if NUL terminated. + * @param options A bitmask for options to apply to the pattern. + * Valid options are USET_IGNORE_SPACE and USET_CASE_INSENSITIVE. + * @param status Returns an error if the pattern cannot be parsed. + * @return Upon successful parse, the value is either + * the index of the character after the closing ']' + * of the parsed pattern. + * If the status code indicates failure, then the return value + * is the index of the error in the source. + * + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +uset_applyPattern(USet *set, + const UChar *pattern, int32_t patternLength, + uint32_t options, + UErrorCode *status); + +/** + * Modifies the set to contain those code points which have the given value + * for the given binary or enumerated property, as returned by + * u_getIntPropertyValue. Prior contents of this set are lost. + * A frozen set will not be modified. + * + * @param set the object to contain the code points defined by the property + * + * @param prop a property in the range UCHAR_BIN_START..UCHAR_BIN_LIMIT-1 + * or UCHAR_INT_START..UCHAR_INT_LIMIT-1 + * or UCHAR_MASK_START..UCHAR_MASK_LIMIT-1. + * + * @param value a value in the range u_getIntPropertyMinValue(prop).. + * u_getIntPropertyMaxValue(prop), with one exception. If prop is + * UCHAR_GENERAL_CATEGORY_MASK, then value should not be a UCharCategory, but + * rather a mask value produced by U_GET_GC_MASK(). This allows grouped + * categories such as [:L:] to be represented. + * + * @param ec error code input/output parameter + * + * @stable ICU 3.2 + */ +U_STABLE void U_EXPORT2 +uset_applyIntPropertyValue(USet* set, + UProperty prop, int32_t value, UErrorCode* ec); + +/** + * Modifies the set to contain those code points which have the + * given value for the given property. Prior contents of this + * set are lost. + * A frozen set will not be modified. + * + * @param set the object to contain the code points defined by the given + * property and value alias + * + * @param prop a string specifying a property alias, either short or long. + * The name is matched loosely. See PropertyAliases.txt for names and a + * description of loose matching. If the value string is empty, then this + * string is interpreted as either a General_Category value alias, a Script + * value alias, a binary property alias, or a special ID. Special IDs are + * matched loosely and correspond to the following sets: + * + * "ANY" = [\\u0000-\\U0010FFFF], + * "ASCII" = [\\u0000-\\u007F], + * "Assigned" = [:^Cn:]. + * + * @param propLength the length of the prop, or -1 if NULL + * + * @param value a string specifying a value alias, either short or long. + * The name is matched loosely. See PropertyValueAliases.txt for names + * and a description of loose matching. In addition to aliases listed, + * numeric values and canonical combining classes may be expressed + * numerically, e.g., ("nv", "0.5") or ("ccc", "220"). The value string + * may also be empty. + * + * @param valueLength the length of the value, or -1 if NULL + * + * @param ec error code input/output parameter + * + * @stable ICU 3.2 + */ +U_STABLE void U_EXPORT2 +uset_applyPropertyAlias(USet* set, + const UChar *prop, int32_t propLength, + const UChar *value, int32_t valueLength, + UErrorCode* ec); + +/** + * Return true if the given position, in the given pattern, appears + * to be the start of a UnicodeSet pattern. + * + * @param pattern a string specifying the pattern + * @param patternLength the length of the pattern, or -1 if NULL + * @param pos the given position + * @stable ICU 3.2 + */ +U_STABLE UBool U_EXPORT2 +uset_resemblesPattern(const UChar *pattern, int32_t patternLength, + int32_t pos); + +/** + * Returns a string representation of this set. If the result of + * calling this function is passed to a uset_openPattern(), it + * will produce another set that is equal to this one. + * @param set the set + * @param result the string to receive the rules, may be NULL + * @param resultCapacity the capacity of result, may be 0 if result is NULL + * @param escapeUnprintable if TRUE then convert unprintable + * character to their hex escape representations, \\uxxxx or + * \\Uxxxxxxxx. Unprintable characters are those other than + * U+000A, U+0020..U+007E. + * @param ec error code. + * @return length of string, possibly larger than resultCapacity + * @stable ICU 2.4 + */ +U_STABLE int32_t U_EXPORT2 +uset_toPattern(const USet* set, + UChar* result, int32_t resultCapacity, + UBool escapeUnprintable, + UErrorCode* ec); + +/** + * Adds the given character to the given USet. After this call, + * uset_contains(set, c) will return TRUE. + * A frozen set will not be modified. + * @param set the object to which to add the character + * @param c the character to add + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +uset_add(USet* set, UChar32 c); + +/** + * Adds all of the elements in the specified set to this set if + * they're not already present. This operation effectively + * modifies this set so that its value is the <i>union</i> of the two + * sets. The behavior of this operation is unspecified if the specified + * collection is modified while the operation is in progress. + * A frozen set will not be modified. + * + * @param set the object to which to add the set + * @param additionalSet the source set whose elements are to be added to this set. + * @stable ICU 2.6 + */ +U_STABLE void U_EXPORT2 +uset_addAll(USet* set, const USet *additionalSet); + +/** + * Adds the given range of characters to the given USet. After this call, + * uset_contains(set, start, end) will return TRUE. + * A frozen set will not be modified. + * @param set the object to which to add the character + * @param start the first character of the range to add, inclusive + * @param end the last character of the range to add, inclusive + * @stable ICU 2.2 + */ +U_STABLE void U_EXPORT2 +uset_addRange(USet* set, UChar32 start, UChar32 end); + +/** + * Adds the given string to the given USet. After this call, + * uset_containsString(set, str, strLen) will return TRUE. + * A frozen set will not be modified. + * @param set the object to which to add the character + * @param str the string to add + * @param strLen the length of the string or -1 if null terminated. + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +uset_addString(USet* set, const UChar* str, int32_t strLen); + +/** + * Adds each of the characters in this string to the set. Thus "ch" => {"c", "h"} + * If this set already any particular character, it has no effect on that character. + * A frozen set will not be modified. + * @param set the object to which to add the character + * @param str the source string + * @param strLen the length of the string or -1 if null terminated. + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +uset_addAllCodePoints(USet* set, const UChar *str, int32_t strLen); + +/** + * Removes the given character from the given USet. After this call, + * uset_contains(set, c) will return FALSE. + * A frozen set will not be modified. + * @param set the object from which to remove the character + * @param c the character to remove + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +uset_remove(USet* set, UChar32 c); + +/** + * Removes the given range of characters from the given USet. After this call, + * uset_contains(set, start, end) will return FALSE. + * A frozen set will not be modified. + * @param set the object to which to add the character + * @param start the first character of the range to remove, inclusive + * @param end the last character of the range to remove, inclusive + * @stable ICU 2.2 + */ +U_STABLE void U_EXPORT2 +uset_removeRange(USet* set, UChar32 start, UChar32 end); + +/** + * Removes the given string to the given USet. After this call, + * uset_containsString(set, str, strLen) will return FALSE. + * A frozen set will not be modified. + * @param set the object to which to add the character + * @param str the string to remove + * @param strLen the length of the string or -1 if null terminated. + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +uset_removeString(USet* set, const UChar* str, int32_t strLen); + +/** + * Removes from this set all of its elements that are contained in the + * specified set. This operation effectively modifies this + * set so that its value is the <i>asymmetric set difference</i> of + * the two sets. + * A frozen set will not be modified. + * @param set the object from which the elements are to be removed + * @param removeSet the object that defines which elements will be + * removed from this set + * @stable ICU 3.2 + */ +U_STABLE void U_EXPORT2 +uset_removeAll(USet* set, const USet* removeSet); + +/** + * Retain only the elements in this set that are contained in the + * specified range. If <code>start > end</code> then an empty range is + * retained, leaving the set empty. This is equivalent to + * a boolean logic AND, or a set INTERSECTION. + * A frozen set will not be modified. + * + * @param set the object for which to retain only the specified range + * @param start first character, inclusive, of range to be retained + * to this set. + * @param end last character, inclusive, of range to be retained + * to this set. + * @stable ICU 3.2 + */ +U_STABLE void U_EXPORT2 +uset_retain(USet* set, UChar32 start, UChar32 end); + +/** + * Retains only the elements in this set that are contained in the + * specified set. In other words, removes from this set all of + * its elements that are not contained in the specified set. This + * operation effectively modifies this set so that its value is + * the <i>intersection</i> of the two sets. + * A frozen set will not be modified. + * + * @param set the object on which to perform the retain + * @param retain set that defines which elements this set will retain + * @stable ICU 3.2 + */ +U_STABLE void U_EXPORT2 +uset_retainAll(USet* set, const USet* retain); + +/** + * Reallocate this objects internal structures to take up the least + * possible space, without changing this object's value. + * A frozen set will not be modified. + * + * @param set the object on which to perfrom the compact + * @stable ICU 3.2 + */ +U_STABLE void U_EXPORT2 +uset_compact(USet* set); + +/** + * Inverts this set. This operation modifies this set so that + * its value is its complement. This operation does not affect + * the multicharacter strings, if any. + * A frozen set will not be modified. + * @param set the set + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +uset_complement(USet* set); + +/** + * Complements in this set all elements contained in the specified + * set. Any character in the other set will be removed if it is + * in this set, or will be added if it is not in this set. + * A frozen set will not be modified. + * + * @param set the set with which to complement + * @param complement set that defines which elements will be xor'ed + * from this set. + * @stable ICU 3.2 + */ +U_STABLE void U_EXPORT2 +uset_complementAll(USet* set, const USet* complement); + +/** + * Removes all of the elements from this set. This set will be + * empty after this call returns. + * A frozen set will not be modified. + * @param set the set + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +uset_clear(USet* set); + +/** + * Returns TRUE if the given USet contains no characters and no + * strings. + * @param set the set + * @return true if set is empty + * @stable ICU 2.4 + */ +U_STABLE UBool U_EXPORT2 +uset_isEmpty(const USet* set); + +/** + * Returns TRUE if the given USet contains the given character. + * This function works faster with a frozen set. + * @param set the set + * @param c The codepoint to check for within the set + * @return true if set contains c + * @stable ICU 2.4 + */ +U_STABLE UBool U_EXPORT2 +uset_contains(const USet* set, UChar32 c); + +/** + * Returns TRUE if the given USet contains all characters c + * where start <= c && c <= end. + * @param set the set + * @param start the first character of the range to test, inclusive + * @param end the last character of the range to test, inclusive + * @return TRUE if set contains the range + * @stable ICU 2.2 + */ +U_STABLE UBool U_EXPORT2 +uset_containsRange(const USet* set, UChar32 start, UChar32 end); + +/** + * Returns TRUE if the given USet contains the given string. + * @param set the set + * @param str the string + * @param strLen the length of the string or -1 if null terminated. + * @return true if set contains str + * @stable ICU 2.4 + */ +U_STABLE UBool U_EXPORT2 +uset_containsString(const USet* set, const UChar* str, int32_t strLen); + +/** + * Returns the index of the given character within this set, where + * the set is ordered by ascending code point. If the character + * is not in this set, return -1. The inverse of this method is + * <code>charAt()</code>. + * @param set the set + * @param c the character to obtain the index for + * @return an index from 0..size()-1, or -1 + * @stable ICU 3.2 + */ +U_STABLE int32_t U_EXPORT2 +uset_indexOf(const USet* set, UChar32 c); + +/** + * Returns the character at the given index within this set, where + * the set is ordered by ascending code point. If the index is + * out of range, return (UChar32)-1. The inverse of this method is + * <code>indexOf()</code>. + * @param set the set + * @param index an index from 0..size()-1 to obtain the char for + * @return the character at the given index, or (UChar32)-1. + * @stable ICU 3.2 + */ +U_STABLE UChar32 U_EXPORT2 +uset_charAt(const USet* set, int32_t index); + +/** + * Returns the number of characters and strings contained in the given + * USet. + * @param set the set + * @return a non-negative integer counting the characters and strings + * contained in set + * @stable ICU 2.4 + */ +U_STABLE int32_t U_EXPORT2 +uset_size(const USet* set); + +/** + * Returns the number of items in this set. An item is either a range + * of characters or a single multicharacter string. + * @param set the set + * @return a non-negative integer counting the character ranges + * and/or strings contained in set + * @stable ICU 2.4 + */ +U_STABLE int32_t U_EXPORT2 +uset_getItemCount(const USet* set); + +/** + * Returns an item of this set. An item is either a range of + * characters or a single multicharacter string. + * @param set the set + * @param itemIndex a non-negative integer in the range 0.. + * uset_getItemCount(set)-1 + * @param start pointer to variable to receive first character + * in range, inclusive + * @param end pointer to variable to receive last character in range, + * inclusive + * @param str buffer to receive the string, may be NULL + * @param strCapacity capacity of str, or 0 if str is NULL + * @param ec error code + * @return the length of the string (>= 2), or 0 if the item is a + * range, in which case it is the range *start..*end, or -1 if + * itemIndex is out of range + * @stable ICU 2.4 + */ +U_STABLE int32_t U_EXPORT2 +uset_getItem(const USet* set, int32_t itemIndex, + UChar32* start, UChar32* end, + UChar* str, int32_t strCapacity, + UErrorCode* ec); + +/** + * Returns true if set1 contains all the characters and strings + * of set2. It answers the question, 'Is set1 a superset of set2?' + * @param set1 set to be checked for containment + * @param set2 set to be checked for containment + * @return true if the test condition is met + * @stable ICU 3.2 + */ +U_STABLE UBool U_EXPORT2 +uset_containsAll(const USet* set1, const USet* set2); + +/** + * Returns true if this set contains all the characters + * of the given string. This is does not check containment of grapheme + * clusters, like uset_containsString. + * @param set set of characters to be checked for containment + * @param str string containing codepoints to be checked for containment + * @param strLen the length of the string or -1 if null terminated. + * @return true if the test condition is met + * @stable ICU 3.4 + */ +U_STABLE UBool U_EXPORT2 +uset_containsAllCodePoints(const USet* set, const UChar *str, int32_t strLen); + +/** + * Returns true if set1 contains none of the characters and strings + * of set2. It answers the question, 'Is set1 a disjoint set of set2?' + * @param set1 set to be checked for containment + * @param set2 set to be checked for containment + * @return true if the test condition is met + * @stable ICU 3.2 + */ +U_STABLE UBool U_EXPORT2 +uset_containsNone(const USet* set1, const USet* set2); + +/** + * Returns true if set1 contains some of the characters and strings + * of set2. It answers the question, 'Does set1 and set2 have an intersection?' + * @param set1 set to be checked for containment + * @param set2 set to be checked for containment + * @return true if the test condition is met + * @stable ICU 3.2 + */ +U_STABLE UBool U_EXPORT2 +uset_containsSome(const USet* set1, const USet* set2); + +/** + * Returns the length of the initial substring of the input string which + * consists only of characters and strings that are contained in this set + * (USET_SPAN_CONTAINED, USET_SPAN_SIMPLE), + * or only of characters and strings that are not contained + * in this set (USET_SPAN_NOT_CONTAINED). + * See USetSpanCondition for details. + * Similar to the strspn() C library function. + * Unpaired surrogates are treated according to contains() of their surrogate code points. + * This function works faster with a frozen set and with a non-negative string length argument. + * @param set the set + * @param s start of the string + * @param length of the string; can be -1 for NUL-terminated + * @param spanCondition specifies the containment condition + * @return the length of the initial substring according to the spanCondition; + * 0 if the start of the string does not fit the spanCondition + * @stable ICU 4.0 + * @see USetSpanCondition + */ +U_DRAFT int32_t U_EXPORT2 +uset_span(const USet *set, const UChar *s, int32_t length, USetSpanCondition spanCondition); + +/** + * Returns the start of the trailing substring of the input string which + * consists only of characters and strings that are contained in this set + * (USET_SPAN_CONTAINED, USET_SPAN_SIMPLE), + * or only of characters and strings that are not contained + * in this set (USET_SPAN_NOT_CONTAINED). + * See USetSpanCondition for details. + * Unpaired surrogates are treated according to contains() of their surrogate code points. + * This function works faster with a frozen set and with a non-negative string length argument. + * @param set the set + * @param s start of the string + * @param length of the string; can be -1 for NUL-terminated + * @param spanCondition specifies the containment condition + * @return the start of the trailing substring according to the spanCondition; + * the string length if the end of the string does not fit the spanCondition + * @stable ICU 4.0 + * @see USetSpanCondition + */ +U_DRAFT int32_t U_EXPORT2 +uset_spanBack(const USet *set, const UChar *s, int32_t length, USetSpanCondition spanCondition); + +/** + * Returns the length of the initial substring of the input string which + * consists only of characters and strings that are contained in this set + * (USET_SPAN_CONTAINED, USET_SPAN_SIMPLE), + * or only of characters and strings that are not contained + * in this set (USET_SPAN_NOT_CONTAINED). + * See USetSpanCondition for details. + * Similar to the strspn() C library function. + * Malformed byte sequences are treated according to contains(0xfffd). + * This function works faster with a frozen set and with a non-negative string length argument. + * @param set the set + * @param s start of the string (UTF-8) + * @param length of the string; can be -1 for NUL-terminated + * @param spanCondition specifies the containment condition + * @return the length of the initial substring according to the spanCondition; + * 0 if the start of the string does not fit the spanCondition + * @stable ICU 4.0 + * @see USetSpanCondition + */ +U_DRAFT int32_t U_EXPORT2 +uset_spanUTF8(const USet *set, const char *s, int32_t length, USetSpanCondition spanCondition); + +/** + * Returns the start of the trailing substring of the input string which + * consists only of characters and strings that are contained in this set + * (USET_SPAN_CONTAINED, USET_SPAN_SIMPLE), + * or only of characters and strings that are not contained + * in this set (USET_SPAN_NOT_CONTAINED). + * See USetSpanCondition for details. + * Malformed byte sequences are treated according to contains(0xfffd). + * This function works faster with a frozen set and with a non-negative string length argument. + * @param set the set + * @param s start of the string (UTF-8) + * @param length of the string; can be -1 for NUL-terminated + * @param spanCondition specifies the containment condition + * @return the start of the trailing substring according to the spanCondition; + * the string length if the end of the string does not fit the spanCondition + * @stable ICU 4.0 + * @see USetSpanCondition + */ +U_DRAFT int32_t U_EXPORT2 +uset_spanBackUTF8(const USet *set, const char *s, int32_t length, USetSpanCondition spanCondition); + +/** + * Returns true if set1 contains all of the characters and strings + * of set2, and vis versa. It answers the question, 'Is set1 equal to set2?' + * @param set1 set to be checked for containment + * @param set2 set to be checked for containment + * @return true if the test condition is met + * @stable ICU 3.2 + */ +U_STABLE UBool U_EXPORT2 +uset_equals(const USet* set1, const USet* set2); + +/********************************************************************* + * Serialized set API + *********************************************************************/ + +/** + * Serializes this set into an array of 16-bit integers. Serialization + * (currently) only records the characters in the set; multicharacter + * strings are ignored. + * + * The array + * has following format (each line is one 16-bit integer): + * + * length = (n+2*m) | (m!=0?0x8000:0) + * bmpLength = n; present if m!=0 + * bmp[0] + * bmp[1] + * ... + * bmp[n-1] + * supp-high[0] + * supp-low[0] + * supp-high[1] + * supp-low[1] + * ... + * supp-high[m-1] + * supp-low[m-1] + * + * The array starts with a header. After the header are n bmp + * code points, then m supplementary code points. Either n or m + * or both may be zero. n+2*m is always <= 0x7FFF. + * + * If there are no supplementary characters (if m==0) then the + * header is one 16-bit integer, 'length', with value n. + * + * If there are supplementary characters (if m!=0) then the header + * is two 16-bit integers. The first, 'length', has value + * (n+2*m)|0x8000. The second, 'bmpLength', has value n. + * + * After the header the code points are stored in ascending order. + * Supplementary code points are stored as most significant 16 + * bits followed by least significant 16 bits. + * + * @param set the set + * @param dest pointer to buffer of destCapacity 16-bit integers. + * May be NULL only if destCapacity is zero. + * @param destCapacity size of dest, or zero. Must not be negative. + * @param pErrorCode pointer to the error code. Will be set to + * U_INDEX_OUTOFBOUNDS_ERROR if n+2*m > 0x7FFF. Will be set to + * U_BUFFER_OVERFLOW_ERROR if n+2*m+(m!=0?2:1) > destCapacity. + * @return the total length of the serialized format, including + * the header, that is, n+2*m+(m!=0?2:1), or 0 on error other + * than U_BUFFER_OVERFLOW_ERROR. + * @stable ICU 2.4 + */ +U_STABLE int32_t U_EXPORT2 +uset_serialize(const USet* set, uint16_t* dest, int32_t destCapacity, UErrorCode* pErrorCode); + +/** + * Given a serialized array, fill in the given serialized set object. + * @param fillSet pointer to result + * @param src pointer to start of array + * @param srcLength length of array + * @return true if the given array is valid, otherwise false + * @stable ICU 2.4 + */ +U_STABLE UBool U_EXPORT2 +uset_getSerializedSet(USerializedSet* fillSet, const uint16_t* src, int32_t srcLength); + +/** + * Set the USerializedSet to contain the given character (and nothing + * else). + * @param fillSet pointer to result + * @param c The codepoint to set + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +uset_setSerializedToOne(USerializedSet* fillSet, UChar32 c); + +/** + * Returns TRUE if the given USerializedSet contains the given + * character. + * @param set the serialized set + * @param c The codepoint to check for within the set + * @return true if set contains c + * @stable ICU 2.4 + */ +U_STABLE UBool U_EXPORT2 +uset_serializedContains(const USerializedSet* set, UChar32 c); + +/** + * Returns the number of disjoint ranges of characters contained in + * the given serialized set. Ignores any strings contained in the + * set. + * @param set the serialized set + * @return a non-negative integer counting the character ranges + * contained in set + * @stable ICU 2.4 + */ +U_STABLE int32_t U_EXPORT2 +uset_getSerializedRangeCount(const USerializedSet* set); + +/** + * Returns a range of characters contained in the given serialized + * set. + * @param set the serialized set + * @param rangeIndex a non-negative integer in the range 0.. + * uset_getSerializedRangeCount(set)-1 + * @param pStart pointer to variable to receive first character + * in range, inclusive + * @param pEnd pointer to variable to receive last character in range, + * inclusive + * @return true if rangeIndex is valid, otherwise false + * @stable ICU 2.4 + */ +U_STABLE UBool U_EXPORT2 +uset_getSerializedRange(const USerializedSet* set, int32_t rangeIndex, + UChar32* pStart, UChar32* pEnd); + +#endif diff --git a/utils/openttd/unicode/usetiter.h b/utils/openttd/unicode/usetiter.h new file mode 100644 index 00000000000..defa75cd7ed --- /dev/null +++ b/utils/openttd/unicode/usetiter.h @@ -0,0 +1,318 @@ +/* +********************************************************************** +* Copyright (c) 2002-2006, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +*/ +#ifndef USETITER_H +#define USETITER_H + +#include "unicode/utypes.h" +#include "unicode/uobject.h" +#include "unicode/unistr.h" + +/** + * \file + * \brief C++ API: UnicodeSetIterator iterates over the contents of a UnicodeSet. + */ + +U_NAMESPACE_BEGIN + +class UnicodeSet; +class UnicodeString; + +/** + * + * UnicodeSetIterator iterates over the contents of a UnicodeSet. It + * iterates over either code points or code point ranges. After all + * code points or ranges have been returned, it returns the + * multicharacter strings of the UnicodSet, if any. + * + * This class is not intended to be subclassed. Consider any fields + * or methods declared as "protected" to be private. The use of + * protected in this class is an artifact of history. + * + * <p>To iterate over code points and strings, use a loop like this: + * <pre> + * UnicodeSetIterator it(set); + * while (set.next()) { + * processItem(set.getString()); + * } + * </pre> + * <p>Each item in the set is accessed as a string. Set elements + * consisting of single code points are returned as strings containing + * just the one code point. + * + * <p>To iterate over code point ranges, instead of individual code points, + * use a loop like this: + * <pre> + * UnicodeSetIterator it(set); + * while (it.nextRange()) { + * if (it.isString()) { + * processString(it.getString()); + * } else { + * processCodepointRange(it.getCodepoint(), it.getCodepointEnd()); + * } + * } + * </pre> + * @author M. Davis + * @stable ICU 2.4 + */ +class U_COMMON_API UnicodeSetIterator : public UObject { + + protected: + + /** + * Value of <tt>codepoint</tt> if the iterator points to a string. + * If <tt>codepoint == IS_STRING</tt>, then examine + * <tt>string</tt> for the current iteration result. + * @stable ICU 2.4 + */ + enum { IS_STRING = -1 }; + + /** + * Current code point, or the special value <tt>IS_STRING</tt>, if + * the iterator points to a string. + * @stable ICU 2.4 + */ + UChar32 codepoint; + + /** + * When iterating over ranges using <tt>nextRange()</tt>, + * <tt>codepointEnd</tt> contains the inclusive end of the + * iteration range, if <tt>codepoint != IS_STRING</tt>. If + * iterating over code points using <tt>next()</tt>, or if + * <tt>codepoint == IS_STRING</tt>, then the value of + * <tt>codepointEnd</tt> is undefined. + * @stable ICU 2.4 + */ + UChar32 codepointEnd; + + /** + * If <tt>codepoint == IS_STRING</tt>, then <tt>string</tt> points + * to the current string. If <tt>codepoint != IS_STRING</tt>, the + * value of <tt>string</tt> is undefined. + * @stable ICU 2.4 + */ + const UnicodeString* string; + + public: + + /** + * Create an iterator over the given set. The iterator is valid + * only so long as <tt>set</tt> is valid. + * @param set set to iterate over + * @stable ICU 2.4 + */ + UnicodeSetIterator(const UnicodeSet& set); + + /** + * Create an iterator over nothing. <tt>next()</tt> and + * <tt>nextRange()</tt> return false. This is a convenience + * constructor allowing the target to be set later. + * @stable ICU 2.4 + */ + UnicodeSetIterator(); + + /** + * Destructor. + * @stable ICU 2.4 + */ + virtual ~UnicodeSetIterator(); + + /** + * Returns true if the current element is a string. If so, the + * caller can retrieve it with <tt>getString()</tt>. If this + * method returns false, the current element is a code point or + * code point range, depending on whether <tt>next()</tt> or + * <tt>nextRange()</tt> was called. + * Elements of types string and codepoint can both be retrieved + * with the function <tt>getString()</tt>. + * Elements of type codepoint can also be retrieved with + * <tt>getCodepoint()</tt>. + * For ranges, <tt>getCodepoint()</tt> returns the starting codepoint + * of the range, and <tt>getCodepointEnd()</tt> returns the end + * of the range. + * @stable ICU 2.4 + */ + inline UBool isString() const; + + /** + * Returns the current code point, if <tt>isString()</tt> returned + * false. Otherwise returns an undefined result. + * @stable ICU 2.4 + */ + inline UChar32 getCodepoint() const; + + /** + * Returns the end of the current code point range, if + * <tt>isString()</tt> returned false and <tt>nextRange()</tt> was + * called. Otherwise returns an undefined result. + * @stable ICU 2.4 + */ + inline UChar32 getCodepointEnd() const; + + /** + * Returns the current string, if <tt>isString()</tt> returned + * true. If the current iteration item is a code point, a UnicodeString + * containing that single code point is returned. + * + * Ownership of the returned string remains with the iterator. + * The string is guaranteed to remain valid only until the iterator is + * advanced to the next item, or until the iterator is deleted. + * + * @stable ICU 2.4 + */ + const UnicodeString& getString(); + + /** + * Advances the iteration position to the next element in the set, + * which can be either a single code point or a string. + * If there are no more elements in the set, return false. + * + * <p> + * If <tt>isString() == TRUE</tt>, the value is a + * string, otherwise the value is a + * single code point. Elements of either type can be retrieved + * with the function <tt>getString()</tt>, while elements of + * consisting of a single code point can be retrieved with + * <tt>getCodepoint()</tt> + * + * <p>The order of iteration is all code points in sorted order, + * followed by all strings sorted order. Do not mix + * calls to <tt>next()</tt> and <tt>nextRange()</tt> without + * calling <tt>reset()</tt> between them. The results of doing so + * are undefined. + * + * @return true if there was another element in the set. + * @stable ICU 2.4 + */ + UBool next(); + + /** + * Returns the next element in the set, either a code point range + * or a string. If there are no more elements in the set, return + * false. If <tt>isString() == TRUE</tt>, the value is a + * string and can be accessed with <tt>getString()</tt>. Otherwise the value is a + * range of one or more code points from <tt>getCodepoint()</tt> to + * <tt>getCodepointeEnd()</tt> inclusive. + * + * <p>The order of iteration is all code points ranges in sorted + * order, followed by all strings sorted order. Ranges are + * disjoint and non-contiguous. The value returned from <tt>getString()</tt> + * is undefined unless <tt>isString() == TRUE</tt>. Do not mix calls to + * <tt>next()</tt> and <tt>nextRange()</tt> without calling + * <tt>reset()</tt> between them. The results of doing so are + * undefined. + * + * @return true if there was another element in the set. + * @stable ICU 2.4 + */ + UBool nextRange(); + + /** + * Sets this iterator to visit the elements of the given set and + * resets it to the start of that set. The iterator is valid only + * so long as <tt>set</tt> is valid. + * @param set the set to iterate over. + * @stable ICU 2.4 + */ + void reset(const UnicodeSet& set); + + /** + * Resets this iterator to the start of the set. + * @stable ICU 2.4 + */ + void reset(); + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @stable ICU 2.4 + */ + static UClassID U_EXPORT2 getStaticClassID(); + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @stable ICU 2.4 + */ + virtual UClassID getDynamicClassID() const; + + // ======================= PRIVATES =========================== + + protected: + + // endElement and nextElements are really UChar32's, but we keep + // them as signed int32_t's so we can do comparisons with + // endElement set to -1. Leave them as int32_t's. + /** The set + * @stable ICU 2.4 + */ + const UnicodeSet* set; + /** End range + * @stable ICU 2.4 + */ + int32_t endRange; + /** Range + * @stable ICU 2.4 + */ + int32_t range; + /** End element + * @stable ICU 2.4 + */ + int32_t endElement; + /** Next element + * @stable ICU 2.4 + */ + int32_t nextElement; + //UBool abbreviated; + /** Next string + * @stable ICU 2.4 + */ + int32_t nextString; + /** String count + * @stable ICU 2.4 + */ + int32_t stringCount; + + /** + * Points to the string to use when the caller asks for a + * string and the current iteration item is a code point, not a string. + * @internal + */ + UnicodeString *cpString; + + /** Copy constructor. Disallowed. + * @stable ICU 2.4 + */ + UnicodeSetIterator(const UnicodeSetIterator&); // disallow + + /** Assignment operator. Disallowed. + * @stable ICU 2.4 + */ + UnicodeSetIterator& operator=(const UnicodeSetIterator&); // disallow + + /** Load range + * @stable ICU 2.4 + */ + virtual void loadRange(int32_t range); + +}; + +inline UBool UnicodeSetIterator::isString() const { + return codepoint == (UChar32)IS_STRING; +} + +inline UChar32 UnicodeSetIterator::getCodepoint() const { + return codepoint; +} + +inline UChar32 UnicodeSetIterator::getCodepointEnd() const { + return codepointEnd; +} + + +U_NAMESPACE_END + +#endif diff --git a/utils/openttd/unicode/ushape.h b/utils/openttd/unicode/ushape.h new file mode 100644 index 00000000000..f165e140310 --- /dev/null +++ b/utils/openttd/unicode/ushape.h @@ -0,0 +1,263 @@ +/* +****************************************************************************** +* +* Copyright (C) 2000-2007, International Business Machines +* Corporation and others. All Rights Reserved. +* +****************************************************************************** +* file name: ushape.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2000jun29 +* created by: Markus W. Scherer +*/ + +#ifndef __USHAPE_H__ +#define __USHAPE_H__ + +#include "unicode/utypes.h" + +/** + * \file + * \brief C API: Arabic shaping + * + */ + +/** + * Shape Arabic text on a character basis. + * + * <p>This function performs basic operations for "shaping" Arabic text. It is most + * useful for use with legacy data formats and legacy display technology + * (simple terminals). All operations are performed on Unicode characters.</p> + * + * <p>Text-based shaping means that some character code points in the text are + * replaced by others depending on the context. It transforms one kind of text + * into another. In comparison, modern displays for Arabic text select + * appropriate, context-dependent font glyphs for each text element, which means + * that they transform text into a glyph vector.</p> + * + * <p>Text transformations are necessary when modern display technology is not + * available or when text needs to be transformed to or from legacy formats that + * use "shaped" characters. Since the Arabic script is cursive, connecting + * adjacent letters to each other, computers select images for each letter based + * on the surrounding letters. This usually results in four images per Arabic + * letter: initial, middle, final, and isolated forms. In Unicode, on the other + * hand, letters are normally stored abstract, and a display system is expected + * to select the necessary glyphs. (This makes searching and other text + * processing easier because the same letter has only one code.) It is possible + * to mimic this with text transformations because there are characters in + * Unicode that are rendered as letters with a specific shape + * (or cursive connectivity). They were included for interoperability with + * legacy systems and codepages, and for unsophisticated display systems.</p> + * + * <p>A second kind of text transformations is supported for Arabic digits: + * For compatibility with legacy codepages that only include European digits, + * it is possible to replace one set of digits by another, changing the + * character code points. These operations can be performed for either + * Arabic-Indic Digits (U+0660...U+0669) or Eastern (Extended) Arabic-Indic + * digits (U+06f0...U+06f9).</p> + * + * <p>Some replacements may result in more or fewer characters (code points). + * By default, this means that the destination buffer may receive text with a + * length different from the source length. Some legacy systems rely on the + * length of the text to be constant. They expect extra spaces to be added + * or consumed either next to the affected character or at the end of the + * text.</p> + * + * <p>For details about the available operations, see the description of the + * <code>U_SHAPE_...</code> options.</p> + * + * @param source The input text. + * + * @param sourceLength The number of UChars in <code>source</code>. + * + * @param dest The destination buffer that will receive the results of the + * requested operations. It may be <code>NULL</code> only if + * <code>destSize</code> is 0. The source and destination must not + * overlap. + * + * @param destSize The size (capacity) of the destination buffer in UChars. + * If <code>destSize</code> is 0, then no output is produced, + * but the necessary buffer size is returned ("preflighting"). + * + * @param options This is a 32-bit set of flags that specify the operations + * that are performed on the input text. If no error occurs, + * then the result will always be written to the destination + * buffer. + * + * @param pErrorCode must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * + * @return The number of UChars written to the destination buffer. + * If an error occured, then no output was written, or it may be + * incomplete. If <code>U_BUFFER_OVERFLOW_ERROR</code> is set, then + * the return value indicates the necessary destination buffer size. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_shapeArabic(const UChar *source, int32_t sourceLength, + UChar *dest, int32_t destSize, + uint32_t options, + UErrorCode *pErrorCode); + +/** + * Memory option: allow the result to have a different length than the source. + * @stable ICU 2.0 + */ +#define U_SHAPE_LENGTH_GROW_SHRINK 0 + +/** + * Memory option: the result must have the same length as the source. + * If more room is necessary, then try to consume spaces next to modified characters. + * @stable ICU 2.0 + */ +#define U_SHAPE_LENGTH_FIXED_SPACES_NEAR 1 + +/** + * Memory option: the result must have the same length as the source. + * If more room is necessary, then try to consume spaces at the end of the text. + * @stable ICU 2.0 + */ +#define U_SHAPE_LENGTH_FIXED_SPACES_AT_END 2 + +/** + * Memory option: the result must have the same length as the source. + * If more room is necessary, then try to consume spaces at the beginning of the text. + * @stable ICU 2.0 + */ +#define U_SHAPE_LENGTH_FIXED_SPACES_AT_BEGINNING 3 + +/** Bit mask for memory options. @stable ICU 2.0 */ +#define U_SHAPE_LENGTH_MASK 3 + + +/** Direction indicator: the source is in logical (keyboard) order. @stable ICU 2.0 */ +#define U_SHAPE_TEXT_DIRECTION_LOGICAL 0 + +/** + * Direction indicator: + * the source is in visual LTR order, + * the leftmost displayed character stored first. + * @stable ICU 2.0 + */ +#define U_SHAPE_TEXT_DIRECTION_VISUAL_LTR 4 + +/** Bit mask for direction indicators. @stable ICU 2.0 */ +#define U_SHAPE_TEXT_DIRECTION_MASK 4 + + +/** Letter shaping option: do not perform letter shaping. @stable ICU 2.0 */ +#define U_SHAPE_LETTERS_NOOP 0 + +/** Letter shaping option: replace abstract letter characters by "shaped" ones. @stable ICU 2.0 */ +#define U_SHAPE_LETTERS_SHAPE 8 + +/** Letter shaping option: replace "shaped" letter characters by abstract ones. @stable ICU 2.0 */ +#define U_SHAPE_LETTERS_UNSHAPE 0x10 + +/** + * Letter shaping option: replace abstract letter characters by "shaped" ones. + * The only difference with U_SHAPE_LETTERS_SHAPE is that Tashkeel letters + * are always "shaped" into the isolated form instead of the medial form + * (selecting code points from the Arabic Presentation Forms-B block). + * @stable ICU 2.0 + */ +#define U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED 0x18 + +/** Bit mask for letter shaping options. @stable ICU 2.0 */ +#define U_SHAPE_LETTERS_MASK 0x18 + + +/** Digit shaping option: do not perform digit shaping. @stable ICU 2.0 */ +#define U_SHAPE_DIGITS_NOOP 0 + +/** + * Digit shaping option: + * Replace European digits (U+0030...) by Arabic-Indic digits. + * @stable ICU 2.0 + */ +#define U_SHAPE_DIGITS_EN2AN 0x20 + +/** + * Digit shaping option: + * Replace Arabic-Indic digits by European digits (U+0030...). + * @stable ICU 2.0 + */ +#define U_SHAPE_DIGITS_AN2EN 0x40 + +/** + * Digit shaping option: + * Replace European digits (U+0030...) by Arabic-Indic digits if the most recent + * strongly directional character is an Arabic letter + * (<code>u_charDirection()</code> result <code>U_RIGHT_TO_LEFT_ARABIC</code> [AL]).<br> + * The direction of "preceding" depends on the direction indicator option. + * For the first characters, the preceding strongly directional character + * (initial state) is assumed to be not an Arabic letter + * (it is <code>U_LEFT_TO_RIGHT</code> [L] or <code>U_RIGHT_TO_LEFT</code> [R]). + * @stable ICU 2.0 + */ +#define U_SHAPE_DIGITS_ALEN2AN_INIT_LR 0x60 + +/** + * Digit shaping option: + * Replace European digits (U+0030...) by Arabic-Indic digits if the most recent + * strongly directional character is an Arabic letter + * (<code>u_charDirection()</code> result <code>U_RIGHT_TO_LEFT_ARABIC</code> [AL]).<br> + * The direction of "preceding" depends on the direction indicator option. + * For the first characters, the preceding strongly directional character + * (initial state) is assumed to be an Arabic letter. + * @stable ICU 2.0 + */ +#define U_SHAPE_DIGITS_ALEN2AN_INIT_AL 0x80 + +/** Not a valid option value. May be replaced by a new option. @stable ICU 2.0 */ +#define U_SHAPE_DIGITS_RESERVED 0xa0 + +/** Bit mask for digit shaping options. @stable ICU 2.0 */ +#define U_SHAPE_DIGITS_MASK 0xe0 + + +/** Digit type option: Use Arabic-Indic digits (U+0660...U+0669). @stable ICU 2.0 */ +#define U_SHAPE_DIGIT_TYPE_AN 0 + +/** Digit type option: Use Eastern (Extended) Arabic-Indic digits (U+06f0...U+06f9). @stable ICU 2.0 */ +#define U_SHAPE_DIGIT_TYPE_AN_EXTENDED 0x100 + +/** Not a valid option value. May be replaced by a new option. @stable ICU 2.0 */ +#define U_SHAPE_DIGIT_TYPE_RESERVED 0x200 + +/** Bit mask for digit type options. @stable ICU 2.0 */ +#define U_SHAPE_DIGIT_TYPE_MASK 0x3f00 + +/** + * Tashkeel aggregation option: + * Replaces any combination of U+0651 with one of + * U+064C, U+064D, U+064E, U+064F, U+0650 with + * U+FC5E, U+FC5F, U+FC60, U+FC61, U+FC62 consecutively. + * @stable ICU 3.6 + */ +#define U_SHAPE_AGGREGATE_TASHKEEL 0x4000 +/** Tashkeel aggregation option: do not aggregate tashkeels. @stable ICU 3.6 */ +#define U_SHAPE_AGGREGATE_TASHKEEL_NOOP 0 +/** Bit mask for tashkeel aggregation. @stable ICU 3.6 */ +#define U_SHAPE_AGGREGATE_TASHKEEL_MASK 0x4000 + +/** + * Presentation form option: + * Don't replace Arabic Presentation Forms-A and Arabic Presentation Forms-B + * characters with 0+06xx characters, before shaping. + * @stable ICU 3.6 + */ +#define U_SHAPE_PRESERVE_PRESENTATION 0x8000 +/** Presentation form option: + * Replace Arabic Presentation Forms-A and Arabic Presentationo Forms-B with + * their unshaped correspondants in range 0+06xx, before shaping. + * @stable ICU 3.6 + */ +#define U_SHAPE_PRESERVE_PRESENTATION_NOOP 0 +/** Bit mask for preserve presentation form. @stable ICU 3.6 */ +#define U_SHAPE_PRESERVE_PRESENTATION_MASK 0x8000 + +#endif diff --git a/utils/openttd/unicode/usprep.h b/utils/openttd/unicode/usprep.h new file mode 100644 index 00000000000..c7e75a53fab --- /dev/null +++ b/utils/openttd/unicode/usprep.h @@ -0,0 +1,156 @@ +/* + ******************************************************************************* + * + * Copyright (C) 2003-2006, International Business Machines + * Corporation and others. All Rights Reserved. + * + ******************************************************************************* + * file name: usprep.h + * encoding: US-ASCII + * tab size: 8 (not used) + * indentation:4 + * + * created on: 2003jul2 + * created by: Ram Viswanadha + */ + +#ifndef __USPREP_H__ +#define __USPREP_H__ + +/** + * \file + * \brief C API: Implements the StringPrep algorithm. + */ + +#include "unicode/utypes.h" +/** + * + * StringPrep API implements the StingPrep framework as described by RFC 3454. + * StringPrep prepares Unicode strings for use in network protocols. + * Profiles of StingPrep are set of rules and data according to with the + * Unicode Strings are prepared. Each profiles contains tables which describe + * how a code point should be treated. The tables are broadly classied into + * <ul> + * <li> Unassinged Table: Contains code points that are unassigned + * in the Unicode Version supported by StringPrep. Currently + * RFC 3454 supports Unicode 3.2. </li> + * <li> Prohibited Table: Contains code points that are prohibted from + * the output of the StringPrep processing function. </li> + * <li> Mapping Table: Contains code ponts that are deleted from the output or case mapped. </li> + * </ul> + * + * The procedure for preparing Unicode strings: + * <ol> + * <li> Map: For each character in the input, check if it has a mapping + * and, if so, replace it with its mapping. </li> + * <li> Normalize: Possibly normalize the result of step 1 using Unicode + * normalization. </li> + * <li> Prohibit: Check for any characters that are not allowed in the + * output. If any are found, return an error.</li> + * <li> Check bidi: Possibly check for right-to-left characters, and if + * any are found, make sure that the whole string satisfies the + * requirements for bidirectional strings. If the string does not + * satisfy the requirements for bidirectional strings, return an + * error. </li> + * </ol> + * @author Ram Viswanadha + */ +#if !UCONFIG_NO_IDNA + +#include "unicode/parseerr.h" + +/** + * The StringPrep profile + * @stable ICU 2.8 + */ +typedef struct UStringPrepProfile UStringPrepProfile; + + +/** + * Option to prohibit processing of unassigned code points in the input + * + * @see usprep_prepare + * @stable ICU 2.8 + */ +#define USPREP_DEFAULT 0x0000 + +/** + * Option to allow processing of unassigned code points in the input + * + * @see usprep_prepare + * @stable ICU 2.8 + */ +#define USPREP_ALLOW_UNASSIGNED 0x0001 + + +/** + * Creates a StringPrep profile from the data file. + * + * @param path string containing the full path pointing to the directory + * where the profile reside followed by the package name + * e.g. "/usr/resource/my_app/profiles/mydata" on a Unix system. + * if NULL, ICU default data files will be used. + * @param fileName name of the profile file to be opened + * @param status ICU error code in/out parameter. Must not be NULL. + * Must fulfill U_SUCCESS before the function call. + * @return Pointer to UStringPrepProfile that is opened. Should be closed by + * calling usprep_close() + * @see usprep_close() + * @stable ICU 2.8 + */ +U_STABLE UStringPrepProfile* U_EXPORT2 +usprep_open(const char* path, + const char* fileName, + UErrorCode* status); + + +/** + * Closes the profile + * @param profile The profile to close + * @stable ICU 2.8 + */ +U_STABLE void U_EXPORT2 +usprep_close(UStringPrepProfile* profile); + + +/** + * Prepare the input buffer for use in applications with the given profile. This operation maps, normalizes(NFKC), + * checks for prohited and BiDi characters in the order defined by RFC 3454 + * depending on the options specified in the profile. + * + * @param prep The profile to use + * @param src Pointer to UChar buffer containing the string to prepare + * @param srcLength Number of characters in the source string + * @param dest Pointer to the destination buffer to receive the output + * @param destCapacity The capacity of destination array + * @param options A bit set of options: + * + * - USPREP_NONE Prohibit processing of unassigned code points in the input + * + * - USPREP_ALLOW_UNASSIGNED Treat the unassigned code points are in the input + * as normal Unicode code points. + * + * @param parseError Pointer to UParseError struct to receive information on position + * of error if an error is encountered. Can be NULL. + * @param status ICU in/out error code parameter. + * U_INVALID_CHAR_FOUND if src contains + * unmatched single surrogates. + * U_INDEX_OUTOFBOUNDS_ERROR if src contains + * too many code points. + * U_BUFFER_OVERFLOW_ERROR if destCapacity is not enough + * @return The number of UChars in the destination buffer + * @stable ICU 2.8 + */ + +U_STABLE int32_t U_EXPORT2 +usprep_prepare( const UStringPrepProfile* prep, + const UChar* src, int32_t srcLength, + UChar* dest, int32_t destCapacity, + int32_t options, + UParseError* parseError, + UErrorCode* status ); + + +#endif /* #if !UCONFIG_NO_IDNA */ + +#endif diff --git a/utils/openttd/unicode/ustring.h b/utils/openttd/unicode/ustring.h new file mode 100644 index 00000000000..12411ef6d99 --- /dev/null +++ b/utils/openttd/unicode/ustring.h @@ -0,0 +1,1479 @@ +/* +********************************************************************** +* Copyright (C) 1998-2008, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* +* File ustring.h +* +* Modification History: +* +* Date Name Description +* 12/07/98 bertrand Creation. +****************************************************************************** +*/ + +#ifndef USTRING_H +#define USTRING_H + +#include "unicode/utypes.h" +#include "unicode/putil.h" +#include "unicode/uiter.h" + +/** Simple declaration for u_strToTitle() to avoid including unicode/ubrk.h. @stable ICU 2.1*/ +#ifndef UBRK_TYPEDEF_UBREAK_ITERATOR +# define UBRK_TYPEDEF_UBREAK_ITERATOR + typedef void UBreakIterator; +#endif + +/** + * \file + * \brief C API: Unicode string handling functions + * + * These C API functions provide general Unicode string handling. + * + * Some functions are equivalent in name, signature, and behavior to the ANSI C <string.h> + * functions. (For example, they do not check for bad arguments like NULL string pointers.) + * In some cases, only the thread-safe variant of such a function is implemented here + * (see u_strtok_r()). + * + * Other functions provide more Unicode-specific functionality like locale-specific + * upper/lower-casing and string comparison in code point order. + * + * ICU uses 16-bit Unicode (UTF-16) in the form of arrays of UChar code units. + * UTF-16 encodes each Unicode code point with either one or two UChar code units. + * (This is the default form of Unicode, and a forward-compatible extension of the original, + * fixed-width form that was known as UCS-2. UTF-16 superseded UCS-2 with Unicode 2.0 + * in 1996.) + * + * Some APIs accept a 32-bit UChar32 value for a single code point. + * + * ICU also handles 16-bit Unicode text with unpaired surrogates. + * Such text is not well-formed UTF-16. + * Code-point-related functions treat unpaired surrogates as surrogate code points, + * i.e., as separate units. + * + * Although UTF-16 is a variable-width encoding form (like some legacy multi-byte encodings), + * it is much more efficient even for random access because the code unit values + * for single-unit characters vs. lead units vs. trail units are completely disjoint. + * This means that it is easy to determine character (code point) boundaries from + * random offsets in the string. + * + * Unicode (UTF-16) string processing is optimized for the single-unit case. + * Although it is important to support supplementary characters + * (which use pairs of lead/trail code units called "surrogates"), + * their occurrence is rare. Almost all characters in modern use require only + * a single UChar code unit (i.e., their code point values are <=0xffff). + * + * For more details see the User Guide Strings chapter (http://icu-project.org/userguide/strings.html). + * For a discussion of the handling of unpaired surrogates see also + * Jitterbug 2145 and its icu mailing list proposal on 2002-sep-18. + */ + +/** + * \defgroup ustring_ustrlen String Length + * \ingroup ustring_strlen + */ +/*@{*/ +/** + * Determine the length of an array of UChar. + * + * @param s The array of UChars, NULL (U+0000) terminated. + * @return The number of UChars in <code>chars</code>, minus the terminator. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strlen(const UChar *s); +/*@}*/ + +/** + * Count Unicode code points in the length UChar code units of the string. + * A code point may occupy either one or two UChar code units. + * Counting code points involves reading all code units. + * + * This functions is basically the inverse of the U16_FWD_N() macro (see utf.h). + * + * @param s The input string. + * @param length The number of UChar code units to be checked, or -1 to count all + * code points before the first NUL (U+0000). + * @return The number of code points in the specified code units. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_countChar32(const UChar *s, int32_t length); + +/** + * Check if the string contains more Unicode code points than a certain number. + * This is more efficient than counting all code points in the entire string + * and comparing that number with a threshold. + * This function may not need to scan the string at all if the length is known + * (not -1 for NUL-termination) and falls within a certain range, and + * never needs to count more than 'number+1' code points. + * Logically equivalent to (u_countChar32(s, length)>number). + * A Unicode code point may occupy either one or two UChar code units. + * + * @param s The input string. + * @param length The length of the string, or -1 if it is NUL-terminated. + * @param number The number of code points in the string is compared against + * the 'number' parameter. + * @return Boolean value for whether the string contains more Unicode code points + * than 'number'. Same as (u_countChar32(s, length)>number). + * @stable ICU 2.4 + */ +U_STABLE UBool U_EXPORT2 +u_strHasMoreChar32Than(const UChar *s, int32_t length, int32_t number); + +/** + * Concatenate two ustrings. Appends a copy of <code>src</code>, + * including the null terminator, to <code>dst</code>. The initial copied + * character from <code>src</code> overwrites the null terminator in <code>dst</code>. + * + * @param dst The destination string. + * @param src The source string. + * @return A pointer to <code>dst</code>. + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 +u_strcat(UChar *dst, + const UChar *src); + +/** + * Concatenate two ustrings. + * Appends at most <code>n</code> characters from <code>src</code> to <code>dst</code>. + * Adds a terminating NUL. + * If src is too long, then only <code>n-1</code> characters will be copied + * before the terminating NUL. + * If <code>n<=0</code> then dst is not modified. + * + * @param dst The destination string. + * @param src The source string. + * @param n The maximum number of characters to compare. + * @return A pointer to <code>dst</code>. + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 +u_strncat(UChar *dst, + const UChar *src, + int32_t n); + +/** + * Find the first occurrence of a substring in a string. + * The substring is found at code point boundaries. + * That means that if the substring begins with + * a trail surrogate or ends with a lead surrogate, + * then it is found only if these surrogates stand alone in the text. + * Otherwise, the substring edge units would be matched against + * halves of surrogate pairs. + * + * @param s The string to search (NUL-terminated). + * @param substring The substring to find (NUL-terminated). + * @return A pointer to the first occurrence of <code>substring</code> in <code>s</code>, + * or <code>s</code> itself if the <code>substring</code> is empty, + * or <code>NULL</code> if <code>substring</code> is not in <code>s</code>. + * @stable ICU 2.0 + * + * @see u_strrstr + * @see u_strFindFirst + * @see u_strFindLast + */ +U_STABLE UChar * U_EXPORT2 +u_strstr(const UChar *s, const UChar *substring); + +/** + * Find the first occurrence of a substring in a string. + * The substring is found at code point boundaries. + * That means that if the substring begins with + * a trail surrogate or ends with a lead surrogate, + * then it is found only if these surrogates stand alone in the text. + * Otherwise, the substring edge units would be matched against + * halves of surrogate pairs. + * + * @param s The string to search. + * @param length The length of s (number of UChars), or -1 if it is NUL-terminated. + * @param substring The substring to find (NUL-terminated). + * @param subLength The length of substring (number of UChars), or -1 if it is NUL-terminated. + * @return A pointer to the first occurrence of <code>substring</code> in <code>s</code>, + * or <code>s</code> itself if the <code>substring</code> is empty, + * or <code>NULL</code> if <code>substring</code> is not in <code>s</code>. + * @stable ICU 2.4 + * + * @see u_strstr + * @see u_strFindLast + */ +U_STABLE UChar * U_EXPORT2 +u_strFindFirst(const UChar *s, int32_t length, const UChar *substring, int32_t subLength); + +/** + * Find the first occurrence of a BMP code point in a string. + * A surrogate code point is found only if its match in the text is not + * part of a surrogate pair. + * A NUL character is found at the string terminator. + * + * @param s The string to search (NUL-terminated). + * @param c The BMP code point to find. + * @return A pointer to the first occurrence of <code>c</code> in <code>s</code> + * or <code>NULL</code> if <code>c</code> is not in <code>s</code>. + * @stable ICU 2.0 + * + * @see u_strchr32 + * @see u_memchr + * @see u_strstr + * @see u_strFindFirst + */ +U_STABLE UChar * U_EXPORT2 +u_strchr(const UChar *s, UChar c); + +/** + * Find the first occurrence of a code point in a string. + * A surrogate code point is found only if its match in the text is not + * part of a surrogate pair. + * A NUL character is found at the string terminator. + * + * @param s The string to search (NUL-terminated). + * @param c The code point to find. + * @return A pointer to the first occurrence of <code>c</code> in <code>s</code> + * or <code>NULL</code> if <code>c</code> is not in <code>s</code>. + * @stable ICU 2.0 + * + * @see u_strchr + * @see u_memchr32 + * @see u_strstr + * @see u_strFindFirst + */ +U_STABLE UChar * U_EXPORT2 +u_strchr32(const UChar *s, UChar32 c); + +/** + * Find the last occurrence of a substring in a string. + * The substring is found at code point boundaries. + * That means that if the substring begins with + * a trail surrogate or ends with a lead surrogate, + * then it is found only if these surrogates stand alone in the text. + * Otherwise, the substring edge units would be matched against + * halves of surrogate pairs. + * + * @param s The string to search (NUL-terminated). + * @param substring The substring to find (NUL-terminated). + * @return A pointer to the last occurrence of <code>substring</code> in <code>s</code>, + * or <code>s</code> itself if the <code>substring</code> is empty, + * or <code>NULL</code> if <code>substring</code> is not in <code>s</code>. + * @stable ICU 2.4 + * + * @see u_strstr + * @see u_strFindFirst + * @see u_strFindLast + */ +U_STABLE UChar * U_EXPORT2 +u_strrstr(const UChar *s, const UChar *substring); + +/** + * Find the last occurrence of a substring in a string. + * The substring is found at code point boundaries. + * That means that if the substring begins with + * a trail surrogate or ends with a lead surrogate, + * then it is found only if these surrogates stand alone in the text. + * Otherwise, the substring edge units would be matched against + * halves of surrogate pairs. + * + * @param s The string to search. + * @param length The length of s (number of UChars), or -1 if it is NUL-terminated. + * @param substring The substring to find (NUL-terminated). + * @param subLength The length of substring (number of UChars), or -1 if it is NUL-terminated. + * @return A pointer to the last occurrence of <code>substring</code> in <code>s</code>, + * or <code>s</code> itself if the <code>substring</code> is empty, + * or <code>NULL</code> if <code>substring</code> is not in <code>s</code>. + * @stable ICU 2.4 + * + * @see u_strstr + * @see u_strFindLast + */ +U_STABLE UChar * U_EXPORT2 +u_strFindLast(const UChar *s, int32_t length, const UChar *substring, int32_t subLength); + +/** + * Find the last occurrence of a BMP code point in a string. + * A surrogate code point is found only if its match in the text is not + * part of a surrogate pair. + * A NUL character is found at the string terminator. + * + * @param s The string to search (NUL-terminated). + * @param c The BMP code point to find. + * @return A pointer to the last occurrence of <code>c</code> in <code>s</code> + * or <code>NULL</code> if <code>c</code> is not in <code>s</code>. + * @stable ICU 2.4 + * + * @see u_strrchr32 + * @see u_memrchr + * @see u_strrstr + * @see u_strFindLast + */ +U_STABLE UChar * U_EXPORT2 +u_strrchr(const UChar *s, UChar c); + +/** + * Find the last occurrence of a code point in a string. + * A surrogate code point is found only if its match in the text is not + * part of a surrogate pair. + * A NUL character is found at the string terminator. + * + * @param s The string to search (NUL-terminated). + * @param c The code point to find. + * @return A pointer to the last occurrence of <code>c</code> in <code>s</code> + * or <code>NULL</code> if <code>c</code> is not in <code>s</code>. + * @stable ICU 2.4 + * + * @see u_strrchr + * @see u_memchr32 + * @see u_strrstr + * @see u_strFindLast + */ +U_STABLE UChar * U_EXPORT2 +u_strrchr32(const UChar *s, UChar32 c); + +/** + * Locates the first occurrence in the string <code>string</code> of any of the characters + * in the string <code>matchSet</code>. + * Works just like C's strpbrk but with Unicode. + * + * @param string The string in which to search, NUL-terminated. + * @param matchSet A NUL-terminated string defining a set of code points + * for which to search in the text string. + * @return A pointer to the character in <code>string</code> that matches one of the + * characters in <code>matchSet</code>, or NULL if no such character is found. + * @stable ICU 2.0 + */ +U_STABLE UChar * U_EXPORT2 +u_strpbrk(const UChar *string, const UChar *matchSet); + +/** + * Returns the number of consecutive characters in <code>string</code>, + * beginning with the first, that do not occur somewhere in <code>matchSet</code>. + * Works just like C's strcspn but with Unicode. + * + * @param string The string in which to search, NUL-terminated. + * @param matchSet A NUL-terminated string defining a set of code points + * for which to search in the text string. + * @return The number of initial characters in <code>string</code> that do not + * occur in <code>matchSet</code>. + * @see u_strspn + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strcspn(const UChar *string, const UChar *matchSet); + +/** + * Returns the number of consecutive characters in <code>string</code>, + * beginning with the first, that occur somewhere in <code>matchSet</code>. + * Works just like C's strspn but with Unicode. + * + * @param string The string in which to search, NUL-terminated. + * @param matchSet A NUL-terminated string defining a set of code points + * for which to search in the text string. + * @return The number of initial characters in <code>string</code> that do + * occur in <code>matchSet</code>. + * @see u_strcspn + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strspn(const UChar *string, const UChar *matchSet); + +/** + * The string tokenizer API allows an application to break a string into + * tokens. Unlike strtok(), the saveState (the current pointer within the + * original string) is maintained in saveState. In the first call, the + * argument src is a pointer to the string. In subsequent calls to + * return successive tokens of that string, src must be specified as + * NULL. The value saveState is set by this function to maintain the + * function's position within the string, and on each subsequent call + * you must give this argument the same variable. This function does + * handle surrogate pairs. This function is similar to the strtok_r() + * the POSIX Threads Extension (1003.1c-1995) version. + * + * @param src String containing token(s). This string will be modified. + * After the first call to u_strtok_r(), this argument must + * be NULL to get to the next token. + * @param delim Set of delimiter characters (Unicode code points). + * @param saveState The current pointer within the original string, + * which is set by this function. The saveState + * parameter should the address of a local variable of type + * UChar *. (i.e. defined "Uhar *myLocalSaveState" and use + * &myLocalSaveState for this parameter). + * @return A pointer to the next token found in src, or NULL + * when there are no more tokens. + * @stable ICU 2.0 + */ +U_STABLE UChar * U_EXPORT2 +u_strtok_r(UChar *src, + const UChar *delim, + UChar **saveState); + +/** + * Compare two Unicode strings for bitwise equality (code unit order). + * + * @param s1 A string to compare. + * @param s2 A string to compare. + * @return 0 if <code>s1</code> and <code>s2</code> are bitwise equal; a negative + * value if <code>s1</code> is bitwise less than <code>s2,</code>; a positive + * value if <code>s1</code> is bitwise greater than <code>s2</code>. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strcmp(const UChar *s1, + const UChar *s2); + +/** + * Compare two Unicode strings in code point order. + * See u_strCompare for details. + * + * @param s1 A string to compare. + * @param s2 A string to compare. + * @return a negative/zero/positive integer corresponding to whether + * the first string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strcmpCodePointOrder(const UChar *s1, const UChar *s2); + +/** + * Compare two Unicode strings (binary order). + * + * The comparison can be done in code unit order or in code point order. + * They differ only in UTF-16 when + * comparing supplementary code points (U+10000..U+10ffff) + * to BMP code points near the end of the BMP (i.e., U+e000..U+ffff). + * In code unit order, high BMP code points sort after supplementary code points + * because they are stored as pairs of surrogates which are at U+d800..U+dfff. + * + * This functions works with strings of different explicitly specified lengths + * unlike the ANSI C-like u_strcmp() and u_memcmp() etc. + * NUL-terminated strings are possible with length arguments of -1. + * + * @param s1 First source string. + * @param length1 Length of first source string, or -1 if NUL-terminated. + * + * @param s2 Second source string. + * @param length2 Length of second source string, or -1 if NUL-terminated. + * + * @param codePointOrder Choose between code unit order (FALSE) + * and code point order (TRUE). + * + * @return <0 or 0 or >0 as usual for string comparisons + * + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +u_strCompare(const UChar *s1, int32_t length1, + const UChar *s2, int32_t length2, + UBool codePointOrder); + +/** + * Compare two Unicode strings (binary order) + * as presented by UCharIterator objects. + * Works otherwise just like u_strCompare(). + * + * Both iterators are reset to their start positions. + * When the function returns, it is undefined where the iterators + * have stopped. + * + * @param iter1 First source string iterator. + * @param iter2 Second source string iterator. + * @param codePointOrder Choose between code unit order (FALSE) + * and code point order (TRUE). + * + * @return <0 or 0 or >0 as usual for string comparisons + * + * @see u_strCompare + * + * @stable ICU 2.6 + */ +U_STABLE int32_t U_EXPORT2 +u_strCompareIter(UCharIterator *iter1, UCharIterator *iter2, UBool codePointOrder); + +#ifndef U_COMPARE_CODE_POINT_ORDER +/* see also unistr.h and unorm.h */ +/** + * Option bit for u_strCaseCompare, u_strcasecmp, unorm_compare, etc: + * Compare strings in code point order instead of code unit order. + * @stable ICU 2.2 + */ +#define U_COMPARE_CODE_POINT_ORDER 0x8000 +#endif + +/** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to + * u_strCompare(u_strFoldCase(s1, options), + * u_strFoldCase(s2, options), + * (options&U_COMPARE_CODE_POINT_ORDER)!=0). + * + * The comparison can be done in UTF-16 code unit order or in code point order. + * They differ only when comparing supplementary code points (U+10000..U+10ffff) + * to BMP code points near the end of the BMP (i.e., U+e000..U+ffff). + * In code unit order, high BMP code points sort after supplementary code points + * because they are stored as pairs of surrogates which are at U+d800..U+dfff. + * + * This functions works with strings of different explicitly specified lengths + * unlike the ANSI C-like u_strcmp() and u_memcmp() etc. + * NUL-terminated strings are possible with length arguments of -1. + * + * @param s1 First source string. + * @param length1 Length of first source string, or -1 if NUL-terminated. + * + * @param s2 Second source string. + * @param length2 Length of second source string, or -1 if NUL-terminated. + * + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * + * @return <0 or 0 or >0 as usual for string comparisons + * + * @stable ICU 2.2 + */ +U_STABLE int32_t U_EXPORT2 +u_strCaseCompare(const UChar *s1, int32_t length1, + const UChar *s2, int32_t length2, + uint32_t options, + UErrorCode *pErrorCode); + +/** + * Compare two ustrings for bitwise equality. + * Compares at most <code>n</code> characters. + * + * @param ucs1 A string to compare. + * @param ucs2 A string to compare. + * @param n The maximum number of characters to compare. + * @return 0 if <code>s1</code> and <code>s2</code> are bitwise equal; a negative + * value if <code>s1</code> is bitwise less than <code>s2</code>; a positive + * value if <code>s1</code> is bitwise greater than <code>s2</code>. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strncmp(const UChar *ucs1, + const UChar *ucs2, + int32_t n); + +/** + * Compare two Unicode strings in code point order. + * This is different in UTF-16 from u_strncmp() if supplementary characters are present. + * For details, see u_strCompare(). + * + * @param s1 A string to compare. + * @param s2 A string to compare. + * @param n The maximum number of characters to compare. + * @return a negative/zero/positive integer corresponding to whether + * the first string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strncmpCodePointOrder(const UChar *s1, const UChar *s2, int32_t n); + +/** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to u_strcmp(u_strFoldCase(s1, options), u_strFoldCase(s2, options)). + * + * @param s1 A string to compare. + * @param s2 A string to compare. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strcasecmp(const UChar *s1, const UChar *s2, uint32_t options); + +/** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to u_strcmp(u_strFoldCase(s1, at most n, options), + * u_strFoldCase(s2, at most n, options)). + * + * @param s1 A string to compare. + * @param s2 A string to compare. + * @param n The maximum number of characters each string to case-fold and then compare. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strncasecmp(const UChar *s1, const UChar *s2, int32_t n, uint32_t options); + +/** + * Compare two strings case-insensitively using full case folding. + * This is equivalent to u_strcmp(u_strFoldCase(s1, n, options), + * u_strFoldCase(s2, n, options)). + * + * @param s1 A string to compare. + * @param s2 A string to compare. + * @param length The number of characters in each string to case-fold and then compare. + * @param options A bit set of options: + * - U_FOLD_CASE_DEFAULT or 0 is used for default options: + * Comparison in code unit order with default case folding. + * + * - U_COMPARE_CODE_POINT_ORDER + * Set to choose code point order instead of code unit order + * (see u_strCompare for details). + * + * - U_FOLD_CASE_EXCLUDE_SPECIAL_I + * + * @return A negative, zero, or positive integer indicating the comparison result. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_memcasecmp(const UChar *s1, const UChar *s2, int32_t length, uint32_t options); + +/** + * Copy a ustring. Adds a null terminator. + * + * @param dst The destination string. + * @param src The source string. + * @return A pointer to <code>dst</code>. + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 +u_strcpy(UChar *dst, + const UChar *src); + +/** + * Copy a ustring. + * Copies at most <code>n</code> characters. The result will be null terminated + * if the length of <code>src</code> is less than <code>n</code>. + * + * @param dst The destination string. + * @param src The source string. + * @param n The maximum number of characters to copy. + * @return A pointer to <code>dst</code>. + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 +u_strncpy(UChar *dst, + const UChar *src, + int32_t n); + +#if !UCONFIG_NO_CONVERSION + +/** + * Copy a byte string encoded in the default codepage to a ustring. + * Adds a null terminator. + * Performs a host byte to UChar conversion + * + * @param dst The destination string. + * @param src The source string. + * @return A pointer to <code>dst</code>. + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 u_uastrcpy(UChar *dst, + const char *src ); + +/** + * Copy a byte string encoded in the default codepage to a ustring. + * Copies at most <code>n</code> characters. The result will be null terminated + * if the length of <code>src</code> is less than <code>n</code>. + * Performs a host byte to UChar conversion + * + * @param dst The destination string. + * @param src The source string. + * @param n The maximum number of characters to copy. + * @return A pointer to <code>dst</code>. + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 u_uastrncpy(UChar *dst, + const char *src, + int32_t n); + +/** + * Copy ustring to a byte string encoded in the default codepage. + * Adds a null terminator. + * Performs a UChar to host byte conversion + * + * @param dst The destination string. + * @param src The source string. + * @return A pointer to <code>dst</code>. + * @stable ICU 2.0 + */ +U_STABLE char* U_EXPORT2 u_austrcpy(char *dst, + const UChar *src ); + +/** + * Copy ustring to a byte string encoded in the default codepage. + * Copies at most <code>n</code> characters. The result will be null terminated + * if the length of <code>src</code> is less than <code>n</code>. + * Performs a UChar to host byte conversion + * + * @param dst The destination string. + * @param src The source string. + * @param n The maximum number of characters to copy. + * @return A pointer to <code>dst</code>. + * @stable ICU 2.0 + */ +U_STABLE char* U_EXPORT2 u_austrncpy(char *dst, + const UChar *src, + int32_t n ); + +#endif + +/** + * Synonym for memcpy(), but with UChars only. + * @param dest The destination string + * @param src The source string + * @param count The number of characters to copy + * @return A pointer to <code>dest</code> + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 +u_memcpy(UChar *dest, const UChar *src, int32_t count); + +/** + * Synonym for memmove(), but with UChars only. + * @param dest The destination string + * @param src The source string + * @param count The number of characters to move + * @return A pointer to <code>dest</code> + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 +u_memmove(UChar *dest, const UChar *src, int32_t count); + +/** + * Initialize <code>count</code> characters of <code>dest</code> to <code>c</code>. + * + * @param dest The destination string. + * @param c The character to initialize the string. + * @param count The maximum number of characters to set. + * @return A pointer to <code>dest</code>. + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 +u_memset(UChar *dest, UChar c, int32_t count); + +/** + * Compare the first <code>count</code> UChars of each buffer. + * + * @param buf1 The first string to compare. + * @param buf2 The second string to compare. + * @param count The maximum number of UChars to compare. + * @return When buf1 < buf2, a negative number is returned. + * When buf1 == buf2, 0 is returned. + * When buf1 > buf2, a positive number is returned. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_memcmp(const UChar *buf1, const UChar *buf2, int32_t count); + +/** + * Compare two Unicode strings in code point order. + * This is different in UTF-16 from u_memcmp() if supplementary characters are present. + * For details, see u_strCompare(). + * + * @param s1 A string to compare. + * @param s2 A string to compare. + * @param count The maximum number of characters to compare. + * @return a negative/zero/positive integer corresponding to whether + * the first string is less than/equal to/greater than the second one + * in code point order + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_memcmpCodePointOrder(const UChar *s1, const UChar *s2, int32_t count); + +/** + * Find the first occurrence of a BMP code point in a string. + * A surrogate code point is found only if its match in the text is not + * part of a surrogate pair. + * A NUL character is found at the string terminator. + * + * @param s The string to search (contains <code>count</code> UChars). + * @param c The BMP code point to find. + * @param count The length of the string. + * @return A pointer to the first occurrence of <code>c</code> in <code>s</code> + * or <code>NULL</code> if <code>c</code> is not in <code>s</code>. + * @stable ICU 2.0 + * + * @see u_strchr + * @see u_memchr32 + * @see u_strFindFirst + */ +U_STABLE UChar* U_EXPORT2 +u_memchr(const UChar *s, UChar c, int32_t count); + +/** + * Find the first occurrence of a code point in a string. + * A surrogate code point is found only if its match in the text is not + * part of a surrogate pair. + * A NUL character is found at the string terminator. + * + * @param s The string to search (contains <code>count</code> UChars). + * @param c The code point to find. + * @param count The length of the string. + * @return A pointer to the first occurrence of <code>c</code> in <code>s</code> + * or <code>NULL</code> if <code>c</code> is not in <code>s</code>. + * @stable ICU 2.0 + * + * @see u_strchr32 + * @see u_memchr + * @see u_strFindFirst + */ +U_STABLE UChar* U_EXPORT2 +u_memchr32(const UChar *s, UChar32 c, int32_t count); + +/** + * Find the last occurrence of a BMP code point in a string. + * A surrogate code point is found only if its match in the text is not + * part of a surrogate pair. + * A NUL character is found at the string terminator. + * + * @param s The string to search (contains <code>count</code> UChars). + * @param c The BMP code point to find. + * @param count The length of the string. + * @return A pointer to the last occurrence of <code>c</code> in <code>s</code> + * or <code>NULL</code> if <code>c</code> is not in <code>s</code>. + * @stable ICU 2.4 + * + * @see u_strrchr + * @see u_memrchr32 + * @see u_strFindLast + */ +U_STABLE UChar* U_EXPORT2 +u_memrchr(const UChar *s, UChar c, int32_t count); + +/** + * Find the last occurrence of a code point in a string. + * A surrogate code point is found only if its match in the text is not + * part of a surrogate pair. + * A NUL character is found at the string terminator. + * + * @param s The string to search (contains <code>count</code> UChars). + * @param c The code point to find. + * @param count The length of the string. + * @return A pointer to the last occurrence of <code>c</code> in <code>s</code> + * or <code>NULL</code> if <code>c</code> is not in <code>s</code>. + * @stable ICU 2.4 + * + * @see u_strrchr32 + * @see u_memrchr + * @see u_strFindLast + */ +U_STABLE UChar* U_EXPORT2 +u_memrchr32(const UChar *s, UChar32 c, int32_t count); + +/** + * Unicode String literals in C. + * We need one macro to declare a variable for the string + * and to statically preinitialize it if possible, + * and a second macro to dynamically intialize such a string variable if necessary. + * + * The macros are defined for maximum performance. + * They work only for strings that contain "invariant characters", i.e., + * only latin letters, digits, and some punctuation. + * See utypes.h for details. + * + * A pair of macros for a single string must be used with the same + * parameters. + * The string parameter must be a C string literal. + * The length of the string, not including the terminating + * <code>NUL</code>, must be specified as a constant. + * The U_STRING_DECL macro should be invoked exactly once for one + * such string variable before it is used. + * + * Usage: + * <pre> + * U_STRING_DECL(ustringVar1, "Quick-Fox 2", 11); + * U_STRING_DECL(ustringVar2, "jumps 5%", 8); + * static UBool didInit=FALSE; + * + * int32_t function() { + * if(!didInit) { + * U_STRING_INIT(ustringVar1, "Quick-Fox 2", 11); + * U_STRING_INIT(ustringVar2, "jumps 5%", 8); + * didInit=TRUE; + * } + * return u_strcmp(ustringVar1, ustringVar2); + * } + * </pre> + * @stable ICU 2.0 + */ +#if defined(U_DECLARE_UTF16) +# define U_STRING_DECL(var, cs, length) static const UChar var[(length)+1]=U_DECLARE_UTF16(cs) + /**@stable ICU 2.0 */ +# define U_STRING_INIT(var, cs, length) +#elif U_SIZEOF_WCHAR_T==U_SIZEOF_UCHAR && (U_CHARSET_FAMILY==U_ASCII_FAMILY || (U_SIZEOF_UCHAR == 2 && defined(U_WCHAR_IS_UTF16))) +# define U_STRING_DECL(var, cs, length) static const UChar var[(length)+1]=L ## cs + /**@stable ICU 2.0 */ +# define U_STRING_INIT(var, cs, length) +#elif U_SIZEOF_UCHAR==1 && U_CHARSET_FAMILY==U_ASCII_FAMILY +# define U_STRING_DECL(var, cs, length) static const UChar var[(length)+1]=cs + /**@stable ICU 2.0 */ +# define U_STRING_INIT(var, cs, length) +#else +# define U_STRING_DECL(var, cs, length) static UChar var[(length)+1] + /**@stable ICU 2.0 */ +# define U_STRING_INIT(var, cs, length) u_charsToUChars(cs, var, length+1) +#endif + +/** + * Unescape a string of characters and write the resulting + * Unicode characters to the destination buffer. The following escape + * sequences are recognized: + * + * \\uhhhh 4 hex digits; h in [0-9A-Fa-f] + * \\Uhhhhhhhh 8 hex digits + * \\xhh 1-2 hex digits + * \\x{h...} 1-8 hex digits + * \\ooo 1-3 octal digits; o in [0-7] + * \\cX control-X; X is masked with 0x1F + * + * as well as the standard ANSI C escapes: + * + * \\a => U+0007, \\b => U+0008, \\t => U+0009, \\n => U+000A, + * \\v => U+000B, \\f => U+000C, \\r => U+000D, \\e => U+001B, + * \\" => U+0022, \\' => U+0027, \\? => U+003F, \\\\ => U+005C + * + * Anything else following a backslash is generically escaped. For + * example, "[a\\-z]" returns "[a-z]". + * + * If an escape sequence is ill-formed, this method returns an empty + * string. An example of an ill-formed sequence is "\\u" followed by + * fewer than 4 hex digits. + * + * The above characters are recognized in the compiler's codepage, + * that is, they are coded as 'u', '\\', etc. Characters that are + * not parts of escape sequences are converted using u_charsToUChars(). + * + * This function is similar to UnicodeString::unescape() but not + * identical to it. The latter takes a source UnicodeString, so it + * does escape recognition but no conversion. + * + * @param src a zero-terminated string of invariant characters + * @param dest pointer to buffer to receive converted and unescaped + * text and, if there is room, a zero terminator. May be NULL for + * preflighting, in which case no UChars will be written, but the + * return value will still be valid. On error, an empty string is + * stored here (if possible). + * @param destCapacity the number of UChars that may be written at + * dest. Ignored if dest == NULL. + * @return the length of unescaped string. + * @see u_unescapeAt + * @see UnicodeString#unescape() + * @see UnicodeString#unescapeAt() + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_unescape(const char *src, + UChar *dest, int32_t destCapacity); + +U_CDECL_BEGIN +/** + * Callback function for u_unescapeAt() that returns a character of + * the source text given an offset and a context pointer. The context + * pointer will be whatever is passed into u_unescapeAt(). + * + * @param offset pointer to the offset that will be passed to u_unescapeAt(). + * @param context an opaque pointer passed directly into u_unescapeAt() + * @return the character represented by the escape sequence at + * offset + * @see u_unescapeAt + * @stable ICU 2.0 + */ +typedef UChar (U_CALLCONV *UNESCAPE_CHAR_AT)(int32_t offset, void *context); +U_CDECL_END + +/** + * Unescape a single sequence. The character at offset-1 is assumed + * (without checking) to be a backslash. This method takes a callback + * pointer to a function that returns the UChar at a given offset. By + * varying this callback, ICU functions are able to unescape char* + * strings, UnicodeString objects, and UFILE pointers. + * + * If offset is out of range, or if the escape sequence is ill-formed, + * (UChar32)0xFFFFFFFF is returned. See documentation of u_unescape() + * for a list of recognized sequences. + * + * @param charAt callback function that returns a UChar of the source + * text given an offset and a context pointer. + * @param offset pointer to the offset that will be passed to charAt. + * The offset value will be updated upon return to point after the + * last parsed character of the escape sequence. On error the offset + * is unchanged. + * @param length the number of characters in the source text. The + * last character of the source text is considered to be at offset + * length-1. + * @param context an opaque pointer passed directly into charAt. + * @return the character represented by the escape sequence at + * offset, or (UChar32)0xFFFFFFFF on error. + * @see u_unescape() + * @see UnicodeString#unescape() + * @see UnicodeString#unescapeAt() + * @stable ICU 2.0 + */ +U_STABLE UChar32 U_EXPORT2 +u_unescapeAt(UNESCAPE_CHAR_AT charAt, + int32_t *offset, + int32_t length, + void *context); + +/** + * Uppercase the characters in a string. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer are allowed to overlap. + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param src The original string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param locale The locale to consider, or "" for the root locale or NULL for the default locale. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The length of the result string. It may be greater than destCapacity. In that case, + * only some of the result was written to the destination buffer. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strToUpper(UChar *dest, int32_t destCapacity, + const UChar *src, int32_t srcLength, + const char *locale, + UErrorCode *pErrorCode); + +/** + * Lowercase the characters in a string. + * Casing is locale-dependent and context-sensitive. + * The result may be longer or shorter than the original. + * The source string and the destination buffer are allowed to overlap. + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param src The original string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param locale The locale to consider, or "" for the root locale or NULL for the default locale. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The length of the result string. It may be greater than destCapacity. In that case, + * only some of the result was written to the destination buffer. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strToLower(UChar *dest, int32_t destCapacity, + const UChar *src, int32_t srcLength, + const char *locale, + UErrorCode *pErrorCode); + +#if !UCONFIG_NO_BREAK_ITERATION + +/** + * Titlecase a string. + * Casing is locale-dependent and context-sensitive. + * Titlecasing uses a break iterator to find the first characters of words + * that are to be titlecased. It titlecases those characters and lowercases + * all others. + * + * The titlecase break iterator can be provided to customize for arbitrary + * styles, using rules and dictionaries beyond the standard iterators. + * It may be more efficient to always provide an iterator to avoid + * opening and closing one for each string. + * The standard titlecase iterator for the root locale implements the + * algorithm of Unicode TR 21. + * + * This function uses only the setText(), first() and next() methods of the + * provided break iterator. + * + * The result may be longer or shorter than the original. + * The source string and the destination buffer are allowed to overlap. + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param src The original string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param titleIter A break iterator to find the first characters of words + * that are to be titlecased. + * If none is provided (NULL), then a standard titlecase + * break iterator is opened. + * @param locale The locale to consider, or "" for the root locale or NULL for the default locale. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The length of the result string. It may be greater than destCapacity. In that case, + * only some of the result was written to the destination buffer. + * @stable ICU 2.1 + */ +U_STABLE int32_t U_EXPORT2 +u_strToTitle(UChar *dest, int32_t destCapacity, + const UChar *src, int32_t srcLength, + UBreakIterator *titleIter, + const char *locale, + UErrorCode *pErrorCode); + +#endif + +/** + * Case-fold the characters in a string. + * Case-folding is locale-independent and not context-sensitive, + * but there is an option for whether to include or exclude mappings for dotted I + * and dotless i that are marked with 'I' in CaseFolding.txt. + * The result may be longer or shorter than the original. + * The source string and the destination buffer are allowed to overlap. + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the result + * without writing any of the result string. + * @param src The original string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param options Either U_FOLD_CASE_DEFAULT or U_FOLD_CASE_EXCLUDE_SPECIAL_I + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The length of the result string. It may be greater than destCapacity. In that case, + * only some of the result was written to the destination buffer. + * @stable ICU 2.0 + */ +U_STABLE int32_t U_EXPORT2 +u_strFoldCase(UChar *dest, int32_t destCapacity, + const UChar *src, int32_t srcLength, + uint32_t options, + UErrorCode *pErrorCode); + +#if defined(U_WCHAR_IS_UTF16) || defined(U_WCHAR_IS_UTF32) || !UCONFIG_NO_CONVERSION +/** + * Converts a sequence of UChars to wchar_t units. + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of wchar_t's). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param pDestLength A pointer to receive the number of units written to the destination. If + * pDestLength!=NULL then *pDestLength is always set to the + * number of output units corresponding to the transformation of + * all the input units, even in case of a buffer overflow. + * @param src The original source string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The pointer to destination buffer. + * @stable ICU 2.0 + */ +U_STABLE wchar_t* U_EXPORT2 +u_strToWCS(wchar_t *dest, + int32_t destCapacity, + int32_t *pDestLength, + const UChar *src, + int32_t srcLength, + UErrorCode *pErrorCode); +/** + * Converts a sequence of wchar_t units to UChars + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param pDestLength A pointer to receive the number of units written to the destination. If + * pDestLength!=NULL then *pDestLength is always set to the + * number of output units corresponding to the transformation of + * all the input units, even in case of a buffer overflow. + * @param src The original source string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The pointer to destination buffer. + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 +u_strFromWCS(UChar *dest, + int32_t destCapacity, + int32_t *pDestLength, + const wchar_t *src, + int32_t srcLength, + UErrorCode *pErrorCode); +#endif /* defined(U_WCHAR_IS_UTF16) || defined(U_WCHAR_IS_UTF32) || !UCONFIG_NO_CONVERSION */ + +/** + * Converts a sequence of UChars (UTF-16) to UTF-8 bytes + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of chars). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param pDestLength A pointer to receive the number of units written to the destination. If + * pDestLength!=NULL then *pDestLength is always set to the + * number of output units corresponding to the transformation of + * all the input units, even in case of a buffer overflow. + * @param src The original source string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The pointer to destination buffer. + * @stable ICU 2.0 + * @see u_strToUTF8WithSub + * @see u_strFromUTF8 + */ +U_STABLE char* U_EXPORT2 +u_strToUTF8(char *dest, + int32_t destCapacity, + int32_t *pDestLength, + const UChar *src, + int32_t srcLength, + UErrorCode *pErrorCode); + +/** + * Converts a sequence of UTF-8 bytes to UChars (UTF-16). + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param pDestLength A pointer to receive the number of units written to the destination. If + * pDestLength!=NULL then *pDestLength is always set to the + * number of output units corresponding to the transformation of + * all the input units, even in case of a buffer overflow. + * @param src The original source string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The pointer to destination buffer. + * @stable ICU 2.0 + * @see u_strFromUTF8WithSub + * @see u_strFromUTF8Lenient + */ +U_STABLE UChar* U_EXPORT2 +u_strFromUTF8(UChar *dest, + int32_t destCapacity, + int32_t *pDestLength, + const char *src, + int32_t srcLength, + UErrorCode *pErrorCode); + +/** + * Converts a sequence of UChars (UTF-16) to UTF-8 bytes. + * Same as u_strToUTF8() except for the additional subchar which is output for + * illegal input sequences, instead of stopping with the U_INVALID_CHAR_FOUND error code. + * With subchar==U_SENTINEL, this function behaves exactly like u_strToUTF8(). + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of chars). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param pDestLength A pointer to receive the number of units written to the destination. If + * pDestLength!=NULL then *pDestLength is always set to the + * number of output units corresponding to the transformation of + * all the input units, even in case of a buffer overflow. + * @param src The original source string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param subchar The substitution character to use in place of an illegal input sequence, + * or U_SENTINEL if the function is to return with U_INVALID_CHAR_FOUND instead. + * A substitution character can be any valid Unicode code point (up to U+10FFFF) + * except for surrogate code points (U+D800..U+DFFF). + * The recommended value is U+FFFD "REPLACEMENT CHARACTER". + * @param pNumSubstitutions Output parameter receiving the number of substitutions if subchar>=0. + * Set to 0 if no substitutions occur or subchar<0. + * pNumSubstitutions can be NULL. + * @param pErrorCode Pointer to a standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @return The pointer to destination buffer. + * @see u_strToUTF8 + * @see u_strFromUTF8WithSub + * @stable ICU 3.6 + */ +U_STABLE char* U_EXPORT2 +u_strToUTF8WithSub(char *dest, + int32_t destCapacity, + int32_t *pDestLength, + const UChar *src, + int32_t srcLength, + UChar32 subchar, int32_t *pNumSubstitutions, + UErrorCode *pErrorCode); + +/** + * Converts a sequence of UTF-8 bytes to UChars (UTF-16). + * Same as u_strFromUTF8() except for the additional subchar which is output for + * illegal input sequences, instead of stopping with the U_INVALID_CHAR_FOUND error code. + * With subchar==U_SENTINEL, this function behaves exactly like u_strFromUTF8(). + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param pDestLength A pointer to receive the number of units written to the destination. If + * pDestLength!=NULL then *pDestLength is always set to the + * number of output units corresponding to the transformation of + * all the input units, even in case of a buffer overflow. + * @param src The original source string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param subchar The substitution character to use in place of an illegal input sequence, + * or U_SENTINEL if the function is to return with U_INVALID_CHAR_FOUND instead. + * A substitution character can be any valid Unicode code point (up to U+10FFFF) + * except for surrogate code points (U+D800..U+DFFF). + * The recommended value is U+FFFD "REPLACEMENT CHARACTER". + * @param pNumSubstitutions Output parameter receiving the number of substitutions if subchar>=0. + * Set to 0 if no substitutions occur or subchar<0. + * pNumSubstitutions can be NULL. + * @param pErrorCode Pointer to a standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @return The pointer to destination buffer. + * @see u_strFromUTF8 + * @see u_strFromUTF8Lenient + * @see u_strToUTF8WithSub + * @stable ICU 3.6 + */ +U_STABLE UChar* U_EXPORT2 +u_strFromUTF8WithSub(UChar *dest, + int32_t destCapacity, + int32_t *pDestLength, + const char *src, + int32_t srcLength, + UChar32 subchar, int32_t *pNumSubstitutions, + UErrorCode *pErrorCode); + +/** + * Converts a sequence of UTF-8 bytes to UChars (UTF-16). + * Same as u_strFromUTF8() except that this function is designed to be very fast, + * which it achieves by being lenient about malformed UTF-8 sequences. + * This function is intended for use in environments where UTF-8 text is + * expected to be well-formed. + * + * Its semantics are: + * - Well-formed UTF-8 text is correctly converted to well-formed UTF-16 text. + * - The function will not read beyond the input string, nor write beyond + * the destCapacity. + * - Malformed UTF-8 results in "garbage" 16-bit Unicode strings which may not + * be well-formed UTF-16. + * The function will resynchronize to valid code point boundaries + * within a small number of code points after an illegal sequence. + * - Non-shortest forms are not detected and will result in "spoofing" output. + * + * For further performance improvement, if srcLength is given (>=0), + * then it must be destCapacity>=srcLength. + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * Unlike for other ICU functions, if srcLength>=0 then it + * must be destCapacity>=srcLength. + * @param pDestLength A pointer to receive the number of units written to the destination. If + * pDestLength!=NULL then *pDestLength is always set to the + * number of output units corresponding to the transformation of + * all the input units, even in case of a buffer overflow. + * Unlike for other ICU functions, if srcLength>=0 but + * destCapacity<srcLength, then *pDestLength will be set to srcLength + * (and U_BUFFER_OVERFLOW_ERROR will be set) + * regardless of the actual result length. + * @param src The original source string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param pErrorCode Pointer to a standard ICU error code. Its input value must + * pass the U_SUCCESS() test, or else the function returns + * immediately. Check for U_FAILURE() on output or use with + * function chaining. (See User Guide for details.) + * @return The pointer to destination buffer. + * @see u_strFromUTF8 + * @see u_strFromUTF8WithSub + * @see u_strToUTF8WithSub + * @stable ICU 3.6 + */ +U_STABLE UChar * U_EXPORT2 +u_strFromUTF8Lenient(UChar *dest, + int32_t destCapacity, + int32_t *pDestLength, + const char *src, + int32_t srcLength, + UErrorCode *pErrorCode); + +/** + * Converts a sequence of UChars (UTF-16) to UTF32 units. + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChar32s). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param pDestLength A pointer to receive the number of units written to the destination. If + * pDestLength!=NULL then *pDestLength is always set to the + * number of output units corresponding to the transformation of + * all the input units, even in case of a buffer overflow. + * @param src The original source string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The pointer to destination buffer. + * @stable ICU 2.0 + */ +U_STABLE UChar32* U_EXPORT2 +u_strToUTF32(UChar32 *dest, + int32_t destCapacity, + int32_t *pDestLength, + const UChar *src, + int32_t srcLength, + UErrorCode *pErrorCode); + +/** + * Converts a sequence of UTF32 units to UChars (UTF-16) + * + * @param dest A buffer for the result string. The result will be zero-terminated if + * the buffer is large enough. + * @param destCapacity The size of the buffer (number of UChars). If it is 0, then + * dest may be NULL and the function will only return the length of the + * result without writing any of the result string (pre-flighting). + * @param pDestLength A pointer to receive the number of units written to the destination. If + * pDestLength!=NULL then *pDestLength is always set to the + * number of output units corresponding to the transformation of + * all the input units, even in case of a buffer overflow. + * @param src The original source string + * @param srcLength The length of the original string. If -1, then src must be zero-terminated. + * @param pErrorCode Must be a valid pointer to an error code value, + * which must not indicate a failure before the function call. + * @return The pointer to destination buffer. + * @stable ICU 2.0 + */ +U_STABLE UChar* U_EXPORT2 +u_strFromUTF32(UChar *dest, + int32_t destCapacity, + int32_t *pDestLength, + const UChar32 *src, + int32_t srcLength, + UErrorCode *pErrorCode); + +#endif diff --git a/utils/openttd/unicode/usystem.h b/utils/openttd/unicode/usystem.h new file mode 100644 index 00000000000..752e2f160de --- /dev/null +++ b/utils/openttd/unicode/usystem.h @@ -0,0 +1,46 @@ +/* +******************************************************************************* +* Copyright (C) 2004-2008, International Business Machines +* Corporation and others. All Rights Reserved. +******************************************************************************* +* +* file name: +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* Created by: genheaders.pl, a perl script written by Ram Viswanadha +* +* Contains data for commenting out APIs. +* Gets included by umachine.h +* +* THIS FILE IS MACHINE-GENERATED, DON'T PLAY WITH IT IF YOU DON'T KNOW WHAT +* YOU ARE DOING, OTHERWISE VERY BAD THINGS WILL HAPPEN! +*/ + +#ifndef USYSTEM_H +#define USYSTEM_H + +#ifdef U_HIDE_SYSTEM_API + +# if U_DISABLE_RENAMING +# define u_cleanup u_cleanup_SYSTEM_API_DO_NOT_USE +# define u_setAtomicIncDecFunctions u_setAtomicIncDecFunctions_SYSTEM_API_DO_NOT_USE +# define u_setMemoryFunctions u_setMemoryFunctions_SYSTEM_API_DO_NOT_USE +# define u_setMutexFunctions u_setMutexFunctions_SYSTEM_API_DO_NOT_USE +# define ucnv_setDefaultName ucnv_setDefaultName_SYSTEM_API_DO_NOT_USE +# define uloc_getDefault uloc_getDefault_SYSTEM_API_DO_NOT_USE +# define uloc_setDefault uloc_setDefault_SYSTEM_API_DO_NOT_USE +# else +# define u_cleanup_4_0 u_cleanup_SYSTEM_API_DO_NOT_USE +# define u_setAtomicIncDecFunctions_4_0 u_setAtomicIncDecFunctions_SYSTEM_API_DO_NOT_USE +# define u_setMemoryFunctions_4_0 u_setMemoryFunctions_SYSTEM_API_DO_NOT_USE +# define u_setMutexFunctions_4_0 u_setMutexFunctions_SYSTEM_API_DO_NOT_USE +# define ucnv_setDefaultName_4_0 ucnv_setDefaultName_SYSTEM_API_DO_NOT_USE +# define uloc_getDefault_4_0 uloc_getDefault_SYSTEM_API_DO_NOT_USE +# define uloc_setDefault_4_0 uloc_setDefault_SYSTEM_API_DO_NOT_USE +# endif /* U_DISABLE_RENAMING */ + +#endif /* U_HIDE_SYSTEM_API */ +#endif /* USYSTEM_H */ + diff --git a/utils/openttd/unicode/utext.h b/utils/openttd/unicode/utext.h new file mode 100644 index 00000000000..866b850390d --- /dev/null +++ b/utils/openttd/unicode/utext.h @@ -0,0 +1,1562 @@ +/* +******************************************************************************* +* +* Copyright (C) 2004-2008, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: utext.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2004oct06 +* created by: Markus W. Scherer +*/ + +#ifndef __UTEXT_H__ +#define __UTEXT_H__ + +/** + * \file + * \brief C API: Abstract Unicode Text API + * + * The Text Access API provides a means to allow text that is stored in alternative + * formats to work with ICU services. ICU normally operates on text that is + * stored in UTF-16 format, in (UChar *) arrays for the C APIs or as type + * UnicodeString for C++ APIs. + * + * ICU Text Access allows other formats, such as UTF-8 or non-contiguous + * UTF-16 strings, to be placed in a UText wrapper and then passed to ICU services. + * + * There are three general classes of usage for UText: + * + * Application Level Use. This is the simplest usage - applications would + * use one of the utext_open() functions on their input text, and pass + * the resulting UText to the desired ICU service. + * + * Second is usage in ICU Services, such as break iteration, that will need to + * operate on input presented to them as a UText. These implementations + * will need to use the iteration and related UText functions to gain + * access to the actual text. + * + * The third class of UText users are "text providers." These are the + * UText implementations for the various text storage formats. An application + * or system with a unique text storage format can implement a set of + * UText provider functions for that format, which will then allow + * ICU services to operate on that format. + * + * + * <em>Iterating over text</em> + * + * Here is sample code for a forward iteration over the contents of a UText + * + * \code + * UChar32 c; + * UText *ut = whatever(); + * + * for (c=utext_next32From(ut, 0); c>=0; c=utext_next32(ut)) { + * // do whatever with the codepoint c here. + * } + * \endcode + * + * And here is similar code to iterate in the reverse direction, from the end + * of the text towards the beginning. + * + * \code + * UChar32 c; + * UText *ut = whatever(); + * int textLength = utext_nativeLength(ut); + * for (c=utext_previous32From(ut, textLength); c>=0; c=utext_previous32(ut)) { + * // do whatever with the codepoint c here. + * } + * \endcode + * + * <em>Characters and Indexing</em> + * + * Indexing into text by UText functions is nearly always in terms of the native + * indexing of the underlying text storage. The storage format could be UTF-8 + * or UTF-32, for example. When coding to the UText access API, no assumptions + * can be made regarding the size of characters, or how far an index + * may move when iterating between characters. + * + * All indices supplied to UText functions are pinned to the length of the + * text. An out-of-bounds index is not considered to be an error, but is + * adjusted to be in the range 0 <= index <= length of input text. + * + * + * When an index position is returned from a UText function, it will be + * a native index to the underlying text. In the case of multi-unit characters, + * it will always refer to the first position of the character, + * never to the interior. This is essentially the same thing as saying that + * a returned index will always point to a boundary between characters. + * + * When a native index is supplied to a UText function, all indices that + * refer to any part of a multi-unit character representation are considered + * to be equivalent. In the case of multi-unit characters, an incoming index + * will be logically normalized to refer to the start of the character. + * + * It is possible to test whether a native index is on a code point boundary + * by doing a utext_setNativeIndex() followed by a utext_getNativeIndex(). + * If the index is returned unchanged, it was on a code point boundary. If + * an adjusted index is returned, the original index referred to the + * interior of a character. + * + * <em>Conventions for calling UText functions</em> + * + * Most UText access functions have as their first parameter a (UText *) pointer, + * which specifies the UText to be used. Unless otherwise noted, the + * pointer must refer to a valid, open UText. Attempting to + * use a closed UText or passing a NULL pointer is a programming error and + * will produce undefined results or NULL pointer exceptions. + * + * The UText_Open family of functions can either open an existing (closed) + * UText, or heap allocate a new UText. Here is sample code for creating + * a stack-allocated UText. + * + * \code + * char *s = whatever(); // A utf-8 string + * U_ErrorCode status = U_ZERO_ERROR; + * UText ut = UTEXT_INITIALIZER; + * utext_openUTF8(ut, s, -1, &status); + * if (U_FAILURE(status)) { + * // error handling + * } else { + * // work with the UText + * } + * \endcode + * + * Any existing UText passed to an open function _must_ have been initialized, + * either by the UTEXT_INITIALIZER, or by having been originally heap-allocated + * by an open function. Passing NULL will cause the open function to + * heap-allocate and fully initialize a new UText. + * + */ + + + +#include "unicode/utypes.h" +#ifdef XP_CPLUSPLUS +#include "unicode/rep.h" +#include "unicode/unistr.h" +#include "unicode/chariter.h" +#endif + + +U_CDECL_BEGIN + +struct UText; +typedef struct UText UText; /**< C typedef for struct UText. @stable ICU 3.6 */ + + +/*************************************************************************************** + * + * C Functions for creating UText wrappers around various kinds of text strings. + * + ****************************************************************************************/ + + +/** + * Close function for UText instances. + * Cleans up, releases any resources being held by an open UText. + * <p> + * If the UText was originally allocated by one of the utext_open functions, + * the storage associated with the utext will also be freed. + * If the UText storage originated with the application, as it would with + * a local or static instance, the storage will not be deleted. + * + * An open UText can be reset to refer to new string by using one of the utext_open() + * functions without first closing the UText. + * + * @param ut The UText to be closed. + * @return NULL if the UText struct was deleted by the close. If the UText struct + * was originally provided by the caller to the open function, it is + * returned by this function, and may be safely used again in + * a subsequent utext_open. + * + * @stable ICU 3.4 + */ +U_STABLE UText * U_EXPORT2 +utext_close(UText *ut); + + +/** + * Open a read-only UText implementation for UTF-8 strings. + * + * \htmlonly + * Any invalid UTF-8 in the input will be handled in this way: + * a sequence of bytes that has the form of a truncated, but otherwise valid, + * UTF-8 sequence will be replaced by a single unicode replacement character, \uFFFD. + * Any other illegal bytes will each be replaced by a \uFFFD. + * \endhtmlonly + * + * @param ut Pointer to a UText struct. If NULL, a new UText will be created. + * If non-NULL, must refer to an initialized UText struct, which will then + * be reset to reference the specified UTF-8 string. + * @param s A UTF-8 string. Must not be NULL. + * @param length The length of the UTF-8 string in bytes, or -1 if the string is + * zero terminated. + * @param status Errors are returned here. + * @return A pointer to the UText. If a pre-allocated UText was provided, it + * will always be used and returned. + * @stable ICU 3.4 + */ +U_STABLE UText * U_EXPORT2 +utext_openUTF8(UText *ut, const char *s, int64_t length, UErrorCode *status); + + +/** + * Open a read-only UText for UChar * string. + * + * @param ut Pointer to a UText struct. If NULL, a new UText will be created. + * If non-NULL, must refer to an initialized UText struct, which will then + * be reset to reference the specified UChar string. + * @param s A UChar (UTF-16) string + * @param length The number of UChars in the input string, or -1 if the string is + * zero terminated. + * @param status Errors are returned here. + * @return A pointer to the UText. If a pre-allocated UText was provided, it + * will always be used and returned. + * @stable ICU 3.4 + */ +U_STABLE UText * U_EXPORT2 +utext_openUChars(UText *ut, const UChar *s, int64_t length, UErrorCode *status); + + +#ifdef XP_CPLUSPLUS +/** + * Open a writable UText for a non-const UnicodeString. + * + * @param ut Pointer to a UText struct. If NULL, a new UText will be created. + * If non-NULL, must refer to an initialized UText struct, which will then + * be reset to reference the specified input string. + * @param s A UnicodeString. + * @param status Errors are returned here. + * @return Pointer to the UText. If a UText was supplied as input, this + * will always be used and returned. + * @stable ICU 3.4 + */ +U_STABLE UText * U_EXPORT2 +utext_openUnicodeString(UText *ut, U_NAMESPACE_QUALIFIER UnicodeString *s, UErrorCode *status); + + +/** + * Open a UText for a const UnicodeString. The resulting UText will not be writable. + * + * @param ut Pointer to a UText struct. If NULL, a new UText will be created. + * If non-NULL, must refer to an initialized UText struct, which will then + * be reset to reference the specified input string. + * @param s A const UnicodeString to be wrapped. + * @param status Errors are returned here. + * @return Pointer to the UText. If a UText was supplied as input, this + * will always be used and returned. + * @stable ICU 3.4 + */ +U_STABLE UText * U_EXPORT2 +utext_openConstUnicodeString(UText *ut, const U_NAMESPACE_QUALIFIER UnicodeString *s, UErrorCode *status); + + +/** + * Open a writable UText implementation for an ICU Replaceable object. + * @param ut Pointer to a UText struct. If NULL, a new UText will be created. + * If non-NULL, must refer to an already existing UText, which will then + * be reset to reference the specified replaceable text. + * @param rep A Replaceable text object. + * @param status Errors are returned here. + * @return Pointer to the UText. If a UText was supplied as input, this + * will always be used and returned. + * @see Replaceable + * @stable ICU 3.4 + */ +U_STABLE UText * U_EXPORT2 +utext_openReplaceable(UText *ut, U_NAMESPACE_QUALIFIER Replaceable *rep, UErrorCode *status); + +/** + * Open a UText implementation over an ICU CharacterIterator. + * @param ut Pointer to a UText struct. If NULL, a new UText will be created. + * If non-NULL, must refer to an already existing UText, which will then + * be reset to reference the specified replaceable text. + * @param ci A Character Iterator. + * @param status Errors are returned here. + * @return Pointer to the UText. If a UText was supplied as input, this + * will always be used and returned. + * @see Replaceable + * @stable ICU 3.4 + */ +U_STABLE UText * U_EXPORT2 +utext_openCharacterIterator(UText *ut, U_NAMESPACE_QUALIFIER CharacterIterator *ic, UErrorCode *status); + +#endif + + +/** + * Clone a UText. This is much like opening a UText where the source text is itself + * another UText. + * + * A deep clone will copy both the UText data structures and the underlying text. + * The original and cloned UText will operate completely independently; modifications + * made to the text in one will not affect the other. Text providers are not + * required to support deep clones. The user of clone() must check the status return + * and be prepared to handle failures. + * + * The standard UText implementations for UTF8, UChar *, UnicodeString and + * Replaceable all support deep cloning. + * + * The UText returned from a deep clone will be writable, assuming that the text + * provider is able to support writing, even if the source UText had been made + * non-writable by means of UText_freeze(). + * + * A shallow clone replicates only the UText data structures; it does not make + * a copy of the underlying text. Shallow clones can be used as an efficient way to + * have multiple iterators active in a single text string that is not being + * modified. + * + * A shallow clone operation will not fail, barring truly exceptional conditions such + * as memory allocation failures. + * + * Shallow UText clones should be avoided if the UText functions that modify the + * text are expected to be used, either on the original or the cloned UText. + * Any such modifications can cause unpredictable behavior. Read Only + * shallow clones provide some protection against errors of this type by + * disabling text modification via the cloned UText. + * + * A shallow clone made with the readOnly parameter == FALSE will preserve the + * utext_isWritable() state of the source object. Note, however, that + * write operations must be avoided while more than one UText exists that refer + * to the same underlying text. + * + * A UText and its clone may be safely concurrently accessed by separate threads. + * This is true for read access only with shallow clones, and for both read and + * write access with deep clones. + * It is the responsibility of the Text Provider to ensure that this thread safety + * constraint is met. + * + * @param dest A UText struct to be filled in with the result of the clone operation, + * or NULL if the clone function should heap-allocate a new UText struct. + * If non-NULL, must refer to an already existing UText, which will then + * be reset to become the clone. + * @param src The UText to be cloned. + * @param deep TRUE to request a deep clone, FALSE for a shallow clone. + * @param readOnly TRUE to request that the cloned UText have read only access to the + * underlying text. + + * @param status Errors are returned here. For deep clones, U_UNSUPPORTED_ERROR + * will be returned if the text provider is unable to clone the + * original text. + * @return The newly created clone, or NULL if the clone operation failed. + * @stable ICU 3.4 + */ +U_STABLE UText * U_EXPORT2 +utext_clone(UText *dest, const UText *src, UBool deep, UBool readOnly, UErrorCode *status); + + +/** + * Compare two UText objects for equality. + * UTexts are equal if they are iterating over the same text, and + * have the same iteration position within the text. + * If either or both of the parameters are NULL, the comparison is FALSE. + * + * @param a The first of the two UTexts to compare. + * @param b The other UText to be compared. + * @return TRUE if the two UTexts are equal. + * @stable ICU 3.6 + */ +U_STABLE UBool U_EXPORT2 +utext_equals(const UText *a, const UText *b); + + +/***************************************************************************** + * + * Functions to work with the text represeted by a UText wrapper + * + *****************************************************************************/ + +/** + * Get the length of the text. Depending on the characteristics + * of the underlying text representation, this may be expensive. + * @see utext_isLengthExpensive() + * + * + * @param ut the text to be accessed. + * @return the length of the text, expressed in native units. + * + * @stable ICU 3.4 + */ +U_STABLE int64_t U_EXPORT2 +utext_nativeLength(UText *ut); + +/** + * Return TRUE if calculating the length of the text could be expensive. + * Finding the length of NUL terminated strings is considered to be expensive. + * + * Note that the value of this function may change + * as the result of other operations on a UText. + * Once the length of a string has been discovered, it will no longer + * be expensive to report it. + * + * @param ut the text to be accessed. + * @return TRUE if determining the length of the text could be time consuming. + * @stable ICU 3.4 + */ +U_STABLE UBool U_EXPORT2 +utext_isLengthExpensive(const UText *ut); + +/** + * Returns the code point at the requested index, + * or U_SENTINEL (-1) if it is out of bounds. + * + * If the specified index points to the interior of a multi-unit + * character - one of the trail bytes of a UTF-8 sequence, for example - + * the complete code point will be returned. + * + * The iteration position will be set to the start of the returned code point. + * + * This function is roughly equivalent to the the sequence + * utext_setNativeIndex(index); + * utext_current32(); + * (There is a subtle difference if the index is out of bounds by being less than zero - + * utext_setNativeIndex(negative value) sets the index to zero, after which utext_current() + * will return the char at zero. utext_char32At(negative index), on the other hand, will + * return the U_SENTINEL value of -1.) + * + * @param ut the text to be accessed + * @param nativeIndex the native index of the character to be accessed. If the index points + * to other than the first unit of a multi-unit character, it will be adjusted + * to the start of the character. + * @return the code point at the specified index. + * @stable ICU 3.4 + */ +U_STABLE UChar32 U_EXPORT2 +utext_char32At(UText *ut, int64_t nativeIndex); + + +/** + * + * Get the code point at the current iteration position, + * or U_SENTINEL (-1) if the iteration has reached the end of + * the input text. + * + * @param ut the text to be accessed. + * @return the Unicode code point at the current iterator position. + * @stable ICU 3.4 + */ +U_STABLE UChar32 U_EXPORT2 +utext_current32(UText *ut); + + +/** + * Get the code point at the current iteration position of the UText, and + * advance the position to the first index following the character. + * + * If the position is at the end of the text (the index following + * the last character, which is also the length of the text), + * return U_SENTINEL (-1) and do not advance the index. + * + * This is a post-increment operation. + * + * An inline macro version of this function, UTEXT_NEXT32(), + * is available for performance critical use. + * + * @param ut the text to be accessed. + * @return the Unicode code point at the iteration position. + * @see UTEXT_NEXT32 + * @stable ICU 3.4 + */ +U_STABLE UChar32 U_EXPORT2 +utext_next32(UText *ut); + + +/** + * Move the iterator position to the character (code point) whose + * index precedes the current position, and return that character. + * This is a pre-decrement operation. + * + * If the initial position is at the start of the text (index of 0) + * return U_SENTINEL (-1), and leave the position unchanged. + * + * An inline macro version of this function, UTEXT_PREVIOUS32(), + * is available for performance critical use. + * + * @param ut the text to be accessed. + * @return the previous UChar32 code point, or U_SENTINEL (-1) + * if the iteration has reached the start of the text. + * @see UTEXT_PREVIOUS32 + * @stable ICU 3.4 + */ +U_STABLE UChar32 U_EXPORT2 +utext_previous32(UText *ut); + + +/** + * Set the iteration index and return the code point at that index. + * Leave the iteration index at the start of the following code point. + * + * This function is the most efficient and convenient way to + * begin a forward iteration. The results are identical to the those + * from the sequence + * \code + * utext_setIndex(); + * utext_next32(); + * \endcode + * + * @param ut the text to be accessed. + * @param nativeIndex Iteration index, in the native units of the text provider. + * @return Code point which starts at or before index, + * or U_SENTINEL (-1) if it is out of bounds. + * @stable ICU 3.4 + */ +U_STABLE UChar32 U_EXPORT2 +utext_next32From(UText *ut, int64_t nativeIndex); + + + +/** + * Set the iteration index, and return the code point preceding the + * one specified by the initial index. Leave the iteration position + * at the start of the returned code point. + * + * This function is the most efficient and convenient way to + * begin a backwards iteration. + * + * @param ut the text to be accessed. + * @param nativeIndex Iteration index in the native units of the text provider. + * @return Code point preceding the one at the initial index, + * or U_SENTINEL (-1) if it is out of bounds. + * + * @stable ICU 3.4 + */ +U_STABLE UChar32 U_EXPORT2 +utext_previous32From(UText *ut, int64_t nativeIndex); + +/** + * Get the current iterator position, which can range from 0 to + * the length of the text. + * The position is a native index into the input text, in whatever format it + * may have (possibly UTF-8 for example), and may not always be the same as + * the corresponding UChar (UTF-16) index. + * The returned position will always be aligned to a code point boundary. + * + * @param ut the text to be accessed. + * @return the current index position, in the native units of the text provider. + * @stable ICU 3.4 + */ +U_STABLE int64_t U_EXPORT2 +utext_getNativeIndex(const UText *ut); + +/** + * Set the current iteration position to the nearest code point + * boundary at or preceding the specified index. + * The index is in the native units of the original input text. + * If the index is out of range, it will be pinned to be within + * the range of the input text. + * <p> + * It will usually be more efficient to begin an iteration + * using the functions utext_next32From() or utext_previous32From() + * rather than setIndex(). + * <p> + * Moving the index position to an adjacent character is best done + * with utext_next32(), utext_previous32() or utext_moveIndex32(). + * Attempting to do direct arithmetic on the index position is + * complicated by the fact that the size (in native units) of a + * character depends on the underlying representation of the character + * (UTF-8, UTF-16, UTF-32, arbitrary codepage), and is not + * easily knowable. + * + * @param ut the text to be accessed. + * @param nativeIndex the native unit index of the new iteration position. + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +utext_setNativeIndex(UText *ut, int64_t nativeIndex); + +/** + * Move the iterator postion by delta code points. The number of code points + * is a signed number; a negative delta will move the iterator backwards, + * towards the start of the text. + * <p> + * The index is moved by <code>delta</code> code points + * forward or backward, but no further backward than to 0 and + * no further forward than to utext_nativeLength(). + * The resulting index value will be in between 0 and length, inclusive. + * + * @param ut the text to be accessed. + * @param delta the signed number of code points to move the iteration position. + * @return TRUE if the position could be moved the requested number of positions while + * staying within the range [0 - text length]. + * @stable ICU 3.4 + */ +U_STABLE UBool U_EXPORT2 +utext_moveIndex32(UText *ut, int32_t delta); + +/** + * Get the native index of the character preceeding the current position. + * If the iteration position is already at the start of the text, zero + * is returned. + * The value returned is the same as that obtained from the following sequence, + * but without the side effect of changing the iteration position. + * + * \code + * UText *ut = whatever; + * ... + * utext_previous(ut) + * utext_getNativeIndex(ut); + * \endcode + * + * This function is most useful during forwards iteration, where it will get the + * native index of the character most recently returned from utext_next(). + * + * @param ut the text to be accessed + * @return the native index of the character preceeding the current index position, + * or zero if the current position is at the start of the text. + * @stable ICU 3.6 + */ +U_STABLE int64_t U_EXPORT2 +utext_getPreviousNativeIndex(UText *ut); + + +/** + * + * Extract text from a UText into a UChar buffer. The range of text to be extracted + * is specified in the native indices of the UText provider. These may not necessarily + * be UTF-16 indices. + * <p> + * The size (number of 16 bit UChars) of the data to be extracted is returned. The + * full number of UChars is returned, even when the extracted text is truncated + * because the specified buffer size is too small. + * <p> + * The extracted string will (if you are a user) / must (if you are a text provider) + * be NUL-terminated if there is sufficient space in the destination buffer. This + * terminating NUL is not included in the returned length. + * <p> + * The iteration index is left at the position following the last extracted character. + * + * @param ut the UText from which to extract data. + * @param nativeStart the native index of the first character to extract.\ + * If the specified index is out of range, + * it will be pinned to to be within 0 <= index <= textLength + * @param nativeLimit the native string index of the position following the last + * character to extract. If the specified index is out of range, + * it will be pinned to to be within 0 <= index <= textLength. + * nativeLimit must be >= nativeStart. + * @param dest the UChar (UTF-16) buffer into which the extracted text is placed + * @param destCapacity The size, in UChars, of the destination buffer. May be zero + * for precomputing the required size. + * @param status receives any error status. + * U_BUFFER_OVERFLOW_ERROR: the extracted text was truncated because the + * buffer was too small. Returns number of UChars for preflighting. + * @return Number of UChars in the data to be extracted. Does not include a trailing NUL. + * + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +utext_extract(UText *ut, + int64_t nativeStart, int64_t nativeLimit, + UChar *dest, int32_t destCapacity, + UErrorCode *status); + + +/************************************************************************************ + * + * #define inline versions of selected performance-critical text access functions + * Caution: do not use auto increment++ or decrement-- expressions + * as parameters to these macros. + * + * For most use, where there is no extreme performance constraint, the + * normal, non-inline functions are a better choice. The resulting code + * will be smaller, and, if the need ever arises, easier to debug. + * + * These are implemented as #defines rather than real functions + * because there is no fully portable way to do inline functions in plain C. + * + ************************************************************************************/ + +/** + * inline version of utext_next32(), for performance-critical situations. + * + * Get the code point at the current iteration position of the UText, and + * advance the position to the first index following the character. + * This is a post-increment operation. + * Returns U_SENTINEL (-1) if the position is at the end of the + * text. + * + * @stable ICU 3.4 + */ +#define UTEXT_NEXT32(ut) \ + ((ut)->chunkOffset < (ut)->chunkLength && ((ut)->chunkContents)[(ut)->chunkOffset]<0xd800 ? \ + ((ut)->chunkContents)[((ut)->chunkOffset)++] : utext_next32(ut)) + +/** + * inline version of utext_previous32(), for performance-critical situations. + * + * Move the iterator position to the character (code point) whose + * index precedes the current position, and return that character. + * This is a pre-decrement operation. + * Returns U_SENTINEL (-1) if the position is at the start of the text. + * + * @stable ICU 3.4 + */ +#define UTEXT_PREVIOUS32(ut) \ + ((ut)->chunkOffset > 0 && \ + (ut)->chunkContents[(ut)->chunkOffset-1] < 0xd800 ? \ + (ut)->chunkContents[--((ut)->chunkOffset)] : utext_previous32(ut)) + +/** + * inline version of utext_getNativeIndex(), for performance-critical situations. + * + * Get the current iterator position, which can range from 0 to + * the length of the text. + * The position is a native index into the input text, in whatever format it + * may have (possibly UTF-8 for example), and may not always be the same as + * the corresponding UChar (UTF-16) index. + * The returned position will always be aligned to a code point boundary. + * + * @stable ICU 3.6 + */ +#define UTEXT_GETNATIVEINDEX(ut) \ + ((ut)->chunkOffset <= (ut)->nativeIndexingLimit? \ + (ut)->chunkNativeStart+(ut)->chunkOffset : \ + (ut)->pFuncs->mapOffsetToNative(ut)) + +/** + * inline version of utext_setNativeIndex(), for performance-critical situations. + * + * Set the current iteration position to the nearest code point + * boundary at or preceding the specified index. + * The index is in the native units of the original input text. + * If the index is out of range, it will be pinned to be within + * the range of the input text. + * + * @stable ICU 4.0 + */ +#define UTEXT_SETNATIVEINDEX(ut, ix) \ + { int64_t __offset = (ix) - (ut)->chunkNativeStart; \ + if (__offset>=0 && __offset<=(int64_t)(ut)->nativeIndexingLimit) { \ + (ut)->chunkOffset=(int32_t)__offset; \ + } else { \ + utext_setNativeIndex((ut), (ix)); } } + + + +/************************************************************************************ + * + * Functions related to writing or modifying the text. + * These will work only with modifiable UTexts. Attempting to + * modify a read-only UText will return an error status. + * + ************************************************************************************/ + + +/** + * Return TRUE if the text can be written (modified) with utext_replace() or + * utext_copy(). For the text to be writable, the text provider must + * be of a type that supports writing and the UText must not be frozen. + * + * Attempting to modify text when utext_isWriteable() is FALSE will fail - + * the text will not be modified, and an error will be returned from the function + * that attempted the modification. + * + * @param ut the UText to be tested. + * @return TRUE if the text is modifiable. + * + * @see utext_freeze() + * @see utext_replace() + * @see utext_copy() + * @stable ICU 3.4 + * + */ +U_STABLE UBool U_EXPORT2 +utext_isWritable(const UText *ut); + + +/** + * Test whether there is meta data associated with the text. + * @see Replaceable::hasMetaData() + * + * @param ut The UText to be tested + * @return TRUE if the underlying text includes meta data. + * @stable ICU 3.4 + */ +U_STABLE UBool U_EXPORT2 +utext_hasMetaData(const UText *ut); + + +/** + * Replace a range of the original text with a replacement text. + * + * Leaves the current iteration position at the position following the + * newly inserted replacement text. + * + * This function is only available on UText types that support writing, + * that is, ones where utext_isWritable() returns TRUE. + * + * When using this function, there should be only a single UText opened onto the + * underlying native text string. Behavior after a replace operation + * on a UText is undefined for any other additional UTexts that refer to the + * modified string. + * + * @param ut the UText representing the text to be operated on. + * @param nativeStart the native index of the start of the region to be replaced + * @param nativeLimit the native index of the character following the region to be replaced. + * @param replacementText pointer to the replacement text + * @param replacementLength length of the replacement text, or -1 if the text is NUL terminated. + * @param status receives any error status. Possible errors include + * U_NO_WRITE_PERMISSION + * + * @return The signed number of (native) storage units by which + * the length of the text expanded or contracted. + * + * @stable ICU 3.4 + */ +U_STABLE int32_t U_EXPORT2 +utext_replace(UText *ut, + int64_t nativeStart, int64_t nativeLimit, + const UChar *replacementText, int32_t replacementLength, + UErrorCode *status); + + + +/** + * + * Copy or move a substring from one position to another within the text, + * while retaining any metadata associated with the text. + * This function is used to duplicate or reorder substrings. + * The destination index must not overlap the source range. + * + * The text to be copied or moved is inserted at destIndex; + * it does not replace or overwrite any existing text. + * + * The iteration position is left following the newly inserted text + * at the destination position. + * + * This function is only available on UText types that support writing, + * that is, ones where utext_isWritable() returns TRUE. + * + * When using this function, there should be only a single UText opened onto the + * underlying native text string. Behavior after a copy operation + * on a UText is undefined in any other additional UTexts that refer to the + * modified string. + * + * @param ut The UText representing the text to be operated on. + * @param nativeStart The native index of the start of the region to be copied or moved + * @param nativeLimit The native index of the character position following the region + * to be copied. + * @param destIndex The native destination index to which the source substring is + * copied or moved. + * @param move If TRUE, then the substring is moved, not copied/duplicated. + * @param status receives any error status. Possible errors include U_NO_WRITE_PERMISSION + * + * @stable ICU 3.4 + */ +U_STABLE void U_EXPORT2 +utext_copy(UText *ut, + int64_t nativeStart, int64_t nativeLimit, + int64_t destIndex, + UBool move, + UErrorCode *status); + + +/** + * <p> + * Freeze a UText. This prevents any modification to the underlying text itself + * by means of functions operating on this UText. + * </p> + * <p> + * Once frozen, a UText can not be unfrozen. The intent is to ensure + * that a the text underlying a frozen UText wrapper cannot be modified via that UText. + * </p> + * <p> + * Caution: freezing a UText will disable changes made via the specific + * frozen UText wrapper only; it will not have any effect on the ability to + * directly modify the text by bypassing the UText. Any such backdoor modifications + * are always an error while UText access is occuring because the underlying + * text can get out of sync with UText's buffering. + * </p> + * + * @param ut The UText to be frozen. + * @see utext_isWritable() + * @stable ICU 3.6 + */ +U_STABLE void U_EXPORT2 +utext_freeze(UText *ut); + + +/** + * UText provider properties (bit field indexes). + * + * @see UText + * @stable ICU 3.4 + */ +enum { + /** + * It is potentially time consuming for the provider to determine the length of the text. + * @stable ICU 3.4 + */ + UTEXT_PROVIDER_LENGTH_IS_EXPENSIVE = 1, + /** + * Text chunks remain valid and usable until the text object is modified or + * deleted, not just until the next time the access() function is called + * (which is the default). + * @stable ICU 3.4 + */ + UTEXT_PROVIDER_STABLE_CHUNKS = 2, + /** + * The provider supports modifying the text via the replace() and copy() + * functions. + * @see Replaceable + * @stable ICU 3.4 + */ + UTEXT_PROVIDER_WRITABLE = 3, + /** + * There is meta data associated with the text. + * @see Replaceable::hasMetaData() + * @stable ICU 3.4 + */ + UTEXT_PROVIDER_HAS_META_DATA = 4, + /** + * Text provider owns the text storage. + * Generally occurs as the result of a deep clone of the UText. + * When closing the UText, the associated text must + * also be closed/deleted/freed/ whatever is appropriate. + * @stable ICU 3.6 + */ + UTEXT_PROVIDER_OWNS_TEXT = 5 +}; + +/** + * Function type declaration for UText.clone(). + * + * clone a UText. Much like opening a UText where the source text is itself + * another UText. + * + * A deep clone will copy both the UText data structures and the underlying text. + * The original and cloned UText will operate completely independently; modifications + * made to the text in one will not effect the other. Text providers are not + * required to support deep clones. The user of clone() must check the status return + * and be prepared to handle failures. + * + * A shallow clone replicates only the UText data structures; it does not make + * a copy of the underlying text. Shallow clones can be used as an efficient way to + * have multiple iterators active in a single text string that is not being + * modified. + * + * A shallow clone operation must not fail except for truly exceptional conditions such + * as memory allocation failures. + * + * A UText and its clone may be safely concurrently accessed by separate threads. + * This is true for both shallow and deep clones. + * It is the responsibility of the Text Provider to ensure that this thread safety + * constraint is met. + + * + * @param dest A UText struct to be filled in with the result of the clone operation, + * or NULL if the clone function should heap-allocate a new UText struct. + * @param src The UText to be cloned. + * @param deep TRUE to request a deep clone, FALSE for a shallow clone. + * @param status Errors are returned here. For deep clones, U_UNSUPPORTED_ERROR + * should be returned if the text provider is unable to clone the + * original text. + * @return The newly created clone, or NULL if the clone operation failed. + * + * @stable ICU 3.4 + */ +typedef UText * U_CALLCONV +UTextClone(UText *dest, const UText *src, UBool deep, UErrorCode *status); + + +/** + * Function type declaration for UText.nativeLength(). + * + * @param ut the UText to get the length of. + * @return the length, in the native units of the original text string. + * @see UText + * @stable ICU 3.4 + */ +typedef int64_t U_CALLCONV +UTextNativeLength(UText *ut); + +/** + * Function type declaration for UText.access(). Get the description of the text chunk + * containing the text at a requested native index. The UText's iteration + * position will be left at the requested index. If the index is out + * of bounds, the iteration position will be left at the start or end + * of the string, as appropriate. + * + * Chunks must begin and end on code point boundaries. A single code point + * comprised of multiple storage units must never span a chunk boundary. + * + * + * @param ut the UText being accessed. + * @param nativeIndex Requested index of the text to be accessed. + * @param forward If TRUE, then the returned chunk must contain text + * starting from the index, so that start<=index<limit. + * If FALSE, then the returned chunk must contain text + * before the index, so that start<index<=limit. + * @return True if the requested index could be accessed. The chunk + * will contain the requested text. + * False value if a chunk cannot be accessed + * (the requested index is out of bounds). + * + * @see UText + * @stable ICU 3.4 + */ +typedef UBool U_CALLCONV +UTextAccess(UText *ut, int64_t nativeIndex, UBool forward); + +/** + * Function type declaration for UText.extract(). + * + * Extract text from a UText into a UChar buffer. The range of text to be extracted + * is specified in the native indices of the UText provider. These may not necessarily + * be UTF-16 indices. + * <p> + * The size (number of 16 bit UChars) in the data to be extracted is returned. The + * full amount is returned, even when the specified buffer size is smaller. + * <p> + * The extracted string will (if you are a user) / must (if you are a text provider) + * be NUL-terminated if there is sufficient space in the destination buffer. + * + * @param ut the UText from which to extract data. + * @param nativeStart the native index of the first characer to extract. + * @param nativeLimit the native string index of the position following the last + * character to extract. + * @param dest the UChar (UTF-16) buffer into which the extracted text is placed + * @param destCapacity The size, in UChars, of the destination buffer. May be zero + * for precomputing the required size. + * @param status receives any error status. + * If U_BUFFER_OVERFLOW_ERROR: Returns number of UChars for + * preflighting. + * @return Number of UChars in the data. Does not include a trailing NUL. + * + * @stable ICU 3.4 + */ +typedef int32_t U_CALLCONV +UTextExtract(UText *ut, + int64_t nativeStart, int64_t nativeLimit, + UChar *dest, int32_t destCapacity, + UErrorCode *status); + +/** + * Function type declaration for UText.replace(). + * + * Replace a range of the original text with a replacement text. + * + * Leaves the current iteration position at the position following the + * newly inserted replacement text. + * + * This function need only be implemented on UText types that support writing. + * + * When using this function, there should be only a single UText opened onto the + * underlying native text string. The function is responsible for updating the + * text chunk within the UText to reflect the updated iteration position, + * taking into account any changes to the underlying string's structure caused + * by the replace operation. + * + * @param ut the UText representing the text to be operated on. + * @param nativeStart the index of the start of the region to be replaced + * @param nativeLimit the index of the character following the region to be replaced. + * @param replacementText pointer to the replacement text + * @param replacmentLength length of the replacement text in UChars, or -1 if the text is NUL terminated. + * @param status receives any error status. Possible errors include + * U_NO_WRITE_PERMISSION + * + * @return The signed number of (native) storage units by which + * the length of the text expanded or contracted. + * + * @stable ICU 3.4 + */ +typedef int32_t U_CALLCONV +UTextReplace(UText *ut, + int64_t nativeStart, int64_t nativeLimit, + const UChar *replacementText, int32_t replacmentLength, + UErrorCode *status); + +/** + * Function type declaration for UText.copy(). + * + * Copy or move a substring from one position to another within the text, + * while retaining any metadata associated with the text. + * This function is used to duplicate or reorder substrings. + * The destination index must not overlap the source range. + * + * The text to be copied or moved is inserted at destIndex; + * it does not replace or overwrite any existing text. + * + * This function need only be implemented for UText types that support writing. + * + * When using this function, there should be only a single UText opened onto the + * underlying native text string. The function is responsible for updating the + * text chunk within the UText to reflect the updated iteration position, + * taking into account any changes to the underlying string's structure caused + * by the replace operation. + * + * @param ut The UText representing the text to be operated on. + * @param nativeStart The index of the start of the region to be copied or moved + * @param nativeLimit The index of the character following the region to be replaced. + * @param nativeDest The destination index to which the source substring is copied or moved. + * @param move If TRUE, then the substring is moved, not copied/duplicated. + * @param status receives any error status. Possible errors include U_NO_WRITE_PERMISSION + * + * @stable ICU 3.4 + */ +typedef void U_CALLCONV +UTextCopy(UText *ut, + int64_t nativeStart, int64_t nativeLimit, + int64_t nativeDest, + UBool move, + UErrorCode *status); + +/** + * Function type declaration for UText.mapOffsetToNative(). + * Map from the current UChar offset within the current text chunk to + * the corresponding native index in the original source text. + * + * This is required only for text providers that do not use native UTF-16 indexes. + * + * @param ut the UText. + * @return Absolute (native) index corresponding to chunkOffset in the current chunk. + * The returned native index should always be to a code point boundary. + * + * @stable ICU 3.4 + */ +typedef int64_t U_CALLCONV +UTextMapOffsetToNative(const UText *ut); + +/** + * Function type declaration for UText.mapIndexToUTF16(). + * Map from a native index to a UChar offset within a text chunk. + * Behavior is undefined if the native index does not fall within the + * current chunk. + * + * This function is required only for text providers that do not use native UTF-16 indexes. + * + * @param ut The UText containing the text chunk. + * @param nativeIndex Absolute (native) text index, chunk->start<=index<=chunk->limit. + * @return Chunk-relative UTF-16 offset corresponding to the specified native + * index. + * + * @stable ICU 3.4 + */ +typedef int32_t U_CALLCONV +UTextMapNativeIndexToUTF16(const UText *ut, int64_t nativeIndex); + + +/** + * Function type declaration for UText.utextClose(). + * + * A Text Provider close function is only required for provider types that make + * allocations in their open function (or other functions) that must be + * cleaned when the UText is closed. + * + * The allocation of the UText struct itself and any "extra" storage + * associated with the UText is handled by the common UText implementation + * and does not require provider specific cleanup in a close function. + * + * Most UText provider implementations do not need to implement this function. + * + * @param ut A UText object to be closed. + * + * @stable ICU 3.4 + */ +typedef void U_CALLCONV +UTextClose(UText *ut); + + +/** + * (public) Function dispatch table for UText. + * Conceptually very much like a C++ Virtual Function Table. + * This struct defines the organization of the table. + * Each text provider implementation must provide an + * actual table that is initialized with the appropriate functions + * for the type of text being handled. + * @stable ICU 3.6 + */ +struct UTextFuncs { + /** + * (public) Function table size, sizeof(UTextFuncs) + * Intended for use should the table grow to accomodate added + * functions in the future, to allow tests for older format + * function tables that do not contain the extensions. + * + * Fields are placed for optimal alignment on + * 32/64/128-bit-pointer machines, by normally grouping together + * 4 32-bit fields, + * 4 pointers, + * 2 64-bit fields + * in sequence. + * @stable ICU 3.6 + */ + int32_t tableSize; + + /** + * (private) Alignment padding. + * Do not use, reserved for use by the UText framework only. + * @internal + */ + int32_t reserved1, /** @internal */ reserved2, /** @internal */ reserved3; + + + /** + * (public) Function pointer for UTextClone + * + * @see UTextClone + * @stable ICU 3.6 + */ + UTextClone *clone; + + /** + * (public) function pointer for UTextLength + * May be expensive to compute! + * + * @see UTextLength + * @stable ICU 3.6 + */ + UTextNativeLength *nativeLength; + + /** + * (public) Function pointer for UTextAccess. + * + * @see UTextAccess + * @stable ICU 3.6 + */ + UTextAccess *access; + + /** + * (public) Function pointer for UTextExtract. + * + * @see UTextExtract + * @stable ICU 3.6 + */ + UTextExtract *extract; + + /** + * (public) Function pointer for UTextReplace. + * + * @see UTextReplace + * @stable ICU 3.6 + */ + UTextReplace *replace; + + /** + * (public) Function pointer for UTextCopy. + * + * @see UTextCopy + * @stable ICU 3.6 + */ + UTextCopy *copy; + + /** + * (public) Function pointer for UTextMapOffsetToNative. + * + * @see UTextMapOffsetToNative + * @stable ICU 3.6 + */ + UTextMapOffsetToNative *mapOffsetToNative; + + /** + * (public) Function pointer for UTextMapNativeIndexToUTF16. + * + * @see UTextMapNativeIndexToUTF16 + * @stable ICU 3.6 + */ + UTextMapNativeIndexToUTF16 *mapNativeIndexToUTF16; + + /** + * (public) Function pointer for UTextClose. + * + * @see UTextClose + * @stable ICU 3.6 + */ + UTextClose *close; + + /** + * (private) Spare function pointer + * @internal + */ + + UTextClose *spare1; + /** + * (private) Spare function pointer + * @internal + */ + UTextClose *spare2; + + /** + * (private) Spare function pointer + * @internal + */ + UTextClose *spare3; + +}; +/** + * Function dispatch table for UText + * @see UTextFuncs + */ +typedef struct UTextFuncs UTextFuncs; + + /** + * UText struct. Provides the interface between the generic UText access code + * and the UText provider code that works on specific kinds of + * text (UTF-8, noncontiguous UTF-16, whatever.) + * + * Applications that are using predefined types of text providers + * to pass text data to ICU services will have no need to view the + * internals of the UText structs that they open. + * + * @stable ICU 3.6 + */ +struct UText { + /** + * (private) Magic. Used to help detect when UText functions are handed + * invalid or unitialized UText structs. + * utext_openXYZ() functions take an initialized, + * but not necessarily open, UText struct as an + * optional fill-in parameter. This magic field + * is used to check for that initialization. + * Text provider close functions must NOT clear + * the magic field because that would prevent + * reuse of the UText struct. + * @internal + */ + uint32_t magic; + + + /** + * (private) Flags for managing the allocation and freeing of + * memory associated with this UText. + * @internal + */ + int32_t flags; + + + /** + * Text provider properties. This set of flags is maintainted by the + * text provider implementation. + * @stable ICU 3.4 + */ + int32_t providerProperties; + + /** + * (public) sizeOfStruct=sizeof(UText) + * Allows possible backward compatible extension. + * + * @stable ICU 3.4 + */ + int32_t sizeOfStruct; + + /* ------ 16 byte alignment boundary ----------- */ + + + /** + * (protected) Native index of the first character position following + * the current chunk. + * @stable ICU 3.6 + */ + int64_t chunkNativeLimit; + + /** + * (protected) Size in bytes of the extra space (pExtra). + * @stable ICU 3.4 + */ + int32_t extraSize; + + /** + * (protected) The highest chunk offset where native indexing and + * chunk (UTF-16) indexing correspond. For UTF-16 sources, value + * will be equal to chunkLength. + * + * @stable ICU 3.6 + */ + int32_t nativeIndexingLimit; + + /* ---- 16 byte alignment boundary------ */ + + /** + * (protected) Native index of the first character in the text chunk. + * @stable ICU 3.6 + */ + int64_t chunkNativeStart; + + /** + * (protected) Current iteration position within the text chunk (UTF-16 buffer). + * This is the index to the character that will be returned by utext_next32(). + * @stable ICU 3.6 + */ + int32_t chunkOffset; + + /** + * (protected) Length the text chunk (UTF-16 buffer), in UChars. + * @stable ICU 3.6 + */ + int32_t chunkLength; + + /* ---- 16 byte alignment boundary-- */ + + + /** + * (protected) pointer to a chunk of text in UTF-16 format. + * May refer either to original storage of the source of the text, or + * if conversion was required, to a buffer owned by the UText. + * @stable ICU 3.6 + */ + const UChar *chunkContents; + + /** + * (public) Pointer to Dispatch table for accessing functions for this UText. + * @stable ICU 3.6 + */ + const UTextFuncs *pFuncs; + + /** + * (protected) Pointer to additional space requested by the + * text provider during the utext_open operation. + * @stable ICU 3.4 + */ + void *pExtra; + + /** + * (protected) Pointer to string or text-containin object or similar. + * This is the source of the text that this UText is wrapping, in a format + * that is known to the text provider functions. + * @stable ICU 3.4 + */ + const void *context; + + /* --- 16 byte alignment boundary--- */ + + /** + * (protected) Pointer fields available for use by the text provider. + * Not used by UText common code. + * @stable ICU 3.6 + */ + const void *p; + /** + * (protected) Pointer fields available for use by the text provider. + * Not used by UText common code. + * @stable ICU 3.6 + */ + const void *q; + /** + * (protected) Pointer fields available for use by the text provider. + * Not used by UText common code. + * @stable ICU 3.6 + */ + const void *r; + + /** + * Private field reserved for future use by the UText framework + * itself. This is not to be touched by the text providers. + * @internal ICU 3.4 + */ + void *privP; + + + /* --- 16 byte alignment boundary--- */ + + + /** + * (protected) Integer field reserved for use by the text provider. + * Not used by the UText framework, or by the client (user) of the UText. + * @stable ICU 3.4 + */ + int64_t a; + + /** + * (protected) Integer field reserved for use by the text provider. + * Not used by the UText framework, or by the client (user) of the UText. + * @stable ICU 3.4 + */ + int32_t b; + + /** + * (protected) Integer field reserved for use by the text provider. + * Not used by the UText framework, or by the client (user) of the UText. + * @stable ICU 3.4 + */ + int32_t c; + + /* ---- 16 byte alignment boundary---- */ + + + /** + * Private field reserved for future use by the UText framework + * itself. This is not to be touched by the text providers. + * @internal ICU 3.4 + */ + int64_t privA; + /** + * Private field reserved for future use by the UText framework + * itself. This is not to be touched by the text providers. + * @internal ICU 3.4 + */ + int32_t privB; + /** + * Private field reserved for future use by the UText framework + * itself. This is not to be touched by the text providers. + * @internal ICU 3.4 + */ + int32_t privC; +}; + + +/** + * Common function for use by Text Provider implementations to allocate and/or initialize + * a new UText struct. To be called in the implementation of utext_open() functions. + * If the supplied UText parameter is null, a new UText struct will be allocated on the heap. + * If the supplied UText is already open, the provider's close function will be called + * so that the struct can be reused by the open that is in progress. + * + * @param ut pointer to a UText struct to be re-used, or null if a new UText + * should be allocated. + * @param extraSpace The amount of additional space to be allocated as part + * of this UText, for use by types of providers that require + * additional storage. + * @param status Errors are returned here. + * @return pointer to the UText, allocated if necessary, with extra space set up if requested. + * @stable ICU 3.4 + */ +U_STABLE UText * U_EXPORT2 +utext_setup(UText *ut, int32_t extraSpace, UErrorCode *status); + +/** + * @internal + * Value used to help identify correctly initialized UText structs. + * Note: must be publicly visible so that UTEXT_INITIALIZER can access it. + */ +enum { + UTEXT_MAGIC = 0x345ad82c +}; + +/** + * initializer to be used with local (stack) instances of a UText + * struct. UText structs must be initialized before passing + * them to one of the utext_open functions. + * + * @stable ICU 3.6 + */ +#define UTEXT_INITIALIZER { \ + UTEXT_MAGIC, /* magic */ \ + 0, /* flags */ \ + 0, /* providerProps */ \ + sizeof(UText), /* sizeOfStruct */ \ + 0, /* chunkNativeLimit */ \ + 0, /* extraSize */ \ + 0, /* nativeIndexingLimit */ \ + 0, /* chunkNativeStart */ \ + 0, /* chunkOffset */ \ + 0, /* chunkLength */ \ + NULL, /* chunkContents */ \ + NULL, /* pFuncs */ \ + NULL, /* pExtra */ \ + NULL, /* context */ \ + NULL, NULL, NULL, /* p, q, r */ \ + NULL, /* privP */ \ + 0, 0, 0, /* a, b, c */ \ + 0, 0, 0 /* privA,B,C, */ \ + } + + +U_CDECL_END + + + +#endif diff --git a/utils/openttd/unicode/utf.h b/utils/openttd/unicode/utf.h new file mode 100644 index 00000000000..1682283cc6d --- /dev/null +++ b/utils/openttd/unicode/utf.h @@ -0,0 +1,227 @@ +/* +******************************************************************************* +* +* Copyright (C) 1999-2007, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: utf.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 1999sep09 +* created by: Markus W. Scherer +*/ + +/** + * \file + * \brief C API: Code point macros + * + * This file defines macros for checking whether a code point is + * a surrogate or a non-character etc. + * + * The UChar and UChar32 data types for Unicode code units and code points + * are defined in umachines.h because they can be machine-dependent. + * + * utf.h is included by utypes.h and itself includes utf8.h and utf16.h after some + * common definitions. Those files define macros for efficiently getting code points + * in and out of UTF-8/16 strings. + * utf16.h macros have "U16_" prefixes. + * utf8.h defines similar macros with "U8_" prefixes for UTF-8 string handling. + * + * ICU processes 16-bit Unicode strings. + * Most of the time, such strings are well-formed UTF-16. + * Single, unpaired surrogates must be handled as well, and are treated in ICU + * like regular code points where possible. + * (Pairs of surrogate code points are indistinguishable from supplementary + * code points encoded as pairs of supplementary code units.) + * + * In fact, almost all Unicode code points in normal text (>99%) + * are on the BMP (<=U+ffff) and even <=U+d7ff. + * ICU functions handle supplementary code points (U+10000..U+10ffff) + * but are optimized for the much more frequently occurring BMP code points. + * + * utf.h defines UChar to be an unsigned 16-bit integer. If this matches wchar_t, then + * UChar is defined to be exactly wchar_t, otherwise uint16_t. + * + * UChar32 is defined to be a signed 32-bit integer (int32_t), large enough for a 21-bit + * Unicode code point (Unicode scalar value, 0..0x10ffff). + * Before ICU 2.4, the definition of UChar32 was similarly platform-dependent as + * the definition of UChar. For details see the documentation for UChar32 itself. + * + * utf.h also defines a small number of C macros for single Unicode code points. + * These are simple checks for surrogates and non-characters. + * For actual Unicode character properties see uchar.h. + * + * By default, string operations must be done with error checking in case + * a string is not well-formed UTF-16. + * The macros will detect if a surrogate code unit is unpaired + * (lead unit without trail unit or vice versa) and just return the unit itself + * as the code point. + * (It is an accidental property of Unicode and UTF-16 that all + * malformed sequences can be expressed unambiguously with a distinct subrange + * of Unicode code points.) + * + * The regular "safe" macros require that the initial, passed-in string index + * is within bounds. They only check the index when they read more than one + * code unit. This is usually done with code similar to the following loop: + * <pre>while(i<length) { + * U16_NEXT(s, i, length, c); + * // use c + * }</pre> + * + * When it is safe to assume that text is well-formed UTF-16 + * (does not contain single, unpaired surrogates), then one can use + * U16_..._UNSAFE macros. + * These do not check for proper code unit sequences or truncated text and may + * yield wrong results or even cause a crash if they are used with "malformed" + * text. + * In practice, U16_..._UNSAFE macros will produce slightly less code but + * should not be faster because the processing is only different when a + * surrogate code unit is detected, which will be rare. + * + * Similarly for UTF-8, there are "safe" macros without a suffix, + * and U8_..._UNSAFE versions. + * The performance differences are much larger here because UTF-8 provides so + * many opportunities for malformed sequences. + * The unsafe UTF-8 macros are entirely implemented inside the macro definitions + * and are fast, while the safe UTF-8 macros call functions for all but the + * trivial (ASCII) cases. + * (ICU 3.6 optimizes U8_NEXT() and U8_APPEND() to handle most other common + * characters inline as well.) + * + * Unlike with UTF-16, malformed sequences cannot be expressed with distinct + * code point values (0..U+10ffff). They are indicated with negative values instead. + * + * For more information see the ICU User Guide Strings chapter + * (http://icu-project.org/userguide/strings.html). + * + * <em>Usage:</em> + * ICU coding guidelines for if() statements should be followed when using these macros. + * Compound statements (curly braces {}) must be used for if-else-while... + * bodies and all macro statements should be terminated with semicolon. + * + * @stable ICU 2.4 + */ + +#ifndef __UTF_H__ +#define __UTF_H__ + +#include "unicode/utypes.h" +/* include the utfXX.h after the following definitions */ + +/* single-code point definitions -------------------------------------------- */ + +/** + * This value is intended for sentinel values for APIs that + * (take or) return single code points (UChar32). + * It is outside of the Unicode code point range 0..0x10ffff. + * + * For example, a "done" or "error" value in a new API + * could be indicated with U_SENTINEL. + * + * ICU APIs designed before ICU 2.4 usually define service-specific "done" + * values, mostly 0xffff. + * Those may need to be distinguished from + * actual U+ffff text contents by calling functions like + * CharacterIterator::hasNext() or UnicodeString::length(). + * + * @return -1 + * @see UChar32 + * @stable ICU 2.4 + */ +#define U_SENTINEL (-1) + +/** + * Is this code point a Unicode noncharacter? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U_IS_UNICODE_NONCHAR(c) \ + ((c)>=0xfdd0 && \ + ((uint32_t)(c)<=0xfdef || ((c)&0xfffe)==0xfffe) && \ + (uint32_t)(c)<=0x10ffff) + +/** + * Is c a Unicode code point value (0..U+10ffff) + * that can be assigned a character? + * + * Code points that are not characters include: + * - single surrogate code points (U+d800..U+dfff, 2048 code points) + * - the last two code points on each plane (U+__fffe and U+__ffff, 34 code points) + * - U+fdd0..U+fdef (new with Unicode 3.1, 32 code points) + * - the highest Unicode code point value is U+10ffff + * + * This means that all code points below U+d800 are character code points, + * and that boundary is tested first for performance. + * + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U_IS_UNICODE_CHAR(c) \ + ((uint32_t)(c)<0xd800 || \ + ((uint32_t)(c)>0xdfff && \ + (uint32_t)(c)<=0x10ffff && \ + !U_IS_UNICODE_NONCHAR(c))) + +/** + * Is this code point a BMP code point (U+0000..U+ffff)? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.8 + */ +#define U_IS_BMP(c) ((uint32_t)(c)<=0xffff) + +/** + * Is this code point a supplementary code point (U+10000..U+10ffff)? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.8 + */ +#define U_IS_SUPPLEMENTARY(c) ((uint32_t)((c)-0x10000)<=0xfffff) + +/** + * Is this code point a lead surrogate (U+d800..U+dbff)? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U_IS_LEAD(c) (((c)&0xfffffc00)==0xd800) + +/** + * Is this code point a trail surrogate (U+dc00..U+dfff)? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00) + +/** + * Is this code point a surrogate (U+d800..U+dfff)? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800) + +/** + * Assuming c is a surrogate code point (U_IS_SURROGATE(c)), + * is it a lead surrogate? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U_IS_SURROGATE_LEAD(c) (((c)&0x400)==0) + +/* include the utfXX.h ------------------------------------------------------ */ + +#include "unicode/utf8.h" +#include "unicode/utf16.h" + +/* utf_old.h contains deprecated, pre-ICU 2.4 definitions */ +#include "unicode/utf_old.h" + +#endif diff --git a/utils/openttd/unicode/utf16.h b/utils/openttd/unicode/utf16.h new file mode 100644 index 00000000000..719bc043bb2 --- /dev/null +++ b/utils/openttd/unicode/utf16.h @@ -0,0 +1,605 @@ +/* +******************************************************************************* +* +* Copyright (C) 1999-2007, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: utf16.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 1999sep09 +* created by: Markus W. Scherer +*/ + +/** + * \file + * \brief C API: 16-bit Unicode handling macros + * + * This file defines macros to deal with 16-bit Unicode (UTF-16) code units and strings. + * utf16.h is included by utf.h after unicode/umachine.h + * and some common definitions. + * + * For more information see utf.h and the ICU User Guide Strings chapter + * (http://icu-project.org/userguide/strings.html). + * + * <em>Usage:</em> + * ICU coding guidelines for if() statements should be followed when using these macros. + * Compound statements (curly braces {}) must be used for if-else-while... + * bodies and all macro statements should be terminated with semicolon. + */ + +#ifndef __UTF16_H__ +#define __UTF16_H__ + +/* utf.h must be included first. */ +#ifndef __UTF_H__ +# include "unicode/utf.h" +#endif + +/* single-code point definitions -------------------------------------------- */ + +/** + * Does this code unit alone encode a code point (BMP, not a surrogate)? + * @param c 16-bit code unit + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c) + +/** + * Is this code unit a lead surrogate (U+d800..U+dbff)? + * @param c 16-bit code unit + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800) + +/** + * Is this code unit a trail surrogate (U+dc00..U+dfff)? + * @param c 16-bit code unit + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00) + +/** + * Is this code unit a surrogate (U+d800..U+dfff)? + * @param c 16-bit code unit + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c) + +/** + * Assuming c is a surrogate code point (U16_IS_SURROGATE(c)), + * is it a lead surrogate? + * @param c 16-bit code unit + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0) + +/** + * Helper constant for U16_GET_SUPPLEMENTARY. + * @internal + */ +#define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000) + +/** + * Get a supplementary code point value (U+10000..U+10ffff) + * from its lead and trail surrogates. + * The result is undefined if the input values are not + * lead and trail surrogates. + * + * @param lead lead surrogate (U+d800..U+dbff) + * @param trail trail surrogate (U+dc00..U+dfff) + * @return supplementary code point (U+10000..U+10ffff) + * @stable ICU 2.4 + */ +#define U16_GET_SUPPLEMENTARY(lead, trail) \ + (((UChar32)(lead)<<10UL)+(UChar32)(trail)-U16_SURROGATE_OFFSET) + + +/** + * Get the lead surrogate (0xd800..0xdbff) for a + * supplementary code point (0x10000..0x10ffff). + * @param supplementary 32-bit code point (U+10000..U+10ffff) + * @return lead surrogate (U+d800..U+dbff) for supplementary + * @stable ICU 2.4 + */ +#define U16_LEAD(supplementary) (UChar)(((supplementary)>>10)+0xd7c0) + +/** + * Get the trail surrogate (0xdc00..0xdfff) for a + * supplementary code point (0x10000..0x10ffff). + * @param supplementary 32-bit code point (U+10000..U+10ffff) + * @return trail surrogate (U+dc00..U+dfff) for supplementary + * @stable ICU 2.4 + */ +#define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00) + +/** + * How many 16-bit code units are used to encode this Unicode code point? (1 or 2) + * The result is not defined if c is not a Unicode code point (U+0000..U+10ffff). + * @param c 32-bit code point + * @return 1 or 2 + * @stable ICU 2.4 + */ +#define U16_LENGTH(c) ((uint32_t)(c)<=0xffff ? 1 : 2) + +/** + * The maximum number of 16-bit code units per Unicode code point (U+0000..U+10ffff). + * @return 2 + * @stable ICU 2.4 + */ +#define U16_MAX_LENGTH 2 + +/** + * Get a code point from a string at a random-access offset, + * without changing the offset. + * "Unsafe" macro, assumes well-formed UTF-16. + * + * The offset may point to either the lead or trail surrogate unit + * for a supplementary code point, in which case the macro will read + * the adjacent matching surrogate as well. + * The result is undefined if the offset points to a single, unpaired surrogate. + * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT. + * + * @param s const UChar * string + * @param i string offset + * @param c output UChar32 variable + * @see U16_GET + * @stable ICU 2.4 + */ +#define U16_GET_UNSAFE(s, i, c) { \ + (c)=(s)[i]; \ + if(U16_IS_SURROGATE(c)) { \ + if(U16_IS_SURROGATE_LEAD(c)) { \ + (c)=U16_GET_SUPPLEMENTARY((c), (s)[(i)+1]); \ + } else { \ + (c)=U16_GET_SUPPLEMENTARY((s)[(i)-1], (c)); \ + } \ + } \ +} + +/** + * Get a code point from a string at a random-access offset, + * without changing the offset. + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * The offset may point to either the lead or trail surrogate unit + * for a supplementary code point, in which case the macro will read + * the adjacent matching surrogate as well. + * If the offset points to a single, unpaired surrogate, then that itself + * will be returned as the code point. + * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT. + * + * @param s const UChar * string + * @param start starting string offset (usually 0) + * @param i string offset, must be start<=i<length + * @param length string length + * @param c output UChar32 variable + * @see U16_GET_UNSAFE + * @stable ICU 2.4 + */ +#define U16_GET(s, start, i, length, c) { \ + (c)=(s)[i]; \ + if(U16_IS_SURROGATE(c)) { \ + uint16_t __c2; \ + if(U16_IS_SURROGATE_LEAD(c)) { \ + if((i)+1<(length) && U16_IS_TRAIL(__c2=(s)[(i)+1])) { \ + (c)=U16_GET_SUPPLEMENTARY((c), __c2); \ + } \ + } else { \ + if((i)-1>=(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \ + (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \ + } \ + } \ + } \ +} + +/* definitions with forward iteration --------------------------------------- */ + +/** + * Get a code point from a string at a code point boundary offset, + * and advance the offset to the next code point boundary. + * (Post-incrementing forward iteration.) + * "Unsafe" macro, assumes well-formed UTF-16. + * + * The offset may point to the lead surrogate unit + * for a supplementary code point, in which case the macro will read + * the following trail surrogate as well. + * If the offset points to a trail surrogate, then that itself + * will be returned as the code point. + * The result is undefined if the offset points to a single, unpaired lead surrogate. + * + * @param s const UChar * string + * @param i string offset + * @param c output UChar32 variable + * @see U16_NEXT + * @stable ICU 2.4 + */ +#define U16_NEXT_UNSAFE(s, i, c) { \ + (c)=(s)[(i)++]; \ + if(U16_IS_LEAD(c)) { \ + (c)=U16_GET_SUPPLEMENTARY((c), (s)[(i)++]); \ + } \ +} + +/** + * Get a code point from a string at a code point boundary offset, + * and advance the offset to the next code point boundary. + * (Post-incrementing forward iteration.) + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * The offset may point to the lead surrogate unit + * for a supplementary code point, in which case the macro will read + * the following trail surrogate as well. + * If the offset points to a trail surrogate or + * to a single, unpaired lead surrogate, then that itself + * will be returned as the code point. + * + * @param s const UChar * string + * @param i string offset, must be i<length + * @param length string length + * @param c output UChar32 variable + * @see U16_NEXT_UNSAFE + * @stable ICU 2.4 + */ +#define U16_NEXT(s, i, length, c) { \ + (c)=(s)[(i)++]; \ + if(U16_IS_LEAD(c)) { \ + uint16_t __c2; \ + if((i)<(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \ + ++(i); \ + (c)=U16_GET_SUPPLEMENTARY((c), __c2); \ + } \ + } \ +} + +/** + * Append a code point to a string, overwriting 1 or 2 code units. + * The offset points to the current end of the string contents + * and is advanced (post-increment). + * "Unsafe" macro, assumes a valid code point and sufficient space in the string. + * Otherwise, the result is undefined. + * + * @param s const UChar * string buffer + * @param i string offset + * @param c code point to append + * @see U16_APPEND + * @stable ICU 2.4 + */ +#define U16_APPEND_UNSAFE(s, i, c) { \ + if((uint32_t)(c)<=0xffff) { \ + (s)[(i)++]=(uint16_t)(c); \ + } else { \ + (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \ + (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \ + } \ +} + +/** + * Append a code point to a string, overwriting 1 or 2 code units. + * The offset points to the current end of the string contents + * and is advanced (post-increment). + * "Safe" macro, checks for a valid code point. + * If a surrogate pair is written, checks for sufficient space in the string. + * If the code point is not valid or a trail surrogate does not fit, + * then isError is set to TRUE. + * + * @param s const UChar * string buffer + * @param i string offset, must be i<capacity + * @param capacity size of the string buffer + * @param c code point to append + * @param isError output UBool set to TRUE if an error occurs, otherwise not modified + * @see U16_APPEND_UNSAFE + * @stable ICU 2.4 + */ +#define U16_APPEND(s, i, capacity, c, isError) { \ + if((uint32_t)(c)<=0xffff) { \ + (s)[(i)++]=(uint16_t)(c); \ + } else if((uint32_t)(c)<=0x10ffff && (i)+1<(capacity)) { \ + (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \ + (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \ + } else /* c>0x10ffff or not enough space */ { \ + (isError)=TRUE; \ + } \ +} + +/** + * Advance the string offset from one code point boundary to the next. + * (Post-incrementing iteration.) + * "Unsafe" macro, assumes well-formed UTF-16. + * + * @param s const UChar * string + * @param i string offset + * @see U16_FWD_1 + * @stable ICU 2.4 + */ +#define U16_FWD_1_UNSAFE(s, i) { \ + if(U16_IS_LEAD((s)[(i)++])) { \ + ++(i); \ + } \ +} + +/** + * Advance the string offset from one code point boundary to the next. + * (Post-incrementing iteration.) + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * @param s const UChar * string + * @param i string offset, must be i<length + * @param length string length + * @see U16_FWD_1_UNSAFE + * @stable ICU 2.4 + */ +#define U16_FWD_1(s, i, length) { \ + if(U16_IS_LEAD((s)[(i)++]) && (i)<(length) && U16_IS_TRAIL((s)[i])) { \ + ++(i); \ + } \ +} + +/** + * Advance the string offset from one code point boundary to the n-th next one, + * i.e., move forward by n code points. + * (Post-incrementing iteration.) + * "Unsafe" macro, assumes well-formed UTF-16. + * + * @param s const UChar * string + * @param i string offset + * @param n number of code points to skip + * @see U16_FWD_N + * @stable ICU 2.4 + */ +#define U16_FWD_N_UNSAFE(s, i, n) { \ + int32_t __N=(n); \ + while(__N>0) { \ + U16_FWD_1_UNSAFE(s, i); \ + --__N; \ + } \ +} + +/** + * Advance the string offset from one code point boundary to the n-th next one, + * i.e., move forward by n code points. + * (Post-incrementing iteration.) + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * @param s const UChar * string + * @param i string offset, must be i<length + * @param length string length + * @param n number of code points to skip + * @see U16_FWD_N_UNSAFE + * @stable ICU 2.4 + */ +#define U16_FWD_N(s, i, length, n) { \ + int32_t __N=(n); \ + while(__N>0 && (i)<(length)) { \ + U16_FWD_1(s, i, length); \ + --__N; \ + } \ +} + +/** + * Adjust a random-access offset to a code point boundary + * at the start of a code point. + * If the offset points to the trail surrogate of a surrogate pair, + * then the offset is decremented. + * Otherwise, it is not modified. + * "Unsafe" macro, assumes well-formed UTF-16. + * + * @param s const UChar * string + * @param i string offset + * @see U16_SET_CP_START + * @stable ICU 2.4 + */ +#define U16_SET_CP_START_UNSAFE(s, i) { \ + if(U16_IS_TRAIL((s)[i])) { \ + --(i); \ + } \ +} + +/** + * Adjust a random-access offset to a code point boundary + * at the start of a code point. + * If the offset points to the trail surrogate of a surrogate pair, + * then the offset is decremented. + * Otherwise, it is not modified. + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * @param s const UChar * string + * @param start starting string offset (usually 0) + * @param i string offset, must be start<=i + * @see U16_SET_CP_START_UNSAFE + * @stable ICU 2.4 + */ +#define U16_SET_CP_START(s, start, i) { \ + if(U16_IS_TRAIL((s)[i]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \ + --(i); \ + } \ +} + +/* definitions with backward iteration -------------------------------------- */ + +/** + * Move the string offset from one code point boundary to the previous one + * and get the code point between them. + * (Pre-decrementing backward iteration.) + * "Unsafe" macro, assumes well-formed UTF-16. + * + * The input offset may be the same as the string length. + * If the offset is behind a trail surrogate unit + * for a supplementary code point, then the macro will read + * the preceding lead surrogate as well. + * If the offset is behind a lead surrogate, then that itself + * will be returned as the code point. + * The result is undefined if the offset is behind a single, unpaired trail surrogate. + * + * @param s const UChar * string + * @param i string offset + * @param c output UChar32 variable + * @see U16_PREV + * @stable ICU 2.4 + */ +#define U16_PREV_UNSAFE(s, i, c) { \ + (c)=(s)[--(i)]; \ + if(U16_IS_TRAIL(c)) { \ + (c)=U16_GET_SUPPLEMENTARY((s)[--(i)], (c)); \ + } \ +} + +/** + * Move the string offset from one code point boundary to the previous one + * and get the code point between them. + * (Pre-decrementing backward iteration.) + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * The input offset may be the same as the string length. + * If the offset is behind a trail surrogate unit + * for a supplementary code point, then the macro will read + * the preceding lead surrogate as well. + * If the offset is behind a lead surrogate or behind a single, unpaired + * trail surrogate, then that itself + * will be returned as the code point. + * + * @param s const UChar * string + * @param start starting string offset (usually 0) + * @param i string offset, must be start<i + * @param c output UChar32 variable + * @see U16_PREV_UNSAFE + * @stable ICU 2.4 + */ +#define U16_PREV(s, start, i, c) { \ + (c)=(s)[--(i)]; \ + if(U16_IS_TRAIL(c)) { \ + uint16_t __c2; \ + if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \ + --(i); \ + (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \ + } \ + } \ +} + +/** + * Move the string offset from one code point boundary to the previous one. + * (Pre-decrementing backward iteration.) + * The input offset may be the same as the string length. + * "Unsafe" macro, assumes well-formed UTF-16. + * + * @param s const UChar * string + * @param i string offset + * @see U16_BACK_1 + * @stable ICU 2.4 + */ +#define U16_BACK_1_UNSAFE(s, i) { \ + if(U16_IS_TRAIL((s)[--(i)])) { \ + --(i); \ + } \ +} + +/** + * Move the string offset from one code point boundary to the previous one. + * (Pre-decrementing backward iteration.) + * The input offset may be the same as the string length. + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * @param s const UChar * string + * @param start starting string offset (usually 0) + * @param i string offset, must be start<i + * @see U16_BACK_1_UNSAFE + * @stable ICU 2.4 + */ +#define U16_BACK_1(s, start, i) { \ + if(U16_IS_TRAIL((s)[--(i)]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \ + --(i); \ + } \ +} + +/** + * Move the string offset from one code point boundary to the n-th one before it, + * i.e., move backward by n code points. + * (Pre-decrementing backward iteration.) + * The input offset may be the same as the string length. + * "Unsafe" macro, assumes well-formed UTF-16. + * + * @param s const UChar * string + * @param i string offset + * @param n number of code points to skip + * @see U16_BACK_N + * @stable ICU 2.4 + */ +#define U16_BACK_N_UNSAFE(s, i, n) { \ + int32_t __N=(n); \ + while(__N>0) { \ + U16_BACK_1_UNSAFE(s, i); \ + --__N; \ + } \ +} + +/** + * Move the string offset from one code point boundary to the n-th one before it, + * i.e., move backward by n code points. + * (Pre-decrementing backward iteration.) + * The input offset may be the same as the string length. + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * @param s const UChar * string + * @param start start of string + * @param i string offset, must be start<i + * @param n number of code points to skip + * @see U16_BACK_N_UNSAFE + * @stable ICU 2.4 + */ +#define U16_BACK_N(s, start, i, n) { \ + int32_t __N=(n); \ + while(__N>0 && (i)>(start)) { \ + U16_BACK_1(s, start, i); \ + --__N; \ + } \ +} + +/** + * Adjust a random-access offset to a code point boundary after a code point. + * If the offset is behind the lead surrogate of a surrogate pair, + * then the offset is incremented. + * Otherwise, it is not modified. + * The input offset may be the same as the string length. + * "Unsafe" macro, assumes well-formed UTF-16. + * + * @param s const UChar * string + * @param i string offset + * @see U16_SET_CP_LIMIT + * @stable ICU 2.4 + */ +#define U16_SET_CP_LIMIT_UNSAFE(s, i) { \ + if(U16_IS_LEAD((s)[(i)-1])) { \ + ++(i); \ + } \ +} + +/** + * Adjust a random-access offset to a code point boundary after a code point. + * If the offset is behind the lead surrogate of a surrogate pair, + * then the offset is incremented. + * Otherwise, it is not modified. + * The input offset may be the same as the string length. + * "Safe" macro, handles unpaired surrogates and checks for string boundaries. + * + * @param s const UChar * string + * @param start starting string offset (usually 0) + * @param i string offset, start<=i<=length + * @param length string length + * @see U16_SET_CP_LIMIT_UNSAFE + * @stable ICU 2.4 + */ +#define U16_SET_CP_LIMIT(s, start, i, length) { \ + if((start)<(i) && (i)<(length) && U16_IS_LEAD((s)[(i)-1]) && U16_IS_TRAIL((s)[i])) { \ + ++(i); \ + } \ +} + +#endif diff --git a/utils/openttd/unicode/utf32.h b/utils/openttd/unicode/utf32.h new file mode 100644 index 00000000000..bf63e69dba0 --- /dev/null +++ b/utils/openttd/unicode/utf32.h @@ -0,0 +1,23 @@ +/* +******************************************************************************* +* +* Copyright (C) 1999-2001, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: utf32.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 1999sep20 +* created by: Markus W. Scherer +*/ +/** + * \file + * \brief C API: UTF-32 macros + * + * This file is obsolete and its contents moved to utf_old.h. + * See utf_old.h and Jitterbug 2150 and its discussion on the ICU mailing list + * in September 2002. + */ diff --git a/utils/openttd/unicode/utf8.h b/utils/openttd/unicode/utf8.h new file mode 100644 index 00000000000..1142c44df5f --- /dev/null +++ b/utils/openttd/unicode/utf8.h @@ -0,0 +1,652 @@ +/* +******************************************************************************* +* +* Copyright (C) 1999-2007, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: utf8.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 1999sep13 +* created by: Markus W. Scherer +*/ + +/** + * \file + * \brief C API: 8-bit Unicode handling macros + * + * This file defines macros to deal with 8-bit Unicode (UTF-8) code units (bytes) and strings. + * utf8.h is included by utf.h after unicode/umachine.h + * and some common definitions. + * + * For more information see utf.h and the ICU User Guide Strings chapter + * (http://icu-project.org/userguide/strings.html). + * + * <em>Usage:</em> + * ICU coding guidelines for if() statements should be followed when using these macros. + * Compound statements (curly braces {}) must be used for if-else-while... + * bodies and all macro statements should be terminated with semicolon. + */ + +#ifndef __UTF8_H__ +#define __UTF8_H__ + +/* utf.h must be included first. */ +#ifndef __UTF_H__ +# include "unicode/utf.h" +#endif + +/* internal definitions ----------------------------------------------------- */ + +/** + * \var utf8_countTrailBytes + * Internal array with numbers of trail bytes for any given byte used in + * lead byte position. + * @internal + */ +#ifdef U_UTF8_IMPL +U_EXPORT const uint8_t +#elif defined(U_STATIC_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) +U_CFUNC const uint8_t +#else +U_CFUNC U_IMPORT const uint8_t /* U_IMPORT2? */ /*U_IMPORT*/ +#endif +utf8_countTrailBytes[256]; + +/** + * Count the trail bytes for a UTF-8 lead byte. + * @internal + */ +#define U8_COUNT_TRAIL_BYTES(leadByte) (utf8_countTrailBytes[(uint8_t)leadByte]) + +/** + * Mask a UTF-8 lead byte, leave only the lower bits that form part of the code point value. + * @internal + */ +#define U8_MASK_LEAD_BYTE(leadByte, countTrailBytes) ((leadByte)&=(1<<(6-(countTrailBytes)))-1) + +/** + * Function for handling "next code point" with error-checking. + * @internal + */ +U_INTERNAL UChar32 U_EXPORT2 +utf8_nextCharSafeBody(const uint8_t *s, int32_t *pi, int32_t length, UChar32 c, UBool strict); + +/** + * Function for handling "append code point" with error-checking. + * @internal + */ +U_INTERNAL int32_t U_EXPORT2 +utf8_appendCharSafeBody(uint8_t *s, int32_t i, int32_t length, UChar32 c, UBool *pIsError); + +/** + * Function for handling "previous code point" with error-checking. + * @internal + */ +U_INTERNAL UChar32 U_EXPORT2 +utf8_prevCharSafeBody(const uint8_t *s, int32_t start, int32_t *pi, UChar32 c, UBool strict); + +/** + * Function for handling "skip backward one code point" with error-checking. + * @internal + */ +U_INTERNAL int32_t U_EXPORT2 +utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i); + +/* single-code point definitions -------------------------------------------- */ + +/** + * Does this code unit (byte) encode a code point by itself (US-ASCII 0..0x7f)? + * @param c 8-bit code unit (byte) + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U8_IS_SINGLE(c) (((c)&0x80)==0) + +/** + * Is this code unit (byte) a UTF-8 lead byte? + * @param c 8-bit code unit (byte) + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U8_IS_LEAD(c) ((uint8_t)((c)-0xc0)<0x3e) + +/** + * Is this code unit (byte) a UTF-8 trail byte? + * @param c 8-bit code unit (byte) + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U8_IS_TRAIL(c) (((c)&0xc0)==0x80) + +/** + * How many code units (bytes) are used for the UTF-8 encoding + * of this Unicode code point? + * @param c 32-bit code point + * @return 1..4, or 0 if c is a surrogate or not a Unicode code point + * @stable ICU 2.4 + */ +#define U8_LENGTH(c) \ + ((uint32_t)(c)<=0x7f ? 1 : \ + ((uint32_t)(c)<=0x7ff ? 2 : \ + ((uint32_t)(c)<=0xd7ff ? 3 : \ + ((uint32_t)(c)<=0xdfff || (uint32_t)(c)>0x10ffff ? 0 : \ + ((uint32_t)(c)<=0xffff ? 3 : 4)\ + ) \ + ) \ + ) \ + ) + +/** + * The maximum number of UTF-8 code units (bytes) per Unicode code point (U+0000..U+10ffff). + * @return 4 + * @stable ICU 2.4 + */ +#define U8_MAX_LENGTH 4 + +/** + * Get a code point from a string at a random-access offset, + * without changing the offset. + * The offset may point to either the lead byte or one of the trail bytes + * for a code point, in which case the macro will read all of the bytes + * for the code point. + * The result is undefined if the offset points to an illegal UTF-8 + * byte sequence. + * Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT. + * + * @param s const uint8_t * string + * @param i string offset + * @param c output UChar32 variable + * @see U8_GET + * @stable ICU 2.4 + */ +#define U8_GET_UNSAFE(s, i, c) { \ + int32_t _u8_get_unsafe_index=(int32_t)(i); \ + U8_SET_CP_START_UNSAFE(s, _u8_get_unsafe_index); \ + U8_NEXT_UNSAFE(s, _u8_get_unsafe_index, c); \ +} + +/** + * Get a code point from a string at a random-access offset, + * without changing the offset. + * The offset may point to either the lead byte or one of the trail bytes + * for a code point, in which case the macro will read all of the bytes + * for the code point. + * If the offset points to an illegal UTF-8 byte sequence, then + * c is set to a negative value. + * Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT. + * + * @param s const uint8_t * string + * @param start starting string offset + * @param i string offset, must be start<=i<length + * @param length string length + * @param c output UChar32 variable, set to <0 in case of an error + * @see U8_GET_UNSAFE + * @stable ICU 2.4 + */ +#define U8_GET(s, start, i, length, c) { \ + int32_t _u8_get_index=(int32_t)(i); \ + U8_SET_CP_START(s, start, _u8_get_index); \ + U8_NEXT(s, _u8_get_index, length, c); \ +} + +/* definitions with forward iteration --------------------------------------- */ + +/** + * Get a code point from a string at a code point boundary offset, + * and advance the offset to the next code point boundary. + * (Post-incrementing forward iteration.) + * "Unsafe" macro, assumes well-formed UTF-8. + * + * The offset may point to the lead byte of a multi-byte sequence, + * in which case the macro will read the whole sequence. + * The result is undefined if the offset points to a trail byte + * or an illegal UTF-8 sequence. + * + * @param s const uint8_t * string + * @param i string offset + * @param c output UChar32 variable + * @see U8_NEXT + * @stable ICU 2.4 + */ +#define U8_NEXT_UNSAFE(s, i, c) { \ + (c)=(uint8_t)(s)[(i)++]; \ + if((uint8_t)((c)-0xc0)<0x35) { \ + uint8_t __count=U8_COUNT_TRAIL_BYTES(c); \ + U8_MASK_LEAD_BYTE(c, __count); \ + switch(__count) { \ + /* each following branch falls through to the next one */ \ + case 3: \ + (c)=((c)<<6)|((s)[(i)++]&0x3f); \ + case 2: \ + (c)=((c)<<6)|((s)[(i)++]&0x3f); \ + case 1: \ + (c)=((c)<<6)|((s)[(i)++]&0x3f); \ + /* no other branches to optimize switch() */ \ + break; \ + } \ + } \ +} + +/** + * Get a code point from a string at a code point boundary offset, + * and advance the offset to the next code point boundary. + * (Post-incrementing forward iteration.) + * "Safe" macro, checks for illegal sequences and for string boundaries. + * + * The offset may point to the lead byte of a multi-byte sequence, + * in which case the macro will read the whole sequence. + * If the offset points to a trail byte or an illegal UTF-8 sequence, then + * c is set to a negative value. + * + * @param s const uint8_t * string + * @param i string offset, must be i<length + * @param length string length + * @param c output UChar32 variable, set to <0 in case of an error + * @see U8_NEXT_UNSAFE + * @stable ICU 2.4 + */ +#define U8_NEXT(s, i, length, c) { \ + (c)=(uint8_t)(s)[(i)++]; \ + if((c)>=0x80) { \ + uint8_t __t1, __t2; \ + if( /* handle U+1000..U+CFFF inline */ \ + (0xe0<(c) && (c)<=0xec) && \ + (((i)+1)<(length)) && \ + (__t1=(uint8_t)((s)[i]-0x80))<=0x3f && \ + (__t2=(uint8_t)((s)[(i)+1]-0x80))<= 0x3f \ + ) { \ + /* no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ \ + (c)=(UChar)(((c)<<12)|(__t1<<6)|__t2); \ + (i)+=2; \ + } else if( /* handle U+0080..U+07FF inline */ \ + ((c)<0xe0 && (c)>=0xc2) && \ + ((i)<(length)) && \ + (__t1=(uint8_t)((s)[i]-0x80))<=0x3f \ + ) { \ + (c)=(UChar)((((c)&0x1f)<<6)|__t1); \ + ++(i); \ + } else if(U8_IS_LEAD(c)) { \ + /* function call for "complicated" and error cases */ \ + (c)=utf8_nextCharSafeBody((const uint8_t *)s, &(i), (int32_t)(length), c, -1); \ + } else { \ + (c)=U_SENTINEL; \ + } \ + } \ +} + +/** + * Append a code point to a string, overwriting 1 to 4 bytes. + * The offset points to the current end of the string contents + * and is advanced (post-increment). + * "Unsafe" macro, assumes a valid code point and sufficient space in the string. + * Otherwise, the result is undefined. + * + * @param s const uint8_t * string buffer + * @param i string offset + * @param c code point to append + * @see U8_APPEND + * @stable ICU 2.4 + */ +#define U8_APPEND_UNSAFE(s, i, c) { \ + if((uint32_t)(c)<=0x7f) { \ + (s)[(i)++]=(uint8_t)(c); \ + } else { \ + if((uint32_t)(c)<=0x7ff) { \ + (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \ + } else { \ + if((uint32_t)(c)<=0xffff) { \ + (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \ + } else { \ + (s)[(i)++]=(uint8_t)(((c)>>18)|0xf0); \ + (s)[(i)++]=(uint8_t)((((c)>>12)&0x3f)|0x80); \ + } \ + (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \ + } \ + (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \ + } \ +} + +/** + * Append a code point to a string, overwriting 1 to 4 bytes. + * The offset points to the current end of the string contents + * and is advanced (post-increment). + * "Safe" macro, checks for a valid code point. + * If a non-ASCII code point is written, checks for sufficient space in the string. + * If the code point is not valid or trail bytes do not fit, + * then isError is set to TRUE. + * + * @param s const uint8_t * string buffer + * @param i string offset, must be i<capacity + * @param capacity size of the string buffer + * @param c code point to append + * @param isError output UBool set to TRUE if an error occurs, otherwise not modified + * @see U8_APPEND_UNSAFE + * @stable ICU 2.4 + */ +#define U8_APPEND(s, i, capacity, c, isError) { \ + if((uint32_t)(c)<=0x7f) { \ + (s)[(i)++]=(uint8_t)(c); \ + } else if((uint32_t)(c)<=0x7ff && (i)+1<(capacity)) { \ + (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \ + (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \ + } else if((uint32_t)(c)<=0xd7ff && (i)+2<(capacity)) { \ + (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \ + (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \ + (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \ + } else { \ + (i)=utf8_appendCharSafeBody(s, (int32_t)(i), (int32_t)(capacity), c, &(isError)); \ + } \ +} + +/** + * Advance the string offset from one code point boundary to the next. + * (Post-incrementing iteration.) + * "Unsafe" macro, assumes well-formed UTF-8. + * + * @param s const uint8_t * string + * @param i string offset + * @see U8_FWD_1 + * @stable ICU 2.4 + */ +#define U8_FWD_1_UNSAFE(s, i) { \ + (i)+=1+U8_COUNT_TRAIL_BYTES((s)[i]); \ +} + +/** + * Advance the string offset from one code point boundary to the next. + * (Post-incrementing iteration.) + * "Safe" macro, checks for illegal sequences and for string boundaries. + * + * @param s const uint8_t * string + * @param i string offset, must be i<length + * @param length string length + * @see U8_FWD_1_UNSAFE + * @stable ICU 2.4 + */ +#define U8_FWD_1(s, i, length) { \ + uint8_t __b=(uint8_t)(s)[(i)++]; \ + if(U8_IS_LEAD(__b)) { \ + uint8_t __count=U8_COUNT_TRAIL_BYTES(__b); \ + if((i)+__count>(length)) { \ + __count=(uint8_t)((length)-(i)); \ + } \ + while(__count>0 && U8_IS_TRAIL((s)[i])) { \ + ++(i); \ + --__count; \ + } \ + } \ +} + +/** + * Advance the string offset from one code point boundary to the n-th next one, + * i.e., move forward by n code points. + * (Post-incrementing iteration.) + * "Unsafe" macro, assumes well-formed UTF-8. + * + * @param s const uint8_t * string + * @param i string offset + * @param n number of code points to skip + * @see U8_FWD_N + * @stable ICU 2.4 + */ +#define U8_FWD_N_UNSAFE(s, i, n) { \ + int32_t __N=(n); \ + while(__N>0) { \ + U8_FWD_1_UNSAFE(s, i); \ + --__N; \ + } \ +} + +/** + * Advance the string offset from one code point boundary to the n-th next one, + * i.e., move forward by n code points. + * (Post-incrementing iteration.) + * "Safe" macro, checks for illegal sequences and for string boundaries. + * + * @param s const uint8_t * string + * @param i string offset, must be i<length + * @param length string length + * @param n number of code points to skip + * @see U8_FWD_N_UNSAFE + * @stable ICU 2.4 + */ +#define U8_FWD_N(s, i, length, n) { \ + int32_t __N=(n); \ + while(__N>0 && (i)<(length)) { \ + U8_FWD_1(s, i, length); \ + --__N; \ + } \ +} + +/** + * Adjust a random-access offset to a code point boundary + * at the start of a code point. + * If the offset points to a UTF-8 trail byte, + * then the offset is moved backward to the corresponding lead byte. + * Otherwise, it is not modified. + * "Unsafe" macro, assumes well-formed UTF-8. + * + * @param s const uint8_t * string + * @param i string offset + * @see U8_SET_CP_START + * @stable ICU 2.4 + */ +#define U8_SET_CP_START_UNSAFE(s, i) { \ + while(U8_IS_TRAIL((s)[i])) { --(i); } \ +} + +/** + * Adjust a random-access offset to a code point boundary + * at the start of a code point. + * If the offset points to a UTF-8 trail byte, + * then the offset is moved backward to the corresponding lead byte. + * Otherwise, it is not modified. + * "Safe" macro, checks for illegal sequences and for string boundaries. + * + * @param s const uint8_t * string + * @param start starting string offset (usually 0) + * @param i string offset, must be start<=i + * @see U8_SET_CP_START_UNSAFE + * @stable ICU 2.4 + */ +#define U8_SET_CP_START(s, start, i) { \ + if(U8_IS_TRAIL((s)[(i)])) { \ + (i)=utf8_back1SafeBody(s, start, (int32_t)(i)); \ + } \ +} + +/* definitions with backward iteration -------------------------------------- */ + +/** + * Move the string offset from one code point boundary to the previous one + * and get the code point between them. + * (Pre-decrementing backward iteration.) + * "Unsafe" macro, assumes well-formed UTF-8. + * + * The input offset may be the same as the string length. + * If the offset is behind a multi-byte sequence, then the macro will read + * the whole sequence. + * If the offset is behind a lead byte, then that itself + * will be returned as the code point. + * The result is undefined if the offset is behind an illegal UTF-8 sequence. + * + * @param s const uint8_t * string + * @param i string offset + * @param c output UChar32 variable + * @see U8_PREV + * @stable ICU 2.4 + */ +#define U8_PREV_UNSAFE(s, i, c) { \ + (c)=(uint8_t)(s)[--(i)]; \ + if(U8_IS_TRAIL(c)) { \ + uint8_t __b, __count=1, __shift=6; \ +\ + /* c is a trail byte */ \ + (c)&=0x3f; \ + for(;;) { \ + __b=(uint8_t)(s)[--(i)]; \ + if(__b>=0xc0) { \ + U8_MASK_LEAD_BYTE(__b, __count); \ + (c)|=(UChar32)__b<<__shift; \ + break; \ + } else { \ + (c)|=(UChar32)(__b&0x3f)<<__shift; \ + ++__count; \ + __shift+=6; \ + } \ + } \ + } \ +} + +/** + * Move the string offset from one code point boundary to the previous one + * and get the code point between them. + * (Pre-decrementing backward iteration.) + * "Safe" macro, checks for illegal sequences and for string boundaries. + * + * The input offset may be the same as the string length. + * If the offset is behind a multi-byte sequence, then the macro will read + * the whole sequence. + * If the offset is behind a lead byte, then that itself + * will be returned as the code point. + * If the offset is behind an illegal UTF-8 sequence, then c is set to a negative value. + * + * @param s const uint8_t * string + * @param start starting string offset (usually 0) + * @param i string offset, must be start<i + * @param c output UChar32 variable, set to <0 in case of an error + * @see U8_PREV_UNSAFE + * @stable ICU 2.4 + */ +#define U8_PREV(s, start, i, c) { \ + (c)=(uint8_t)(s)[--(i)]; \ + if((c)>=0x80) { \ + if((c)<=0xbf) { \ + (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -1); \ + } else { \ + (c)=U_SENTINEL; \ + } \ + } \ +} + +/** + * Move the string offset from one code point boundary to the previous one. + * (Pre-decrementing backward iteration.) + * The input offset may be the same as the string length. + * "Unsafe" macro, assumes well-formed UTF-8. + * + * @param s const uint8_t * string + * @param i string offset + * @see U8_BACK_1 + * @stable ICU 2.4 + */ +#define U8_BACK_1_UNSAFE(s, i) { \ + while(U8_IS_TRAIL((s)[--(i)])) {} \ +} + +/** + * Move the string offset from one code point boundary to the previous one. + * (Pre-decrementing backward iteration.) + * The input offset may be the same as the string length. + * "Safe" macro, checks for illegal sequences and for string boundaries. + * + * @param s const uint8_t * string + * @param start starting string offset (usually 0) + * @param i string offset, must be start<i + * @see U8_BACK_1_UNSAFE + * @stable ICU 2.4 + */ +#define U8_BACK_1(s, start, i) { \ + if(U8_IS_TRAIL((s)[--(i)])) { \ + (i)=utf8_back1SafeBody(s, start, (int32_t)(i)); \ + } \ +} + +/** + * Move the string offset from one code point boundary to the n-th one before it, + * i.e., move backward by n code points. + * (Pre-decrementing backward iteration.) + * The input offset may be the same as the string length. + * "Unsafe" macro, assumes well-formed UTF-8. + * + * @param s const uint8_t * string + * @param i string offset + * @param n number of code points to skip + * @see U8_BACK_N + * @stable ICU 2.4 + */ +#define U8_BACK_N_UNSAFE(s, i, n) { \ + int32_t __N=(n); \ + while(__N>0) { \ + U8_BACK_1_UNSAFE(s, i); \ + --__N; \ + } \ +} + +/** + * Move the string offset from one code point boundary to the n-th one before it, + * i.e., move backward by n code points. + * (Pre-decrementing backward iteration.) + * The input offset may be the same as the string length. + * "Safe" macro, checks for illegal sequences and for string boundaries. + * + * @param s const uint8_t * string + * @param start index of the start of the string + * @param i string offset, must be start<i + * @param n number of code points to skip + * @see U8_BACK_N_UNSAFE + * @stable ICU 2.4 + */ +#define U8_BACK_N(s, start, i, n) { \ + int32_t __N=(n); \ + while(__N>0 && (i)>(start)) { \ + U8_BACK_1(s, start, i); \ + --__N; \ + } \ +} + +/** + * Adjust a random-access offset to a code point boundary after a code point. + * If the offset is behind a partial multi-byte sequence, + * then the offset is incremented to behind the whole sequence. + * Otherwise, it is not modified. + * The input offset may be the same as the string length. + * "Unsafe" macro, assumes well-formed UTF-8. + * + * @param s const uint8_t * string + * @param i string offset + * @see U8_SET_CP_LIMIT + * @stable ICU 2.4 + */ +#define U8_SET_CP_LIMIT_UNSAFE(s, i) { \ + U8_BACK_1_UNSAFE(s, i); \ + U8_FWD_1_UNSAFE(s, i); \ +} + +/** + * Adjust a random-access offset to a code point boundary after a code point. + * If the offset is behind a partial multi-byte sequence, + * then the offset is incremented to behind the whole sequence. + * Otherwise, it is not modified. + * The input offset may be the same as the string length. + * "Safe" macro, checks for illegal sequences and for string boundaries. + * + * @param s const uint8_t * string + * @param start starting string offset (usually 0) + * @param i string offset, must be start<=i<=length + * @param length string length + * @see U8_SET_CP_LIMIT_UNSAFE + * @stable ICU 2.4 + */ +#define U8_SET_CP_LIMIT(s, start, i, length) { \ + if((start)<(i) && (i)<(length)) { \ + U8_BACK_1(s, start, i); \ + U8_FWD_1(s, i, length); \ + } \ +} + +#endif diff --git a/utils/openttd/unicode/utf_old.h b/utils/openttd/unicode/utf_old.h new file mode 100644 index 00000000000..2397889960e --- /dev/null +++ b/utils/openttd/unicode/utf_old.h @@ -0,0 +1,1171 @@ +/* +******************************************************************************* +* +* Copyright (C) 2002-2005, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: utf.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2002sep21 +* created by: Markus W. Scherer +*/ + +/** + * \file + * \brief C API: Deprecated macros for Unicode string handling + */ + +/** + * + * The macros in utf_old.h are all deprecated and their use discouraged. + * Some of the design principles behind the set of UTF macros + * have changed or proved impractical. + * Almost all of the old "UTF macros" are at least renamed. + * If you are looking for a new equivalent to an old macro, please see the + * comment at the old one. + * + * utf_old.h is included by utf.h after unicode/umachine.h + * and some common definitions, to not break old code. + * + * Brief summary of reasons for deprecation: + * - Switch on UTF_SIZE (selection of UTF-8/16/32 default string processing) + * was impractical. + * - Switch on UTF_SAFE etc. (selection of unsafe/safe/strict default string processing) + * was of little use and impractical. + * - Whole classes of macros became obsolete outside of the UTF_SIZE/UTF_SAFE + * selection framework: UTF32_ macros (all trivial) + * and UTF_ default and intermediate macros (all aliases). + * - The selection framework also caused many macro aliases. + * - Change in Unicode standard: "irregular" sequences (3.0) became illegal (3.2). + * - Change of language in Unicode standard: + * Growing distinction between internal x-bit Unicode strings and external UTF-x + * forms, with the former more lenient. + * Suggests renaming of UTF16_ macros to U16_. + * - The prefix "UTF_" without a width number confused some users. + * - "Safe" append macros needed the addition of an error indicator output. + * - "Safe" UTF-8 macros used legitimate (if rarely used) code point values + * to indicate error conditions. + * - The use of the "_CHAR" infix for code point operations confused some users. + * + * More details: + * + * Until ICU 2.2, utf.h theoretically allowed to choose among UTF-8/16/32 + * for string processing, and among unsafe/safe/strict default macros for that. + * + * It proved nearly impossible to write non-trivial, high-performance code + * that is UTF-generic. + * Unsafe default macros would be dangerous for default string processing, + * and the main reason for the "strict" versions disappeared: + * Between Unicode 3.0 and 3.2 all "irregular" UTF-8 sequences became illegal. + * The only other conditions that "strict" checked for were non-characters, + * which are valid during processing. Only during text input/output should they + * be checked, and at that time other well-formedness checks may be + * necessary or useful as well. + * This can still be done by using U16_NEXT and U_IS_UNICODE_NONCHAR + * or U_IS_UNICODE_CHAR. + * + * The old UTF8_..._SAFE macros also used some normal Unicode code points + * to indicate malformed sequences. + * The new UTF8_ macros without suffix use negative values instead. + * + * The entire contents of utf32.h was moved here without replacement + * because all those macros were trivial and + * were meaningful only in the framework of choosing the UTF size. + * + * See Jitterbug 2150 and its discussion on the ICU mailing list + * in September 2002. + * + * <hr> + * + * <em>Obsolete part</em> of pre-ICU 2.4 utf.h file documentation: + * + * <p>The original concept for these files was for ICU to allow + * in principle to set which UTF (UTF-8/16/32) is used internally + * by defining UTF_SIZE to either 8, 16, or 32. utf.h would then define the UChar type + * accordingly. UTF-16 was the default.</p> + * + * <p>This concept has been abandoned. + * A lot of the ICU source code assumes UChar strings are in UTF-16. + * This is especially true for low-level code like + * conversion, normalization, and collation. + * The utf.h header enforces the default of UTF-16. + * The UTF-8 and UTF-32 macros remain for now for completeness and backward compatibility.</p> + * + * <p>Accordingly, utf.h defines UChar to be an unsigned 16-bit integer. If this matches wchar_t, then + * UChar is defined to be exactly wchar_t, otherwise uint16_t.</p> + * + * <p>UChar32 is defined to be a signed 32-bit integer (int32_t), large enough for a 21-bit + * Unicode code point (Unicode scalar value, 0..0x10ffff). + * Before ICU 2.4, the definition of UChar32 was similarly platform-dependent as + * the definition of UChar. For details see the documentation for UChar32 itself.</p> + * + * <p>utf.h also defines a number of C macros for handling single Unicode code points and + * for using UTF Unicode strings. It includes utf8.h, utf16.h, and utf32.h for the actual + * implementations of those macros and then aliases one set of them (for UTF-16) for general use. + * The UTF-specific macros have the UTF size in the macro name prefixes (UTF16_...), while + * the general alias macros always begin with UTF_...</p> + * + * <p>Many string operations can be done with or without error checking. + * Where such a distinction is useful, there are two versions of the macros, "unsafe" and "safe" + * ones with ..._UNSAFE and ..._SAFE suffixes. The unsafe macros are fast but may cause + * program failures if the strings are not well-formed. The safe macros have an additional, boolean + * parameter "strict". If strict is FALSE, then only illegal sequences are detected. + * Otherwise, irregular sequences and non-characters are detected as well (like single surrogates). + * Safe macros return special error code points for illegal/irregular sequences: + * Typically, U+ffff, or values that would result in a code unit sequence of the same length + * as the erroneous input sequence.<br> + * Note that _UNSAFE macros have fewer parameters: They do not have the strictness parameter, and + * they do not have start/length parameters for boundary checking.</p> + * + * <p>Here, the macros are aliased in two steps: + * In the first step, the UTF-specific macros with UTF16_ prefix and _UNSAFE and _SAFE suffixes are + * aliased according to the UTF_SIZE to macros with UTF_ prefix and the same suffixes and signatures. + * Then, in a second step, the default, general alias macros are set to use either the unsafe or + * the safe/not strict (default) or the safe/strict macro; + * these general macros do not have a strictness parameter.</p> + * + * <p>It is possible to change the default choice for the general alias macros to be unsafe, safe/not strict or safe/strict. + * The default is safe/not strict. It is not recommended to select the unsafe macros as the basis for + * Unicode string handling in ICU! To select this, define UTF_SAFE, UTF_STRICT, or UTF_UNSAFE.</p> + * + * <p>For general use, one should use the default, general macros with UTF_ prefix and no _SAFE/_UNSAFE suffix. + * Only in some cases it may be necessary to control the choice of macro directly and use a less generic alias. + * For example, if it can be assumed that a string is well-formed and the index will stay within the bounds, + * then the _UNSAFE version may be used. + * If a UTF-8 string is to be processed, then the macros with UTF8_ prefixes need to be used.</p> + * + * <hr> + * + * @deprecated ICU 2.4. Use the macros in utf.h, utf16.h, utf8.h instead. + */ + +#ifndef __UTF_OLD_H__ +#define __UTF_OLD_H__ + +#ifndef U_HIDE_DEPRECATED_API + +/* utf.h must be included first. */ +#ifndef __UTF_H__ +# include "unicode/utf.h" +#endif + +/* Formerly utf.h, part 1 --------------------------------------------------- */ + +#ifdef U_USE_UTF_DEPRECATES +/** + * Unicode string and array offset and index type. + * ICU always counts Unicode code units (UChars) for + * string offsets, indexes, and lengths, not Unicode code points. + * + * @obsolete ICU 2.6. Use int32_t directly instead since this API will be removed in that release. + */ +typedef int32_t UTextOffset; +#endif + +/** Number of bits in a Unicode string code unit - ICU uses 16-bit Unicode. @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF_SIZE 16 + +/** + * The default choice for general Unicode string macros is to use the ..._SAFE macro implementations + * with strict=FALSE. + * + * @deprecated ICU 2.4. Obsolete, see utf_old.h. + */ +#define UTF_SAFE +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#undef UTF_UNSAFE +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#undef UTF_STRICT + +/** + * <p>UTF8_ERROR_VALUE_1 and UTF8_ERROR_VALUE_2 are special error values for UTF-8, + * which need 1 or 2 bytes in UTF-8:<br> + * U+0015 = NAK = Negative Acknowledge, C0 control character<br> + * U+009f = highest C1 control character</p> + * + * <p>These are used by UTF8_..._SAFE macros so that they can return an error value + * that needs the same number of code units (bytes) as were seen by + * a macro. They should be tested with UTF_IS_ERROR() or UTF_IS_VALID().</p> + * + * @deprecated ICU 2.4. Obsolete, see utf_old.h. + */ +#define UTF8_ERROR_VALUE_1 0x15 + +/** + * See documentation on UTF8_ERROR_VALUE_1 for details. + * + * @deprecated ICU 2.4. Obsolete, see utf_old.h. + */ +#define UTF8_ERROR_VALUE_2 0x9f + +/** + * Error value for all UTFs. This code point value will be set by macros with error + * checking if an error is detected. + * + * @deprecated ICU 2.4. Obsolete, see utf_old.h. + */ +#define UTF_ERROR_VALUE 0xffff + +/** + * Is a given 32-bit code an error value + * as returned by one of the macros for any UTF? + * + * @deprecated ICU 2.4. Obsolete, see utf_old.h. + */ +#define UTF_IS_ERROR(c) \ + (((c)&0xfffe)==0xfffe || (c)==UTF8_ERROR_VALUE_1 || (c)==UTF8_ERROR_VALUE_2) + +/** + * This is a combined macro: Is c a valid Unicode value _and_ not an error code? + * + * @deprecated ICU 2.4. Obsolete, see utf_old.h. + */ +#define UTF_IS_VALID(c) \ + (UTF_IS_UNICODE_CHAR(c) && \ + (c)!=UTF8_ERROR_VALUE_1 && (c)!=UTF8_ERROR_VALUE_2) + +/** + * Is this code unit or code point a surrogate (U+d800..U+dfff)? + * @deprecated ICU 2.4. Renamed to U_IS_SURROGATE and U16_IS_SURROGATE, see utf_old.h. + */ +#define UTF_IS_SURROGATE(uchar) (((uchar)&0xfffff800)==0xd800) + +/** + * Is a given 32-bit code point a Unicode noncharacter? + * + * @deprecated ICU 2.4. Renamed to U_IS_UNICODE_NONCHAR, see utf_old.h. + */ +#define UTF_IS_UNICODE_NONCHAR(c) \ + ((c)>=0xfdd0 && \ + ((uint32_t)(c)<=0xfdef || ((c)&0xfffe)==0xfffe) && \ + (uint32_t)(c)<=0x10ffff) + +/** + * Is a given 32-bit value a Unicode code point value (0..U+10ffff) + * that can be assigned a character? + * + * Code points that are not characters include: + * - single surrogate code points (U+d800..U+dfff, 2048 code points) + * - the last two code points on each plane (U+__fffe and U+__ffff, 34 code points) + * - U+fdd0..U+fdef (new with Unicode 3.1, 32 code points) + * - the highest Unicode code point value is U+10ffff + * + * This means that all code points below U+d800 are character code points, + * and that boundary is tested first for performance. + * + * @deprecated ICU 2.4. Renamed to U_IS_UNICODE_CHAR, see utf_old.h. + */ +#define UTF_IS_UNICODE_CHAR(c) \ + ((uint32_t)(c)<0xd800 || \ + ((uint32_t)(c)>0xdfff && \ + (uint32_t)(c)<=0x10ffff && \ + !UTF_IS_UNICODE_NONCHAR(c))) + +/* Formerly utf8.h ---------------------------------------------------------- */ + +/** + * Count the trail bytes for a UTF-8 lead byte. + * @deprecated ICU 2.4. Renamed to U8_COUNT_TRAIL_BYTES, see utf_old.h. + */ +#define UTF8_COUNT_TRAIL_BYTES(leadByte) (utf8_countTrailBytes[(uint8_t)leadByte]) + +/** + * Mask a UTF-8 lead byte, leave only the lower bits that form part of the code point value. + * @deprecated ICU 2.4. Renamed to U8_MASK_LEAD_BYTE, see utf_old.h. + */ +#define UTF8_MASK_LEAD_BYTE(leadByte, countTrailBytes) ((leadByte)&=(1<<(6-(countTrailBytes)))-1) + +/** Is this this code point a single code unit (byte)? @deprecated ICU 2.4. Renamed to U8_IS_SINGLE, see utf_old.h. */ +#define UTF8_IS_SINGLE(uchar) (((uchar)&0x80)==0) +/** Is this this code unit the lead code unit (byte) of a code point? @deprecated ICU 2.4. Renamed to U8_IS_LEAD, see utf_old.h. */ +#define UTF8_IS_LEAD(uchar) ((uint8_t)((uchar)-0xc0)<0x3e) +/** Is this this code unit a trailing code unit (byte) of a code point? @deprecated ICU 2.4. Renamed to U8_IS_TRAIL, see utf_old.h. */ +#define UTF8_IS_TRAIL(uchar) (((uchar)&0xc0)==0x80) + +/** Does this scalar Unicode value need multiple code units for storage? @deprecated ICU 2.4. Use U8_LENGTH or test ((uint32_t)(c)>0x7f) instead, see utf_old.h. */ +#define UTF8_NEED_MULTIPLE_UCHAR(c) ((uint32_t)(c)>0x7f) + +/** + * Given the lead character, how many bytes are taken by this code point. + * ICU does not deal with code points >0x10ffff + * unless necessary for advancing in the byte stream. + * + * These length macros take into account that for values >0x10ffff + * the UTF8_APPEND_CHAR_SAFE macros would write the error code point 0xffff + * with 3 bytes. + * Code point comparisons need to be in uint32_t because UChar32 + * may be a signed type, and negative values must be recognized. + * + * @deprecated ICU 2.4. Use U8_LENGTH instead, see utf_old.h. + */ +#if 1 +# define UTF8_CHAR_LENGTH(c) \ + ((uint32_t)(c)<=0x7f ? 1 : \ + ((uint32_t)(c)<=0x7ff ? 2 : \ + ((uint32_t)((c)-0x10000)>0xfffff ? 3 : 4) \ + ) \ + ) +#else +# define UTF8_CHAR_LENGTH(c) \ + ((uint32_t)(c)<=0x7f ? 1 : \ + ((uint32_t)(c)<=0x7ff ? 2 : \ + ((uint32_t)(c)<=0xffff ? 3 : \ + ((uint32_t)(c)<=0x10ffff ? 4 : \ + ((uint32_t)(c)<=0x3ffffff ? 5 : \ + ((uint32_t)(c)<=0x7fffffff ? 6 : 3) \ + ) \ + ) \ + ) \ + ) \ + ) +#endif + +/** The maximum number of bytes per code point. @deprecated ICU 2.4. Renamed to U8_MAX_LENGTH, see utf_old.h. */ +#define UTF8_MAX_CHAR_LENGTH 4 + +/** Average number of code units compared to UTF-16. @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF8_ARRAY_SIZE(size) ((5*(size))/2) + +/** @deprecated ICU 2.4. Renamed to U8_GET_UNSAFE, see utf_old.h. */ +#define UTF8_GET_CHAR_UNSAFE(s, i, c) { \ + int32_t _utf8_get_char_unsafe_index=(int32_t)(i); \ + UTF8_SET_CHAR_START_UNSAFE(s, _utf8_get_char_unsafe_index); \ + UTF8_NEXT_CHAR_UNSAFE(s, _utf8_get_char_unsafe_index, c); \ +} + +/** @deprecated ICU 2.4. Use U8_GET instead, see utf_old.h. */ +#define UTF8_GET_CHAR_SAFE(s, start, i, length, c, strict) { \ + int32_t _utf8_get_char_safe_index=(int32_t)(i); \ + UTF8_SET_CHAR_START_SAFE(s, start, _utf8_get_char_safe_index); \ + UTF8_NEXT_CHAR_SAFE(s, _utf8_get_char_safe_index, length, c, strict); \ +} + +/** @deprecated ICU 2.4. Renamed to U8_NEXT_UNSAFE, see utf_old.h. */ +#define UTF8_NEXT_CHAR_UNSAFE(s, i, c) { \ + (c)=(s)[(i)++]; \ + if((uint8_t)((c)-0xc0)<0x35) { \ + uint8_t __count=UTF8_COUNT_TRAIL_BYTES(c); \ + UTF8_MASK_LEAD_BYTE(c, __count); \ + switch(__count) { \ + /* each following branch falls through to the next one */ \ + case 3: \ + (c)=((c)<<6)|((s)[(i)++]&0x3f); \ + case 2: \ + (c)=((c)<<6)|((s)[(i)++]&0x3f); \ + case 1: \ + (c)=((c)<<6)|((s)[(i)++]&0x3f); \ + /* no other branches to optimize switch() */ \ + break; \ + } \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U8_APPEND_UNSAFE, see utf_old.h. */ +#define UTF8_APPEND_CHAR_UNSAFE(s, i, c) { \ + if((uint32_t)(c)<=0x7f) { \ + (s)[(i)++]=(uint8_t)(c); \ + } else { \ + if((uint32_t)(c)<=0x7ff) { \ + (s)[(i)++]=(uint8_t)(((c)>>6)|0xc0); \ + } else { \ + if((uint32_t)(c)<=0xffff) { \ + (s)[(i)++]=(uint8_t)(((c)>>12)|0xe0); \ + } else { \ + (s)[(i)++]=(uint8_t)(((c)>>18)|0xf0); \ + (s)[(i)++]=(uint8_t)((((c)>>12)&0x3f)|0x80); \ + } \ + (s)[(i)++]=(uint8_t)((((c)>>6)&0x3f)|0x80); \ + } \ + (s)[(i)++]=(uint8_t)(((c)&0x3f)|0x80); \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U8_FWD_1_UNSAFE, see utf_old.h. */ +#define UTF8_FWD_1_UNSAFE(s, i) { \ + (i)+=1+UTF8_COUNT_TRAIL_BYTES((s)[i]); \ +} + +/** @deprecated ICU 2.4. Renamed to U8_FWD_N_UNSAFE, see utf_old.h. */ +#define UTF8_FWD_N_UNSAFE(s, i, n) { \ + int32_t __N=(n); \ + while(__N>0) { \ + UTF8_FWD_1_UNSAFE(s, i); \ + --__N; \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U8_SET_CP_START_UNSAFE, see utf_old.h. */ +#define UTF8_SET_CHAR_START_UNSAFE(s, i) { \ + while(UTF8_IS_TRAIL((s)[i])) { --(i); } \ +} + +/** @deprecated ICU 2.4. Use U8_NEXT instead, see utf_old.h. */ +#define UTF8_NEXT_CHAR_SAFE(s, i, length, c, strict) { \ + (c)=(s)[(i)++]; \ + if((c)>=0x80) { \ + if(UTF8_IS_LEAD(c)) { \ + (c)=utf8_nextCharSafeBody(s, &(i), (int32_t)(length), c, strict); \ + } else { \ + (c)=UTF8_ERROR_VALUE_1; \ + } \ + } \ +} + +/** @deprecated ICU 2.4. Use U8_APPEND instead, see utf_old.h. */ +#define UTF8_APPEND_CHAR_SAFE(s, i, length, c) { \ + if((uint32_t)(c)<=0x7f) { \ + (s)[(i)++]=(uint8_t)(c); \ + } else { \ + (i)=utf8_appendCharSafeBody(s, (int32_t)(i), (int32_t)(length), c, NULL); \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U8_FWD_1, see utf_old.h. */ +#define UTF8_FWD_1_SAFE(s, i, length) U8_FWD_1(s, i, length) + +/** @deprecated ICU 2.4. Renamed to U8_FWD_N, see utf_old.h. */ +#define UTF8_FWD_N_SAFE(s, i, length, n) U8_FWD_N(s, i, length, n) + +/** @deprecated ICU 2.4. Renamed to U8_SET_CP_START, see utf_old.h. */ +#define UTF8_SET_CHAR_START_SAFE(s, start, i) U8_SET_CP_START(s, start, i) + +/** @deprecated ICU 2.4. Renamed to U8_PREV_UNSAFE, see utf_old.h. */ +#define UTF8_PREV_CHAR_UNSAFE(s, i, c) { \ + (c)=(s)[--(i)]; \ + if(UTF8_IS_TRAIL(c)) { \ + uint8_t __b, __count=1, __shift=6; \ +\ + /* c is a trail byte */ \ + (c)&=0x3f; \ + for(;;) { \ + __b=(s)[--(i)]; \ + if(__b>=0xc0) { \ + UTF8_MASK_LEAD_BYTE(__b, __count); \ + (c)|=(UChar32)__b<<__shift; \ + break; \ + } else { \ + (c)|=(UChar32)(__b&0x3f)<<__shift; \ + ++__count; \ + __shift+=6; \ + } \ + } \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U8_BACK_1_UNSAFE, see utf_old.h. */ +#define UTF8_BACK_1_UNSAFE(s, i) { \ + while(UTF8_IS_TRAIL((s)[--(i)])) {} \ +} + +/** @deprecated ICU 2.4. Renamed to U8_BACK_N_UNSAFE, see utf_old.h. */ +#define UTF8_BACK_N_UNSAFE(s, i, n) { \ + int32_t __N=(n); \ + while(__N>0) { \ + UTF8_BACK_1_UNSAFE(s, i); \ + --__N; \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U8_SET_CP_LIMIT_UNSAFE, see utf_old.h. */ +#define UTF8_SET_CHAR_LIMIT_UNSAFE(s, i) { \ + UTF8_BACK_1_UNSAFE(s, i); \ + UTF8_FWD_1_UNSAFE(s, i); \ +} + +/** @deprecated ICU 2.4. Use U8_PREV instead, see utf_old.h. */ +#define UTF8_PREV_CHAR_SAFE(s, start, i, c, strict) { \ + (c)=(s)[--(i)]; \ + if((c)>=0x80) { \ + if((c)<=0xbf) { \ + (c)=utf8_prevCharSafeBody(s, start, &(i), c, strict); \ + } else { \ + (c)=UTF8_ERROR_VALUE_1; \ + } \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U8_BACK_1, see utf_old.h. */ +#define UTF8_BACK_1_SAFE(s, start, i) U8_BACK_1(s, start, i) + +/** @deprecated ICU 2.4. Renamed to U8_BACK_N, see utf_old.h. */ +#define UTF8_BACK_N_SAFE(s, start, i, n) U8_BACK_N(s, start, i, n) + +/** @deprecated ICU 2.4. Renamed to U8_SET_CP_LIMIT, see utf_old.h. */ +#define UTF8_SET_CHAR_LIMIT_SAFE(s, start, i, length) U8_SET_CP_LIMIT(s, start, i, length) + +/* Formerly utf16.h --------------------------------------------------------- */ + +/** Is uchar a first/lead surrogate? @deprecated ICU 2.4. Renamed to U_IS_LEAD and U16_IS_LEAD, see utf_old.h. */ +#define UTF_IS_FIRST_SURROGATE(uchar) (((uchar)&0xfffffc00)==0xd800) + +/** Is uchar a second/trail surrogate? @deprecated ICU 2.4. Renamed to U_IS_TRAIL and U16_IS_TRAIL, see utf_old.h. */ +#define UTF_IS_SECOND_SURROGATE(uchar) (((uchar)&0xfffffc00)==0xdc00) + +/** Assuming c is a surrogate, is it a first/lead surrogate? @deprecated ICU 2.4. Renamed to U_IS_SURROGATE_LEAD and U16_IS_SURROGATE_LEAD, see utf_old.h. */ +#define UTF_IS_SURROGATE_FIRST(c) (((c)&0x400)==0) + +/** Helper constant for UTF16_GET_PAIR_VALUE. @deprecated ICU 2.4. Renamed to U16_SURROGATE_OFFSET, see utf_old.h. */ +#define UTF_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000) + +/** Get the UTF-32 value from the surrogate code units. @deprecated ICU 2.4. Renamed to U16_GET_SUPPLEMENTARY, see utf_old.h. */ +#define UTF16_GET_PAIR_VALUE(first, second) \ + (((first)<<10UL)+(second)-UTF_SURROGATE_OFFSET) + +/** @deprecated ICU 2.4. Renamed to U16_LEAD, see utf_old.h. */ +#define UTF_FIRST_SURROGATE(supplementary) (UChar)(((supplementary)>>10)+0xd7c0) + +/** @deprecated ICU 2.4. Renamed to U16_TRAIL, see utf_old.h. */ +#define UTF_SECOND_SURROGATE(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00) + +/** @deprecated ICU 2.4. Renamed to U16_LEAD, see utf_old.h. */ +#define UTF16_LEAD(supplementary) UTF_FIRST_SURROGATE(supplementary) + +/** @deprecated ICU 2.4. Renamed to U16_TRAIL, see utf_old.h. */ +#define UTF16_TRAIL(supplementary) UTF_SECOND_SURROGATE(supplementary) + +/** @deprecated ICU 2.4. Renamed to U16_IS_SINGLE, see utf_old.h. */ +#define UTF16_IS_SINGLE(uchar) !UTF_IS_SURROGATE(uchar) + +/** @deprecated ICU 2.4. Renamed to U16_IS_LEAD, see utf_old.h. */ +#define UTF16_IS_LEAD(uchar) UTF_IS_FIRST_SURROGATE(uchar) + +/** @deprecated ICU 2.4. Renamed to U16_IS_TRAIL, see utf_old.h. */ +#define UTF16_IS_TRAIL(uchar) UTF_IS_SECOND_SURROGATE(uchar) + +/** Does this scalar Unicode value need multiple code units for storage? @deprecated ICU 2.4. Use U16_LENGTH or test ((uint32_t)(c)>0xffff) instead, see utf_old.h. */ +#define UTF16_NEED_MULTIPLE_UCHAR(c) ((uint32_t)(c)>0xffff) + +/** @deprecated ICU 2.4. Renamed to U16_LENGTH, see utf_old.h. */ +#define UTF16_CHAR_LENGTH(c) ((uint32_t)(c)<=0xffff ? 1 : 2) + +/** @deprecated ICU 2.4. Renamed to U16_MAX_LENGTH, see utf_old.h. */ +#define UTF16_MAX_CHAR_LENGTH 2 + +/** Average number of code units compared to UTF-16. @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF16_ARRAY_SIZE(size) (size) + +/** + * Get a single code point from an offset that points to any + * of the code units that belong to that code point. + * Assume 0<=i<length. + * + * This could be used for iteration together with + * UTF16_CHAR_LENGTH() and UTF_IS_ERROR(), + * but the use of UTF16_NEXT_CHAR[_UNSAFE]() and + * UTF16_PREV_CHAR[_UNSAFE]() is more efficient for that. + * @deprecated ICU 2.4. Renamed to U16_GET_UNSAFE, see utf_old.h. + */ +#define UTF16_GET_CHAR_UNSAFE(s, i, c) { \ + (c)=(s)[i]; \ + if(UTF_IS_SURROGATE(c)) { \ + if(UTF_IS_SURROGATE_FIRST(c)) { \ + (c)=UTF16_GET_PAIR_VALUE((c), (s)[(i)+1]); \ + } else { \ + (c)=UTF16_GET_PAIR_VALUE((s)[(i)-1], (c)); \ + } \ + } \ +} + +/** @deprecated ICU 2.4. Use U16_GET instead, see utf_old.h. */ +#define UTF16_GET_CHAR_SAFE(s, start, i, length, c, strict) { \ + (c)=(s)[i]; \ + if(UTF_IS_SURROGATE(c)) { \ + uint16_t __c2; \ + if(UTF_IS_SURROGATE_FIRST(c)) { \ + if((i)+1<(length) && UTF_IS_SECOND_SURROGATE(__c2=(s)[(i)+1])) { \ + (c)=UTF16_GET_PAIR_VALUE((c), __c2); \ + /* strict: ((c)&0xfffe)==0xfffe is caught by UTF_IS_ERROR() and UTF_IS_UNICODE_CHAR() */ \ + } else if(strict) {\ + /* unmatched first surrogate */ \ + (c)=UTF_ERROR_VALUE; \ + } \ + } else { \ + if((i)-1>=(start) && UTF_IS_FIRST_SURROGATE(__c2=(s)[(i)-1])) { \ + (c)=UTF16_GET_PAIR_VALUE(__c2, (c)); \ + /* strict: ((c)&0xfffe)==0xfffe is caught by UTF_IS_ERROR() and UTF_IS_UNICODE_CHAR() */ \ + } else if(strict) {\ + /* unmatched second surrogate */ \ + (c)=UTF_ERROR_VALUE; \ + } \ + } \ + } else if((strict) && !UTF_IS_UNICODE_CHAR(c)) { \ + (c)=UTF_ERROR_VALUE; \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_NEXT_UNSAFE, see utf_old.h. */ +#define UTF16_NEXT_CHAR_UNSAFE(s, i, c) { \ + (c)=(s)[(i)++]; \ + if(UTF_IS_FIRST_SURROGATE(c)) { \ + (c)=UTF16_GET_PAIR_VALUE((c), (s)[(i)++]); \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_APPEND_UNSAFE, see utf_old.h. */ +#define UTF16_APPEND_CHAR_UNSAFE(s, i, c) { \ + if((uint32_t)(c)<=0xffff) { \ + (s)[(i)++]=(uint16_t)(c); \ + } else { \ + (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \ + (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_FWD_1_UNSAFE, see utf_old.h. */ +#define UTF16_FWD_1_UNSAFE(s, i) { \ + if(UTF_IS_FIRST_SURROGATE((s)[(i)++])) { \ + ++(i); \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_FWD_N_UNSAFE, see utf_old.h. */ +#define UTF16_FWD_N_UNSAFE(s, i, n) { \ + int32_t __N=(n); \ + while(__N>0) { \ + UTF16_FWD_1_UNSAFE(s, i); \ + --__N; \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_SET_CP_START_UNSAFE, see utf_old.h. */ +#define UTF16_SET_CHAR_START_UNSAFE(s, i) { \ + if(UTF_IS_SECOND_SURROGATE((s)[i])) { \ + --(i); \ + } \ +} + +/** @deprecated ICU 2.4. Use U16_NEXT instead, see utf_old.h. */ +#define UTF16_NEXT_CHAR_SAFE(s, i, length, c, strict) { \ + (c)=(s)[(i)++]; \ + if(UTF_IS_FIRST_SURROGATE(c)) { \ + uint16_t __c2; \ + if((i)<(length) && UTF_IS_SECOND_SURROGATE(__c2=(s)[(i)])) { \ + ++(i); \ + (c)=UTF16_GET_PAIR_VALUE((c), __c2); \ + /* strict: ((c)&0xfffe)==0xfffe is caught by UTF_IS_ERROR() and UTF_IS_UNICODE_CHAR() */ \ + } else if(strict) {\ + /* unmatched first surrogate */ \ + (c)=UTF_ERROR_VALUE; \ + } \ + } else if((strict) && !UTF_IS_UNICODE_CHAR(c)) { \ + /* unmatched second surrogate or other non-character */ \ + (c)=UTF_ERROR_VALUE; \ + } \ +} + +/** @deprecated ICU 2.4. Use U16_APPEND instead, see utf_old.h. */ +#define UTF16_APPEND_CHAR_SAFE(s, i, length, c) { \ + if((uint32_t)(c)<=0xffff) { \ + (s)[(i)++]=(uint16_t)(c); \ + } else if((uint32_t)(c)<=0x10ffff) { \ + if((i)+1<(length)) { \ + (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \ + (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \ + } else /* not enough space */ { \ + (s)[(i)++]=UTF_ERROR_VALUE; \ + } \ + } else /* c>0x10ffff, write error value */ { \ + (s)[(i)++]=UTF_ERROR_VALUE; \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_FWD_1, see utf_old.h. */ +#define UTF16_FWD_1_SAFE(s, i, length) U16_FWD_1(s, i, length) + +/** @deprecated ICU 2.4. Renamed to U16_FWD_N, see utf_old.h. */ +#define UTF16_FWD_N_SAFE(s, i, length, n) U16_FWD_N(s, i, length, n) + +/** @deprecated ICU 2.4. Renamed to U16_SET_CP_START, see utf_old.h. */ +#define UTF16_SET_CHAR_START_SAFE(s, start, i) U16_SET_CP_START(s, start, i) + +/** @deprecated ICU 2.4. Renamed to U16_PREV_UNSAFE, see utf_old.h. */ +#define UTF16_PREV_CHAR_UNSAFE(s, i, c) { \ + (c)=(s)[--(i)]; \ + if(UTF_IS_SECOND_SURROGATE(c)) { \ + (c)=UTF16_GET_PAIR_VALUE((s)[--(i)], (c)); \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_BACK_1_UNSAFE, see utf_old.h. */ +#define UTF16_BACK_1_UNSAFE(s, i) { \ + if(UTF_IS_SECOND_SURROGATE((s)[--(i)])) { \ + --(i); \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_BACK_N_UNSAFE, see utf_old.h. */ +#define UTF16_BACK_N_UNSAFE(s, i, n) { \ + int32_t __N=(n); \ + while(__N>0) { \ + UTF16_BACK_1_UNSAFE(s, i); \ + --__N; \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_SET_CP_LIMIT_UNSAFE, see utf_old.h. */ +#define UTF16_SET_CHAR_LIMIT_UNSAFE(s, i) { \ + if(UTF_IS_FIRST_SURROGATE((s)[(i)-1])) { \ + ++(i); \ + } \ +} + +/** @deprecated ICU 2.4. Use U16_PREV instead, see utf_old.h. */ +#define UTF16_PREV_CHAR_SAFE(s, start, i, c, strict) { \ + (c)=(s)[--(i)]; \ + if(UTF_IS_SECOND_SURROGATE(c)) { \ + uint16_t __c2; \ + if((i)>(start) && UTF_IS_FIRST_SURROGATE(__c2=(s)[(i)-1])) { \ + --(i); \ + (c)=UTF16_GET_PAIR_VALUE(__c2, (c)); \ + /* strict: ((c)&0xfffe)==0xfffe is caught by UTF_IS_ERROR() and UTF_IS_UNICODE_CHAR() */ \ + } else if(strict) {\ + /* unmatched second surrogate */ \ + (c)=UTF_ERROR_VALUE; \ + } \ + } else if((strict) && !UTF_IS_UNICODE_CHAR(c)) { \ + /* unmatched first surrogate or other non-character */ \ + (c)=UTF_ERROR_VALUE; \ + } \ +} + +/** @deprecated ICU 2.4. Renamed to U16_BACK_1, see utf_old.h. */ +#define UTF16_BACK_1_SAFE(s, start, i) U16_BACK_1(s, start, i) + +/** @deprecated ICU 2.4. Renamed to U16_BACK_N, see utf_old.h. */ +#define UTF16_BACK_N_SAFE(s, start, i, n) U16_BACK_N(s, start, i, n) + +/** @deprecated ICU 2.4. Renamed to U16_SET_CP_LIMIT, see utf_old.h. */ +#define UTF16_SET_CHAR_LIMIT_SAFE(s, start, i, length) U16_SET_CP_LIMIT(s, start, i, length) + +/* Formerly utf32.h --------------------------------------------------------- */ + +/* +* Old documentation: +* +* This file defines macros to deal with UTF-32 code units and code points. +* Signatures and semantics are the same as for the similarly named macros +* in utf16.h. +* utf32.h is included by utf.h after unicode/umachine.h</p> +* and some common definitions. +* <p><b>Usage:</b> ICU coding guidelines for if() statements should be followed when using these macros. +* Compound statements (curly braces {}) must be used for if-else-while... +* bodies and all macro statements should be terminated with semicolon.</p> +*/ + +/* internal definitions ----------------------------------------------------- */ + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_IS_SAFE(c, strict) \ + (!(strict) ? \ + (uint32_t)(c)<=0x10ffff : \ + UTF_IS_UNICODE_CHAR(c)) + +/* + * For the semantics of all of these macros, see utf16.h. + * The UTF-32 versions are trivial because any code point is + * encoded using exactly one code unit. + */ + +/* single-code point definitions -------------------------------------------- */ + +/* classes of code unit values */ + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_IS_SINGLE(uchar) 1 +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_IS_LEAD(uchar) 0 +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_IS_TRAIL(uchar) 0 + +/* number of code units per code point */ + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_NEED_MULTIPLE_UCHAR(c) 0 +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_CHAR_LENGTH(c) 1 +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_MAX_CHAR_LENGTH 1 + +/* average number of code units compared to UTF-16 */ + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_ARRAY_SIZE(size) (size) + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_GET_CHAR_UNSAFE(s, i, c) { \ + (c)=(s)[i]; \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_GET_CHAR_SAFE(s, start, i, length, c, strict) { \ + (c)=(s)[i]; \ + if(!UTF32_IS_SAFE(c, strict)) { \ + (c)=UTF_ERROR_VALUE; \ + } \ +} + +/* definitions with forward iteration --------------------------------------- */ + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_NEXT_CHAR_UNSAFE(s, i, c) { \ + (c)=(s)[(i)++]; \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_APPEND_CHAR_UNSAFE(s, i, c) { \ + (s)[(i)++]=(c); \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_FWD_1_UNSAFE(s, i) { \ + ++(i); \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_FWD_N_UNSAFE(s, i, n) { \ + (i)+=(n); \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_SET_CHAR_START_UNSAFE(s, i) { \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_NEXT_CHAR_SAFE(s, i, length, c, strict) { \ + (c)=(s)[(i)++]; \ + if(!UTF32_IS_SAFE(c, strict)) { \ + (c)=UTF_ERROR_VALUE; \ + } \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_APPEND_CHAR_SAFE(s, i, length, c) { \ + if((uint32_t)(c)<=0x10ffff) { \ + (s)[(i)++]=(c); \ + } else /* c>0x10ffff, write 0xfffd */ { \ + (s)[(i)++]=0xfffd; \ + } \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_FWD_1_SAFE(s, i, length) { \ + ++(i); \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_FWD_N_SAFE(s, i, length, n) { \ + if(((i)+=(n))>(length)) { \ + (i)=(length); \ + } \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_SET_CHAR_START_SAFE(s, start, i) { \ +} + +/* definitions with backward iteration -------------------------------------- */ + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_PREV_CHAR_UNSAFE(s, i, c) { \ + (c)=(s)[--(i)]; \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_BACK_1_UNSAFE(s, i) { \ + --(i); \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_BACK_N_UNSAFE(s, i, n) { \ + (i)-=(n); \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_SET_CHAR_LIMIT_UNSAFE(s, i) { \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_PREV_CHAR_SAFE(s, start, i, c, strict) { \ + (c)=(s)[--(i)]; \ + if(!UTF32_IS_SAFE(c, strict)) { \ + (c)=UTF_ERROR_VALUE; \ + } \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_BACK_1_SAFE(s, start, i) { \ + --(i); \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_BACK_N_SAFE(s, start, i, n) { \ + (i)-=(n); \ + if((i)<(start)) { \ + (i)=(start); \ + } \ +} + +/** @deprecated ICU 2.4. Obsolete, see utf_old.h. */ +#define UTF32_SET_CHAR_LIMIT_SAFE(s, i, length) { \ +} + +/* Formerly utf.h, part 2 --------------------------------------------------- */ + +/** + * Estimate the number of code units for a string based on the number of UTF-16 code units. + * + * @deprecated ICU 2.4. Obsolete, see utf_old.h. + */ +#define UTF_ARRAY_SIZE(size) UTF16_ARRAY_SIZE(size) + +/** @deprecated ICU 2.4. Renamed to U16_GET_UNSAFE, see utf_old.h. */ +#define UTF_GET_CHAR_UNSAFE(s, i, c) UTF16_GET_CHAR_UNSAFE(s, i, c) + +/** @deprecated ICU 2.4. Use U16_GET instead, see utf_old.h. */ +#define UTF_GET_CHAR_SAFE(s, start, i, length, c, strict) UTF16_GET_CHAR_SAFE(s, start, i, length, c, strict) + + +/** @deprecated ICU 2.4. Renamed to U16_NEXT_UNSAFE, see utf_old.h. */ +#define UTF_NEXT_CHAR_UNSAFE(s, i, c) UTF16_NEXT_CHAR_UNSAFE(s, i, c) + +/** @deprecated ICU 2.4. Use U16_NEXT instead, see utf_old.h. */ +#define UTF_NEXT_CHAR_SAFE(s, i, length, c, strict) UTF16_NEXT_CHAR_SAFE(s, i, length, c, strict) + + +/** @deprecated ICU 2.4. Renamed to U16_APPEND_UNSAFE, see utf_old.h. */ +#define UTF_APPEND_CHAR_UNSAFE(s, i, c) UTF16_APPEND_CHAR_UNSAFE(s, i, c) + +/** @deprecated ICU 2.4. Use U16_APPEND instead, see utf_old.h. */ +#define UTF_APPEND_CHAR_SAFE(s, i, length, c) UTF16_APPEND_CHAR_SAFE(s, i, length, c) + + +/** @deprecated ICU 2.4. Renamed to U16_FWD_1_UNSAFE, see utf_old.h. */ +#define UTF_FWD_1_UNSAFE(s, i) UTF16_FWD_1_UNSAFE(s, i) + +/** @deprecated ICU 2.4. Renamed to U16_FWD_1, see utf_old.h. */ +#define UTF_FWD_1_SAFE(s, i, length) UTF16_FWD_1_SAFE(s, i, length) + + +/** @deprecated ICU 2.4. Renamed to U16_FWD_N_UNSAFE, see utf_old.h. */ +#define UTF_FWD_N_UNSAFE(s, i, n) UTF16_FWD_N_UNSAFE(s, i, n) + +/** @deprecated ICU 2.4. Renamed to U16_FWD_N, see utf_old.h. */ +#define UTF_FWD_N_SAFE(s, i, length, n) UTF16_FWD_N_SAFE(s, i, length, n) + + +/** @deprecated ICU 2.4. Renamed to U16_SET_CP_START_UNSAFE, see utf_old.h. */ +#define UTF_SET_CHAR_START_UNSAFE(s, i) UTF16_SET_CHAR_START_UNSAFE(s, i) + +/** @deprecated ICU 2.4. Renamed to U16_SET_CP_START, see utf_old.h. */ +#define UTF_SET_CHAR_START_SAFE(s, start, i) UTF16_SET_CHAR_START_SAFE(s, start, i) + + +/** @deprecated ICU 2.4. Renamed to U16_PREV_UNSAFE, see utf_old.h. */ +#define UTF_PREV_CHAR_UNSAFE(s, i, c) UTF16_PREV_CHAR_UNSAFE(s, i, c) + +/** @deprecated ICU 2.4. Use U16_PREV instead, see utf_old.h. */ +#define UTF_PREV_CHAR_SAFE(s, start, i, c, strict) UTF16_PREV_CHAR_SAFE(s, start, i, c, strict) + + +/** @deprecated ICU 2.4. Renamed to U16_BACK_1_UNSAFE, see utf_old.h. */ +#define UTF_BACK_1_UNSAFE(s, i) UTF16_BACK_1_UNSAFE(s, i) + +/** @deprecated ICU 2.4. Renamed to U16_BACK_1, see utf_old.h. */ +#define UTF_BACK_1_SAFE(s, start, i) UTF16_BACK_1_SAFE(s, start, i) + + +/** @deprecated ICU 2.4. Renamed to U16_BACK_N_UNSAFE, see utf_old.h. */ +#define UTF_BACK_N_UNSAFE(s, i, n) UTF16_BACK_N_UNSAFE(s, i, n) + +/** @deprecated ICU 2.4. Renamed to U16_BACK_N, see utf_old.h. */ +#define UTF_BACK_N_SAFE(s, start, i, n) UTF16_BACK_N_SAFE(s, start, i, n) + + +/** @deprecated ICU 2.4. Renamed to U16_SET_CP_LIMIT_UNSAFE, see utf_old.h. */ +#define UTF_SET_CHAR_LIMIT_UNSAFE(s, i) UTF16_SET_CHAR_LIMIT_UNSAFE(s, i) + +/** @deprecated ICU 2.4. Renamed to U16_SET_CP_LIMIT, see utf_old.h. */ +#define UTF_SET_CHAR_LIMIT_SAFE(s, start, i, length) UTF16_SET_CHAR_LIMIT_SAFE(s, start, i, length) + +/* Define default macros (UTF-16 "safe") ------------------------------------ */ + +/** + * Does this code unit alone encode a code point (BMP, not a surrogate)? + * Same as UTF16_IS_SINGLE. + * @deprecated ICU 2.4. Renamed to U_IS_SINGLE and U16_IS_SINGLE, see utf_old.h. + */ +#define UTF_IS_SINGLE(uchar) U16_IS_SINGLE(uchar) + +/** + * Is this code unit the first one of several (a lead surrogate)? + * Same as UTF16_IS_LEAD. + * @deprecated ICU 2.4. Renamed to U_IS_LEAD and U16_IS_LEAD, see utf_old.h. + */ +#define UTF_IS_LEAD(uchar) U16_IS_LEAD(uchar) + +/** + * Is this code unit one of several but not the first one (a trail surrogate)? + * Same as UTF16_IS_TRAIL. + * @deprecated ICU 2.4. Renamed to U_IS_TRAIL and U16_IS_TRAIL, see utf_old.h. + */ +#define UTF_IS_TRAIL(uchar) U16_IS_TRAIL(uchar) + +/** + * Does this code point require multiple code units (is it a supplementary code point)? + * Same as UTF16_NEED_MULTIPLE_UCHAR. + * @deprecated ICU 2.4. Use U16_LENGTH or test ((uint32_t)(c)>0xffff) instead. + */ +#define UTF_NEED_MULTIPLE_UCHAR(c) UTF16_NEED_MULTIPLE_UCHAR(c) + +/** + * How many code units are used to encode this code point (1 or 2)? + * Same as UTF16_CHAR_LENGTH. + * @deprecated ICU 2.4. Renamed to U16_LENGTH, see utf_old.h. + */ +#define UTF_CHAR_LENGTH(c) U16_LENGTH(c) + +/** + * How many code units are used at most for any Unicode code point (2)? + * Same as UTF16_MAX_CHAR_LENGTH. + * @deprecated ICU 2.4. Renamed to U16_MAX_LENGTH, see utf_old.h. + */ +#define UTF_MAX_CHAR_LENGTH U16_MAX_LENGTH + +/** + * Set c to the code point that contains the code unit i. + * i could point to the lead or the trail surrogate for the code point. + * i is not modified. + * Same as UTF16_GET_CHAR. + * \pre 0<=i<length + * + * @deprecated ICU 2.4. Renamed to U16_GET, see utf_old.h. + */ +#define UTF_GET_CHAR(s, start, i, length, c) U16_GET(s, start, i, length, c) + +/** + * Set c to the code point that starts at code unit i + * and advance i to beyond the code units of this code point (post-increment). + * i must point to the first code unit of a code point. + * Otherwise c is set to the trail unit (surrogate) itself. + * Same as UTF16_NEXT_CHAR. + * \pre 0<=i<length + * \post 0<i<=length + * + * @deprecated ICU 2.4. Renamed to U16_NEXT, see utf_old.h. + */ +#define UTF_NEXT_CHAR(s, i, length, c) U16_NEXT(s, i, length, c) + +/** + * Append the code units of code point c to the string at index i + * and advance i to beyond the new code units (post-increment). + * The code units beginning at index i will be overwritten. + * Same as UTF16_APPEND_CHAR. + * \pre 0<=c<=0x10ffff + * \pre 0<=i<length + * \post 0<i<=length + * + * @deprecated ICU 2.4. Use U16_APPEND instead, see utf_old.h. + */ +#define UTF_APPEND_CHAR(s, i, length, c) UTF16_APPEND_CHAR_SAFE(s, i, length, c) + +/** + * Advance i to beyond the code units of the code point that begins at i. + * I.e., advance i by one code point. + * Same as UTF16_FWD_1. + * \pre 0<=i<length + * \post 0<i<=length + * + * @deprecated ICU 2.4. Renamed to U16_FWD_1, see utf_old.h. + */ +#define UTF_FWD_1(s, i, length) U16_FWD_1(s, i, length) + +/** + * Advance i to beyond the code units of the n code points where the first one begins at i. + * I.e., advance i by n code points. + * Same as UT16_FWD_N. + * \pre 0<=i<length + * \post 0<i<=length + * + * @deprecated ICU 2.4. Renamed to U16_FWD_N, see utf_old.h. + */ +#define UTF_FWD_N(s, i, length, n) U16_FWD_N(s, i, length, n) + +/** + * Take the random-access index i and adjust it so that it points to the beginning + * of a code point. + * The input index points to any code unit of a code point and is moved to point to + * the first code unit of the same code point. i is never incremented. + * In other words, if i points to a trail surrogate that is preceded by a matching + * lead surrogate, then i is decremented. Otherwise it is not modified. + * This can be used to start an iteration with UTF_NEXT_CHAR() from a random index. + * Same as UTF16_SET_CHAR_START. + * \pre start<=i<length + * \post start<=i<length + * + * @deprecated ICU 2.4. Renamed to U16_SET_CP_START, see utf_old.h. + */ +#define UTF_SET_CHAR_START(s, start, i) U16_SET_CP_START(s, start, i) + +/** + * Set c to the code point that has code units before i + * and move i backward (towards the beginning of the string) + * to the first code unit of this code point (pre-increment). + * i must point to the first code unit after the last unit of a code point (i==length is allowed). + * Same as UTF16_PREV_CHAR. + * \pre start<i<=length + * \post start<=i<length + * + * @deprecated ICU 2.4. Renamed to U16_PREV, see utf_old.h. + */ +#define UTF_PREV_CHAR(s, start, i, c) U16_PREV(s, start, i, c) + +/** + * Move i backward (towards the beginning of the string) + * to the first code unit of the code point that has code units before i. + * I.e., move i backward by one code point. + * i must point to the first code unit after the last unit of a code point (i==length is allowed). + * Same as UTF16_BACK_1. + * \pre start<i<=length + * \post start<=i<length + * + * @deprecated ICU 2.4. Renamed to U16_BACK_1, see utf_old.h. + */ +#define UTF_BACK_1(s, start, i) U16_BACK_1(s, start, i) + +/** + * Move i backward (towards the beginning of the string) + * to the first code unit of the n code points that have code units before i. + * I.e., move i backward by n code points. + * i must point to the first code unit after the last unit of a code point (i==length is allowed). + * Same as UTF16_BACK_N. + * \pre start<i<=length + * \post start<=i<length + * + * @deprecated ICU 2.4. Renamed to U16_BACK_N, see utf_old.h. + */ +#define UTF_BACK_N(s, start, i, n) U16_BACK_N(s, start, i, n) + +/** + * Take the random-access index i and adjust it so that it points beyond + * a code point. The input index points beyond any code unit + * of a code point and is moved to point beyond the last code unit of the same + * code point. i is never decremented. + * In other words, if i points to a trail surrogate that is preceded by a matching + * lead surrogate, then i is incremented. Otherwise it is not modified. + * This can be used to start an iteration with UTF_PREV_CHAR() from a random index. + * Same as UTF16_SET_CHAR_LIMIT. + * \pre start<i<=length + * \post start<i<=length + * + * @deprecated ICU 2.4. Renamed to U16_SET_CP_LIMIT, see utf_old.h. + */ +#define UTF_SET_CHAR_LIMIT(s, start, i, length) U16_SET_CP_LIMIT(s, start, i, length) + +#endif /* U_HIDE_DEPRECATED_API */ + +#endif + diff --git a/utils/openttd/unicode/utrace.h b/utils/openttd/unicode/utrace.h new file mode 100644 index 00000000000..3c8be9f7c34 --- /dev/null +++ b/utils/openttd/unicode/utrace.h @@ -0,0 +1,358 @@ +/* +******************************************************************************* +* +* Copyright (C) 2003-2006, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: utrace.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2003aug06 +* created by: Markus W. Scherer +* +* Definitions for ICU tracing/logging. +* +*/ + +#ifndef __UTRACE_H__ +#define __UTRACE_H__ + +#include <stdarg.h> +#include "unicode/utypes.h" + +/** + * \file + * \brief C API: Definitions for ICU tracing/logging. + * + * This provides API for debugging the internals of ICU without the use of + * a traditional debugger. + * + * By default, tracing is disabled in ICU. If you need to debug ICU with + * tracing, please compile ICU with the --enable-tracing configure option. + */ + +U_CDECL_BEGIN + +/** + * Trace severity levels. Higher levels increase the verbosity of the trace output. + * @see utrace_setLevel + * @stable ICU 2.8 + */ +typedef enum UTraceLevel { + /** Disable all tracing @stable ICU 2.8*/ + UTRACE_OFF=-1, + /** Trace error conditions only @stable ICU 2.8*/ + UTRACE_ERROR=0, + /** Trace errors and warnings @stable ICU 2.8*/ + UTRACE_WARNING=3, + /** Trace opens and closes of ICU services @stable ICU 2.8*/ + UTRACE_OPEN_CLOSE=5, + /** Trace an intermediate number of ICU operations @stable ICU 2.8*/ + UTRACE_INFO=7, + /** Trace the maximum number of ICU operations @stable ICU 2.8*/ + UTRACE_VERBOSE=9 +} UTraceLevel; + +/** + * These are the ICU functions that will be traced when tracing is enabled. + * @stable ICU 2.8 + */ +typedef enum UTraceFunctionNumber { + UTRACE_FUNCTION_START=0, + UTRACE_U_INIT=UTRACE_FUNCTION_START, + UTRACE_U_CLEANUP, + UTRACE_FUNCTION_LIMIT, + + UTRACE_CONVERSION_START=0x1000, + UTRACE_UCNV_OPEN=UTRACE_CONVERSION_START, + UTRACE_UCNV_OPEN_PACKAGE, + UTRACE_UCNV_OPEN_ALGORITHMIC, + UTRACE_UCNV_CLONE, + UTRACE_UCNV_CLOSE, + UTRACE_UCNV_FLUSH_CACHE, + UTRACE_UCNV_LOAD, + UTRACE_UCNV_UNLOAD, + UTRACE_CONVERSION_LIMIT, + + UTRACE_COLLATION_START=0x2000, + UTRACE_UCOL_OPEN=UTRACE_COLLATION_START, + UTRACE_UCOL_CLOSE, + UTRACE_UCOL_STRCOLL, + UTRACE_UCOL_GET_SORTKEY, + UTRACE_UCOL_GETLOCALE, + UTRACE_UCOL_NEXTSORTKEYPART, + UTRACE_UCOL_STRCOLLITER, + UTRACE_UCOL_OPEN_FROM_SHORT_STRING, + UTRACE_COLLATION_LIMIT +} UTraceFunctionNumber; + +/** + * Setter for the trace level. + * @param traceLevel A UTraceLevel value. + * @stable ICU 2.8 + */ +U_STABLE void U_EXPORT2 +utrace_setLevel(int32_t traceLevel); + +/** + * Getter for the trace level. + * @return The UTraceLevel value being used by ICU. + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +utrace_getLevel(void); + +/* Trace function pointers types ----------------------------- */ + +/** + * Type signature for the trace function to be called when entering a function. + * @param context value supplied at the time the trace functions are set. + * @param fnNumber Enum value indicating the ICU function being entered. + * @stable ICU 2.8 + */ +typedef void U_CALLCONV +UTraceEntry(const void *context, int32_t fnNumber); + +/** + * Type signature for the trace function to be called when exiting from a function. + * @param context value supplied at the time the trace functions are set. + * @param fnNumber Enum value indicating the ICU function being exited. + * @param fmt A formatting string that describes the number and types + * of arguments included with the variable args. The fmt + * string has the same form as the utrace_vformat format + * string. + * @param args A variable arguments list. Contents are described by + * the fmt parameter. + * @see utrace_vformat + * @stable ICU 2.8 + */ +typedef void U_CALLCONV +UTraceExit(const void *context, int32_t fnNumber, + const char *fmt, va_list args); + +/** + * Type signature for the trace function to be called from within an ICU function + * to display data or messages. + * @param context value supplied at the time the trace functions are set. + * @param fnNumber Enum value indicating the ICU function being exited. + * @param level The current tracing level + * @param fmt A format string describing the tracing data that is supplied + * as variable args + * @param args The data being traced, passed as variable args. + * @stable ICU 2.8 + */ +typedef void U_CALLCONV +UTraceData(const void *context, int32_t fnNumber, int32_t level, + const char *fmt, va_list args); + +/** + * Set ICU Tracing functions. Installs application-provided tracing + * functions into ICU. After doing this, subsequent ICU operations + * will call back to the installed functions, providing a trace + * of the use of ICU. Passing a NULL pointer for a tracing function + * is allowed, and inhibits tracing action at points where that function + * would be called. + * <p> + * Tracing and Threads: Tracing functions are global to a process, and + * will be called in response to ICU operations performed by any + * thread. If tracing of an individual thread is desired, the + * tracing functions must themselves filter by checking that the + * current thread is the desired thread. + * + * @param context an uninterpretted pointer. Whatever is passed in + * here will in turn be passed to each of the tracing + * functions UTraceEntry, UTraceExit and UTraceData. + * ICU does not use or alter this pointer. + * @param e Callback function to be called on entry to a + * a traced ICU function. + * @param x Callback function to be called on exit from a + * traced ICU function. + * @param d Callback function to be called from within a + * traced ICU function, for the purpose of providing + * data to the trace. + * + * @stable ICU 2.8 + */ +U_STABLE void U_EXPORT2 +utrace_setFunctions(const void *context, + UTraceEntry *e, UTraceExit *x, UTraceData *d); + +/** + * Get the currently installed ICU tracing functions. Note that a null function + * pointer will be returned if no trace function has been set. + * + * @param context The currently installed tracing context. + * @param e The currently installed UTraceEntry function. + * @param x The currently installed UTraceExit function. + * @param d The currently installed UTraceData function. + * @stable ICU 2.8 + */ +U_STABLE void U_EXPORT2 +utrace_getFunctions(const void **context, + UTraceEntry **e, UTraceExit **x, UTraceData **d); + + + +/* + * + * ICU trace format string syntax + * + * Format Strings are passed to UTraceData functions, and define the + * number and types of the trace data being passed on each call. + * + * The UTraceData function, which is supplied by the application, + * not by ICU, can either forward the trace data (passed via + * varargs) and the format string back to ICU for formatting into + * a displayable string, or it can interpret the format itself, + * and do as it wishes with the trace data. + * + * + * Goals for the format string + * - basic data output + * - easy to use for trace programmer + * - sufficient provision for data types for trace output readability + * - well-defined types and binary portable APIs + * + * Non-goals + * - printf compatibility + * - fancy formatting + * - argument reordering and other internationalization features + * + * ICU trace format strings contain plain text with argument inserts, + * much like standard printf format strings. + * Each insert begins with a '%', then optionally contains a 'v', + * then exactly one type character. + * Two '%' in a row represent a '%' instead of an insert. + * The trace format strings need not have \n at the end. + * + * + * Types + * ----- + * + * Type characters: + * - c A char character in the default codepage. + * - s A NUL-terminated char * string in the default codepage. + * - S A UChar * string. Requires two params, (ptr, length). Length=-1 for nul term. + * - b A byte (8-bit integer). + * - h A 16-bit integer. Also a 16 bit Unicode code unit. + * - d A 32-bit integer. Also a 20 bit Unicode code point value. + * - l A 64-bit integer. + * - p A data pointer. + * + * Vectors + * ------- + * + * If the 'v' is not specified, then one item of the specified type + * is passed in. + * If the 'v' (for "vector") is specified, then a vector of items of the + * specified type is passed in, via a pointer to the first item + * and an int32_t value for the length of the vector. + * Length==-1 means zero or NUL termination. Works for vectors of all types. + * + * Note: %vS is a vector of (UChar *) strings. The strings must + * be nul terminated as there is no way to provide a + * separate length parameter for each string. The length + * parameter (required for all vectors) is the number of + * strings, not the length of the strings. + * + * Examples + * -------- + * + * These examples show the parameters that will be passed to an application's + * UTraceData() function for various formats. + * + * - the precise formatting is up to the application! + * - the examples use type casts for arguments only to _show_ the types of + * arguments without needing variable declarations in the examples; + * the type casts will not be necessary in actual code + * + * UTraceDataFunc(context, fnNumber, level, + * "There is a character %c in the string %s.", // Format String + * (char)c, (const char *)s); // varargs parameters + * -> There is a character 0x42 'B' in the string "Bravo". + * + * UTraceDataFunc(context, fnNumber, level, + * "Vector of bytes %vb vector of chars %vc", + * (const uint8_t *)bytes, (int32_t)bytesLength, + * (const char *)chars, (int32_t)charsLength); + * -> Vector of bytes + * 42 63 64 3f [4] + * vector of chars + * "Bcd?"[4] + * + * UTraceDataFunc(context, fnNumber, level, + * "An int32_t %d and a whole bunch of them %vd", + * (int32_t)-5, (const int32_t *)ints, (int32_t)intsLength); + * -> An int32_t 0xfffffffb and a whole bunch of them + * fffffffb 00000005 0000010a [3] + * + */ + + + +/** + * Trace output Formatter. An application's UTraceData tracing functions may call + * back to this function to format the trace output in a + * human readable form. Note that a UTraceData function may choose + * to not format the data; it could, for example, save it in + * in the raw form it was received (more compact), leaving + * formatting for a later trace analyis tool. + * @param outBuf pointer to a buffer to receive the formatted output. Output + * will be nul terminated if there is space in the buffer - + * if the length of the requested output < the output buffer size. + * @param capacity Length of the output buffer. + * @param indent Number of spaces to indent the output. Intended to allow + * data displayed from nested functions to be indented for readability. + * @param fmt Format specification for the data to output + * @param args Data to be formatted. + * @return Length of formatted output, including the terminating NUL. + * If buffer capacity is insufficient, the required capacity is returned. + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +utrace_vformat(char *outBuf, int32_t capacity, + int32_t indent, const char *fmt, va_list args); + +/** + * Trace output Formatter. An application's UTraceData tracing functions may call + * this function to format any additional trace data, beyond that + * provided by default, in human readable form with the same + * formatting conventions used by utrace_vformat(). + * @param outBuf pointer to a buffer to receive the formatted output. Output + * will be nul terminated if there is space in the buffer - + * if the length of the requested output < the output buffer size. + * @param capacity Length of the output buffer. + * @param indent Number of spaces to indent the output. Intended to allow + * data displayed from nested functions to be indented for readability. + * @param fmt Format specification for the data to output + * @param ... Data to be formatted. + * @return Length of formatted output, including the terminating NUL. + * If buffer capacity is insufficient, the required capacity is returned. + * @stable ICU 2.8 + */ +U_STABLE int32_t U_EXPORT2 +utrace_format(char *outBuf, int32_t capacity, + int32_t indent, const char *fmt, ...); + + + +/* Trace function numbers --------------------------------------------------- */ + +/** + * Get the name of a function from its trace function number. + * + * @param fnNumber The trace number for an ICU function. + * @return The name string for the function. + * + * @see UTraceFunctionNumber + * @stable ICU 2.8 + */ +U_STABLE const char * U_EXPORT2 +utrace_functionName(int32_t fnNumber); + +U_CDECL_END + +#endif diff --git a/utils/openttd/unicode/utypes.h b/utils/openttd/unicode/utypes.h new file mode 100644 index 00000000000..12977ed5e42 --- /dev/null +++ b/utils/openttd/unicode/utypes.h @@ -0,0 +1,801 @@ +/* +********************************************************************** +* Copyright (C) 1996-2008, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* +* FILE NAME : UTYPES.H (formerly ptypes.h) +* +* Date Name Description +* 12/11/96 helena Creation. +* 02/27/97 aliu Added typedefs for UClassID, int8, int16, int32, +* uint8, uint16, and uint32. +* 04/01/97 aliu Added XP_CPLUSPLUS and modified to work under C as +* well as C++. +* Modified to use memcpy() for uprv_arrayCopy() fns. +* 04/14/97 aliu Added TPlatformUtilities. +* 05/07/97 aliu Added import/export specifiers (replacing the old +* broken EXT_CLASS). Added version number for our +* code. Cleaned up header. +* 6/20/97 helena Java class name change. +* 08/11/98 stephen UErrorCode changed from typedef to enum +* 08/12/98 erm Changed T_ANALYTIC_PACKAGE_VERSION to 3 +* 08/14/98 stephen Added uprv_arrayCopy() for int8_t, int16_t, int32_t +* 12/09/98 jfitz Added BUFFER_OVERFLOW_ERROR (bug 1100066) +* 04/20/99 stephen Cleaned up & reworked for autoconf. +* Renamed to utypes.h. +* 05/05/99 stephen Changed to use <inttypes.h> +* 12/07/99 helena Moved copyright notice string from ucnv_bld.h here. +******************************************************************************* +*/ + +#ifndef UTYPES_H +#define UTYPES_H + + +#include "unicode/umachine.h" +#include "unicode/utf.h" +#include "unicode/uversion.h" +#include "unicode/uconfig.h" + +#if !U_DEFAULT_SHOW_DRAFT && !defined(U_SHOW_DRAFT_API) +#define U_HIDE_DRAFT_API 1 +#endif + +#ifdef U_HIDE_DRAFT_API +#include "unicode/udraft.h" +#endif + +#ifdef U_HIDE_DEPRECATED_API +#include "unicode/udeprctd.h" +#endif + +#ifdef U_HIDE_DEPRECATED_API +#include "unicode/uobslete.h" +#endif + +#ifdef U_HIDE_INTERNAL_API +#include "unicode/uintrnal.h" +#endif + +#ifdef U_HIDE_SYSTEM_API +#include "unicode/usystem.h" +#endif + +/*! + * \file + * \brief Basic definitions for ICU, for both C and C++ APIs + * + * This file defines basic types, constants, and enumerations directly or + * indirectly by including other header files, especially utf.h for the + * basic character and string definitions and umachine.h for consistent + * integer and other types. + */ + +/*===========================================================================*/ +/* char Character set family */ +/*===========================================================================*/ + +/** + * U_CHARSET_FAMILY is equal to this value when the platform is an ASCII based platform. + * @stable ICU 2.0 + */ +#define U_ASCII_FAMILY 0 + +/** + * U_CHARSET_FAMILY is equal to this value when the platform is an EBCDIC based platform. + * @stable ICU 2.0 + */ +#define U_EBCDIC_FAMILY 1 + +/** + * \def U_CHARSET_FAMILY + * + * <p>These definitions allow to specify the encoding of text + * in the char data type as defined by the platform and the compiler. + * It is enough to determine the code point values of "invariant characters", + * which are the ones shared by all encodings that are in use + * on a given platform.</p> + * + * <p>Those "invariant characters" should be all the uppercase and lowercase + * latin letters, the digits, the space, and "basic punctuation". + * Also, '\\n', '\\r', '\\t' should be available.</p> + * + * <p>The list of "invariant characters" is:<br> + * \code + * A-Z a-z 0-9 SPACE " % & ' ( ) * + , - . / : ; < = > ? _ + * \endcode + * <br> + * (52 letters + 10 numbers + 20 punc/sym/space = 82 total)</p> + * + * <p>This matches the IBM Syntactic Character Set (CS 640).</p> + * + * <p>In other words, all the graphic characters in 7-bit ASCII should + * be safely accessible except the following:</p> + * + * \code + * '\' <backslash> + * '[' <left bracket> + * ']' <right bracket> + * '{' <left brace> + * '}' <right brace> + * '^' <circumflex> + * '~' <tilde> + * '!' <exclamation mark> + * '#' <number sign> + * '|' <vertical line> + * '$' <dollar sign> + * '@' <commercial at> + * '`' <grave accent> + * \endcode + * @stable ICU 2.0 + */ + +#ifndef U_CHARSET_FAMILY +# define U_CHARSET_FAMILY 0 +#endif + +/*===========================================================================*/ +/* ICUDATA naming scheme */ +/*===========================================================================*/ + +/** + * \def U_ICUDATA_TYPE_LETTER + * + * This is a platform-dependent string containing one letter: + * - b for big-endian, ASCII-family platforms + * - l for little-endian, ASCII-family platforms + * - e for big-endian, EBCDIC-family platforms + * This letter is part of the common data file name. + * @stable ICU 2.0 + */ + +/** + * \def U_ICUDATA_TYPE_LITLETTER + * The non-string form of U_ICUDATA_TYPE_LETTER + * @stable ICU 2.0 + */ +#if U_CHARSET_FAMILY +# if U_IS_BIG_ENDIAN + /* EBCDIC - should always be BE */ +# define U_ICUDATA_TYPE_LETTER "e" +# define U_ICUDATA_TYPE_LITLETTER e +# else +# error "Don't know what to do with little endian EBCDIC!" +# define U_ICUDATA_TYPE_LETTER "x" +# define U_ICUDATA_TYPE_LITLETTER x +# endif +#else +# if U_IS_BIG_ENDIAN + /* Big-endian ASCII */ +# define U_ICUDATA_TYPE_LETTER "b" +# define U_ICUDATA_TYPE_LITLETTER b +# else + /* Little-endian ASCII */ +# define U_ICUDATA_TYPE_LETTER "l" +# define U_ICUDATA_TYPE_LITLETTER l +# endif +#endif + +/** + * A single string literal containing the icudata stub name. i.e. 'icudt18e' for + * ICU 1.8.x on EBCDIC, etc.. + * @stable ICU 2.0 + */ +#define U_ICUDATA_NAME "icudt" U_ICU_VERSION_SHORT U_ICUDATA_TYPE_LETTER + + +/** + * U_ICU_ENTRY_POINT is the name of the DLL entry point to the ICU data library. + * Defined as a literal, not a string. + * Tricky Preprocessor use - ## operator replaces macro paramters with the literal string + * from the corresponding macro invocation, _before_ other macro substitutions. + * Need a nested \#defines to get the actual version numbers rather than + * the literal text U_ICU_VERSION_MAJOR_NUM into the name. + * The net result will be something of the form + * \#define U_ICU_ENTRY_POINT icudt19_dat + * @stable ICU 2.4 + */ +#define U_ICUDATA_ENTRY_POINT U_DEF2_ICUDATA_ENTRY_POINT(U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM) + +/** + * Do not use. + * @internal + */ +#define U_DEF2_ICUDATA_ENTRY_POINT(major, minor) U_DEF_ICUDATA_ENTRY_POINT(major, minor) +/** + * Do not use. + * @internal + */ +#define U_DEF_ICUDATA_ENTRY_POINT(major, minor) icudt##major##minor##_dat + +/** + * \def U_CALLCONV + * Similar to U_CDECL_BEGIN/U_CDECL_END, this qualifier is necessary + * in callback function typedefs to make sure that the calling convention + * is compatible. + * + * This is only used for non-ICU-API functions. + * When a function is a public ICU API, + * you must use the U_CAPI and U_EXPORT2 qualifiers. + * @stable ICU 2.0 + */ +#if defined(OS390) && (__COMPILER_VER__ < 0x41020000) && defined(XP_CPLUSPLUS) +# define U_CALLCONV __cdecl +#else +# define U_CALLCONV U_EXPORT2 +#endif + +/** + * \def NULL + * Define NULL if necessary, to 0 for C++ and to ((void *)0) for C. + * @stable ICU 2.0 + */ +#ifndef NULL +#ifdef XP_CPLUSPLUS +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +/*===========================================================================*/ +/* Calendar/TimeZone data types */ +/*===========================================================================*/ + +/** + * Date and Time data type. + * This is a primitive data type that holds the date and time + * as the number of milliseconds since 1970-jan-01, 00:00 UTC. + * UTC leap seconds are ignored. + * @stable ICU 2.0 + */ +typedef double UDate; + +/** The number of milliseconds per second @stable ICU 2.0 */ +#define U_MILLIS_PER_SECOND (1000) +/** The number of milliseconds per minute @stable ICU 2.0 */ +#define U_MILLIS_PER_MINUTE (60000) +/** The number of milliseconds per hour @stable ICU 2.0 */ +#define U_MILLIS_PER_HOUR (3600000) +/** The number of milliseconds per day @stable ICU 2.0 */ +#define U_MILLIS_PER_DAY (86400000) + + +/*===========================================================================*/ +/* UClassID-based RTTI */ +/*===========================================================================*/ + +/** + * UClassID is used to identify classes without using RTTI, since RTTI + * is not yet supported by all C++ compilers. Each class hierarchy which needs + * to implement polymorphic clone() or operator==() defines two methods, + * described in detail below. UClassID values can be compared using + * operator==(). Nothing else should be done with them. + * + * \par + * getDynamicClassID() is declared in the base class of the hierarchy as + * a pure virtual. Each concrete subclass implements it in the same way: + * + * \code + * class Base { + * public: + * virtual UClassID getDynamicClassID() const = 0; + * } + * + * class Derived { + * public: + * virtual UClassID getDynamicClassID() const + * { return Derived::getStaticClassID(); } + * } + * \endcode + * + * Each concrete class implements getStaticClassID() as well, which allows + * clients to test for a specific type. + * + * \code + * class Derived { + * public: + * static UClassID U_EXPORT2 getStaticClassID(); + * private: + * static char fgClassID; + * } + * + * // In Derived.cpp: + * UClassID Derived::getStaticClassID() + * { return (UClassID)&Derived::fgClassID; } + * char Derived::fgClassID = 0; // Value is irrelevant + * \endcode + * @stable ICU 2.0 + */ +typedef void* UClassID; + +/*===========================================================================*/ +/* Shared library/DLL import-export API control */ +/*===========================================================================*/ + +/* + * Control of symbol import/export. + * ICU is separated into three libraries. + */ + +/* + * \def U_COMBINED_IMPLEMENTATION + * Set to export library symbols from inside the ICU library + * when all of ICU is in a single library. + * This can be set as a compiler option while building ICU, and it + * needs to be the first one tested to override U_COMMON_API, U_I18N_API, etc. + * @stable ICU 2.0 + */ + +/** + * \def U_DATA_API + * Set to export library symbols from inside the stubdata library, + * and to import them from outside. + * @stable ICU 3.0 + */ + +/** + * \def U_COMMON_API + * Set to export library symbols from inside the common library, + * and to import them from outside. + * @stable ICU 2.0 + */ + +/** + * \def U_I18N_API + * Set to export library symbols from inside the i18n library, + * and to import them from outside. + * @stable ICU 2.0 + */ + +/** + * \def U_LAYOUT_API + * Set to export library symbols from inside the layout engine library, + * and to import them from outside. + * @stable ICU 2.0 + */ + +/** + * \def U_LAYOUTEX_API + * Set to export library symbols from inside the layout extensions library, + * and to import them from outside. + * @stable ICU 2.6 + */ + +/** + * \def U_IO_API + * Set to export library symbols from inside the ustdio library, + * and to import them from outside. + * @stable ICU 2.0 + */ + +/** + * \def U_TOOLUTIL_API + * Set to export library symbols from inside the toolutil library, + * and to import them from outside. + * @stable ICU 3.4 + */ + +#if defined(U_COMBINED_IMPLEMENTATION) +#define U_DATA_API U_EXPORT +#define U_COMMON_API U_EXPORT +#define U_I18N_API U_EXPORT +#define U_LAYOUT_API U_EXPORT +#define U_LAYOUTEX_API U_EXPORT +#define U_IO_API U_EXPORT +#define U_TOOLUTIL_API U_EXPORT +#elif defined(U_STATIC_IMPLEMENTATION) +#define U_DATA_API +#define U_COMMON_API +#define U_I18N_API +#define U_LAYOUT_API +#define U_LAYOUTEX_API +#define U_IO_API +#define U_TOOLUTIL_API +#elif defined(U_COMMON_IMPLEMENTATION) +#define U_DATA_API U_IMPORT +#define U_COMMON_API U_EXPORT +#define U_I18N_API U_IMPORT +#define U_LAYOUT_API U_IMPORT +#define U_LAYOUTEX_API U_IMPORT +#define U_IO_API U_IMPORT +#define U_TOOLUTIL_API U_IMPORT +#elif defined(U_I18N_IMPLEMENTATION) +#define U_DATA_API U_IMPORT +#define U_COMMON_API U_IMPORT +#define U_I18N_API U_EXPORT +#define U_LAYOUT_API U_IMPORT +#define U_LAYOUTEX_API U_IMPORT +#define U_IO_API U_IMPORT +#define U_TOOLUTIL_API U_IMPORT +#elif defined(U_LAYOUT_IMPLEMENTATION) +#define U_DATA_API U_IMPORT +#define U_COMMON_API U_IMPORT +#define U_I18N_API U_IMPORT +#define U_LAYOUT_API U_EXPORT +#define U_LAYOUTEX_API U_IMPORT +#define U_IO_API U_IMPORT +#define U_TOOLUTIL_API U_IMPORT +#elif defined(U_LAYOUTEX_IMPLEMENTATION) +#define U_DATA_API U_IMPORT +#define U_COMMON_API U_IMPORT +#define U_I18N_API U_IMPORT +#define U_LAYOUT_API U_IMPORT +#define U_LAYOUTEX_API U_EXPORT +#define U_IO_API U_IMPORT +#define U_TOOLUTIL_API U_IMPORT +#elif defined(U_IO_IMPLEMENTATION) +#define U_DATA_API U_IMPORT +#define U_COMMON_API U_IMPORT +#define U_I18N_API U_IMPORT +#define U_LAYOUT_API U_IMPORT +#define U_LAYOUTEX_API U_IMPORT +#define U_IO_API U_EXPORT +#define U_TOOLUTIL_API U_IMPORT +#elif defined(U_TOOLUTIL_IMPLEMENTATION) +#define U_DATA_API U_IMPORT +#define U_COMMON_API U_IMPORT +#define U_I18N_API U_IMPORT +#define U_LAYOUT_API U_IMPORT +#define U_LAYOUTEX_API U_IMPORT +#define U_IO_API U_IMPORT +#define U_TOOLUTIL_API U_EXPORT +#else +#define U_DATA_API U_IMPORT +#define U_COMMON_API U_IMPORT +#define U_I18N_API U_IMPORT +#define U_LAYOUT_API U_IMPORT +#define U_LAYOUTEX_API U_IMPORT +#define U_IO_API U_IMPORT +#define U_TOOLUTIL_API U_IMPORT +#endif + +/** + * \def U_STANDARD_CPP_NAMESPACE + * Control of C++ Namespace + * @stable ICU 2.0 + */ +#ifdef __cplusplus +#define U_STANDARD_CPP_NAMESPACE :: +#else +#define U_STANDARD_CPP_NAMESPACE +#endif + + +/*===========================================================================*/ +/* Global delete operator */ +/*===========================================================================*/ + +/* + * The ICU4C library must not use the global new and delete operators. + * These operators here are defined to enable testing for this. + * See Jitterbug 2581 for details of why this is necessary. + * + * Verification that ICU4C's memory usage is correct, i.e., + * that global new/delete are not used: + * + * a) Check for imports of global new/delete (see uobject.cpp for details) + * b) Verify that new is never imported. + * c) Verify that delete is only imported from object code for interface/mixin classes. + * d) Add global delete and delete[] only for the ICU4C library itself + * and define them in a way that crashes or otherwise easily shows a problem. + * + * The following implements d). + * The operator implementations crash; this is intentional and used for library debugging. + * + * Note: This is currently only done on Windows because + * some Linux/Unix compilers have problems with defining global new/delete. + * On Windows, U_WINDOWS is defined, and it is _MSC_VER>=1200 for MSVC 6.0 and higher. + */ +#if defined(XP_CPLUSPLUS) && defined(U_WINDOWS) && U_DEBUG && U_OVERRIDE_CXX_ALLOCATION && (_MSC_VER>=1200) && !defined(U_STATIC_IMPLEMENTATION) && (defined(U_COMMON_IMPLEMENTATION) || defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION) || defined(U_LAYOUT_IMPLEMENTATION) || defined(U_LAYOUTEX_IMPLEMENTATION)) + +#ifndef U_HIDE_INTERNAL_API +/** + * Global operator new, defined only inside ICU4C, must not be used. + * Crashes intentionally. + * @internal + */ +inline void * +operator new(size_t /*size*/) { + char *q=NULL; + *q=5; /* break it */ + return q; +} + +#ifdef _Ret_bytecap_ +/* This is only needed to suppress a Visual C++ 2008 warning for operator new[]. */ +_Ret_bytecap_(_Size) +#endif +/** + * Global operator new[], defined only inside ICU4C, must not be used. + * Crashes intentionally. + * @internal + */ +inline void * +operator new[](size_t /*size*/) { + char *q=NULL; + *q=5; /* break it */ + return q; +} + +/** + * Global operator delete, defined only inside ICU4C, must not be used. + * Crashes intentionally. + * @internal + */ +inline void +operator delete(void * /*p*/) { + char *q=NULL; + *q=5; /* break it */ +} + +/** + * Global operator delete[], defined only inside ICU4C, must not be used. + * Crashes intentionally. + * @internal + */ +inline void +operator delete[](void * /*p*/) { + char *q=NULL; + *q=5; /* break it */ +} + +#endif /* U_HIDE_INTERNAL_API */ +#endif + +/*===========================================================================*/ +/* UErrorCode */ +/*===========================================================================*/ + +/** + * Error code to replace exception handling, so that the code is compatible with all C++ compilers, + * and to use the same mechanism for C and C++. + * + * \par + * ICU functions that take a reference (C++) or a pointer (C) to a UErrorCode + * first test if(U_FAILURE(errorCode)) { return immediately; } + * so that in a chain of such functions the first one that sets an error code + * causes the following ones to not perform any operations. + * + * \par + * Error codes should be tested using U_FAILURE() and U_SUCCESS(). + * @stable ICU 2.0 + */ +typedef enum UErrorCode { + /* The ordering of U_ERROR_INFO_START Vs U_USING_FALLBACK_WARNING looks weird + * and is that way because VC++ debugger displays first encountered constant, + * which is not the what the code is used for + */ + + U_USING_FALLBACK_WARNING = -128, /**< A resource bundle lookup returned a fallback result (not an error) */ + + U_ERROR_WARNING_START = -128, /**< Start of information results (semantically successful) */ + + U_USING_DEFAULT_WARNING = -127, /**< A resource bundle lookup returned a result from the root locale (not an error) */ + + U_SAFECLONE_ALLOCATED_WARNING = -126, /**< A SafeClone operation required allocating memory (informational only) */ + + U_STATE_OLD_WARNING = -125, /**< ICU has to use compatibility layer to construct the service. Expect performance/memory usage degradation. Consider upgrading */ + + U_STRING_NOT_TERMINATED_WARNING = -124,/**< An output string could not be NUL-terminated because output length==destCapacity. */ + + U_SORT_KEY_TOO_SHORT_WARNING = -123, /**< Number of levels requested in getBound is higher than the number of levels in the sort key */ + + U_AMBIGUOUS_ALIAS_WARNING = -122, /**< This converter alias can go to different converter implementations */ + + U_DIFFERENT_UCA_VERSION = -121, /**< ucol_open encountered a mismatch between UCA version and collator image version, so the collator was constructed from rules. No impact to further function */ + + U_ERROR_WARNING_LIMIT, /**< This must always be the last warning value to indicate the limit for UErrorCode warnings (last warning code +1) */ + + + U_ZERO_ERROR = 0, /**< No error, no warning. */ + + U_ILLEGAL_ARGUMENT_ERROR = 1, /**< Start of codes indicating failure */ + U_MISSING_RESOURCE_ERROR = 2, /**< The requested resource cannot be found */ + U_INVALID_FORMAT_ERROR = 3, /**< Data format is not what is expected */ + U_FILE_ACCESS_ERROR = 4, /**< The requested file cannot be found */ + U_INTERNAL_PROGRAM_ERROR = 5, /**< Indicates a bug in the library code */ + U_MESSAGE_PARSE_ERROR = 6, /**< Unable to parse a message (message format) */ + U_MEMORY_ALLOCATION_ERROR = 7, /**< Memory allocation error */ + U_INDEX_OUTOFBOUNDS_ERROR = 8, /**< Trying to access the index that is out of bounds */ + U_PARSE_ERROR = 9, /**< Equivalent to Java ParseException */ + U_INVALID_CHAR_FOUND = 10, /**< Character conversion: Unmappable input sequence. In other APIs: Invalid character. */ + U_TRUNCATED_CHAR_FOUND = 11, /**< Character conversion: Incomplete input sequence. */ + U_ILLEGAL_CHAR_FOUND = 12, /**< Character conversion: Illegal input sequence/combination of input units. */ + U_INVALID_TABLE_FORMAT = 13, /**< Conversion table file found, but corrupted */ + U_INVALID_TABLE_FILE = 14, /**< Conversion table file not found */ + U_BUFFER_OVERFLOW_ERROR = 15, /**< A result would not fit in the supplied buffer */ + U_UNSUPPORTED_ERROR = 16, /**< Requested operation not supported in current context */ + U_RESOURCE_TYPE_MISMATCH = 17, /**< an operation is requested over a resource that does not support it */ + U_ILLEGAL_ESCAPE_SEQUENCE = 18, /**< ISO-2022 illlegal escape sequence */ + U_UNSUPPORTED_ESCAPE_SEQUENCE = 19, /**< ISO-2022 unsupported escape sequence */ + U_NO_SPACE_AVAILABLE = 20, /**< No space available for in-buffer expansion for Arabic shaping */ + U_CE_NOT_FOUND_ERROR = 21, /**< Currently used only while setting variable top, but can be used generally */ + U_PRIMARY_TOO_LONG_ERROR = 22, /**< User tried to set variable top to a primary that is longer than two bytes */ + U_STATE_TOO_OLD_ERROR = 23, /**< ICU cannot construct a service from this state, as it is no longer supported */ + U_TOO_MANY_ALIASES_ERROR = 24, /**< There are too many aliases in the path to the requested resource. + It is very possible that a circular alias definition has occured */ + U_ENUM_OUT_OF_SYNC_ERROR = 25, /**< UEnumeration out of sync with underlying collection */ + U_INVARIANT_CONVERSION_ERROR = 26, /**< Unable to convert a UChar* string to char* with the invariant converter. */ + U_INVALID_STATE_ERROR = 27, /**< Requested operation can not be completed with ICU in its current state */ + U_COLLATOR_VERSION_MISMATCH = 28, /**< Collator version is not compatible with the base version */ + U_USELESS_COLLATOR_ERROR = 29, /**< Collator is options only and no base is specified */ + U_NO_WRITE_PERMISSION = 30, /**< Attempt to modify read-only or constant data. */ + + U_STANDARD_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for standard errors */ + /* + * the error code range 0x10000 0x10100 are reserved for Transliterator + */ + U_BAD_VARIABLE_DEFINITION=0x10000,/**< Missing '$' or duplicate variable name */ + U_PARSE_ERROR_START = 0x10000, /**< Start of Transliterator errors */ + U_MALFORMED_RULE, /**< Elements of a rule are misplaced */ + U_MALFORMED_SET, /**< A UnicodeSet pattern is invalid*/ + U_MALFORMED_SYMBOL_REFERENCE, /**< UNUSED as of ICU 2.4 */ + U_MALFORMED_UNICODE_ESCAPE, /**< A Unicode escape pattern is invalid*/ + U_MALFORMED_VARIABLE_DEFINITION, /**< A variable definition is invalid */ + U_MALFORMED_VARIABLE_REFERENCE, /**< A variable reference is invalid */ + U_MISMATCHED_SEGMENT_DELIMITERS, /**< UNUSED as of ICU 2.4 */ + U_MISPLACED_ANCHOR_START, /**< A start anchor appears at an illegal position */ + U_MISPLACED_CURSOR_OFFSET, /**< A cursor offset occurs at an illegal position */ + U_MISPLACED_QUANTIFIER, /**< A quantifier appears after a segment close delimiter */ + U_MISSING_OPERATOR, /**< A rule contains no operator */ + U_MISSING_SEGMENT_CLOSE, /**< UNUSED as of ICU 2.4 */ + U_MULTIPLE_ANTE_CONTEXTS, /**< More than one ante context */ + U_MULTIPLE_CURSORS, /**< More than one cursor */ + U_MULTIPLE_POST_CONTEXTS, /**< More than one post context */ + U_TRAILING_BACKSLASH, /**< A dangling backslash */ + U_UNDEFINED_SEGMENT_REFERENCE, /**< A segment reference does not correspond to a defined segment */ + U_UNDEFINED_VARIABLE, /**< A variable reference does not correspond to a defined variable */ + U_UNQUOTED_SPECIAL, /**< A special character was not quoted or escaped */ + U_UNTERMINATED_QUOTE, /**< A closing single quote is missing */ + U_RULE_MASK_ERROR, /**< A rule is hidden by an earlier more general rule */ + U_MISPLACED_COMPOUND_FILTER, /**< A compound filter is in an invalid location */ + U_MULTIPLE_COMPOUND_FILTERS, /**< More than one compound filter */ + U_INVALID_RBT_SYNTAX, /**< A "::id" rule was passed to the RuleBasedTransliterator parser */ + U_INVALID_PROPERTY_PATTERN, /**< UNUSED as of ICU 2.4 */ + U_MALFORMED_PRAGMA, /**< A 'use' pragma is invlalid */ + U_UNCLOSED_SEGMENT, /**< A closing ')' is missing */ + U_ILLEGAL_CHAR_IN_SEGMENT, /**< UNUSED as of ICU 2.4 */ + U_VARIABLE_RANGE_EXHAUSTED, /**< Too many stand-ins generated for the given variable range */ + U_VARIABLE_RANGE_OVERLAP, /**< The variable range overlaps characters used in rules */ + U_ILLEGAL_CHARACTER, /**< A special character is outside its allowed context */ + U_INTERNAL_TRANSLITERATOR_ERROR, /**< Internal transliterator system error */ + U_INVALID_ID, /**< A "::id" rule specifies an unknown transliterator */ + U_INVALID_FUNCTION, /**< A "&fn()" rule specifies an unknown transliterator */ + U_PARSE_ERROR_LIMIT, /**< The limit for Transliterator errors */ + + /* + * the error code range 0x10100 0x10200 are reserved for formatting API parsing error + */ + U_UNEXPECTED_TOKEN=0x10100, /**< Syntax error in format pattern */ + U_FMT_PARSE_ERROR_START=0x10100, /**< Start of format library errors */ + U_MULTIPLE_DECIMAL_SEPARATORS, /**< More than one decimal separator in number pattern */ + U_MULTIPLE_DECIMAL_SEPERATORS = U_MULTIPLE_DECIMAL_SEPARATORS, /**< Typo: kept for backward compatibility. Use U_MULTIPLE_DECIMAL_SEPARATORS */ + U_MULTIPLE_EXPONENTIAL_SYMBOLS, /**< More than one exponent symbol in number pattern */ + U_MALFORMED_EXPONENTIAL_PATTERN, /**< Grouping symbol in exponent pattern */ + U_MULTIPLE_PERCENT_SYMBOLS, /**< More than one percent symbol in number pattern */ + U_MULTIPLE_PERMILL_SYMBOLS, /**< More than one permill symbol in number pattern */ + U_MULTIPLE_PAD_SPECIFIERS, /**< More than one pad symbol in number pattern */ + U_PATTERN_SYNTAX_ERROR, /**< Syntax error in format pattern */ + U_ILLEGAL_PAD_POSITION, /**< Pad symbol misplaced in number pattern */ + U_UNMATCHED_BRACES, /**< Braces do not match in message pattern */ + U_UNSUPPORTED_PROPERTY, /**< UNUSED as of ICU 2.4 */ + U_UNSUPPORTED_ATTRIBUTE, /**< UNUSED as of ICU 2.4 */ + U_ARGUMENT_TYPE_MISMATCH, /**< Argument name and argument index mismatch in MessageFormat functions */ + U_DUPLICATE_KEYWORD, /**< Duplicate keyword in PluralFormat */ + U_UNDEFINED_KEYWORD, /**< Undefined Pluarl keyword */ + U_DEFAULT_KEYWORD_MISSING, /**< Missing DEFAULT rule in plural rules */ + U_FMT_PARSE_ERROR_LIMIT, /**< The limit for format library errors */ + + /* + * the error code range 0x10200 0x102ff are reserved for Break Iterator related error + */ + U_BRK_INTERNAL_ERROR=0x10200, /**< An internal error (bug) was detected. */ + U_BRK_ERROR_START=0x10200, /**< Start of codes indicating Break Iterator failures */ + U_BRK_HEX_DIGITS_EXPECTED, /**< Hex digits expected as part of a escaped char in a rule. */ + U_BRK_SEMICOLON_EXPECTED, /**< Missing ';' at the end of a RBBI rule. */ + U_BRK_RULE_SYNTAX, /**< Syntax error in RBBI rule. */ + U_BRK_UNCLOSED_SET, /**< UnicodeSet witing an RBBI rule missing a closing ']'. */ + U_BRK_ASSIGN_ERROR, /**< Syntax error in RBBI rule assignment statement. */ + U_BRK_VARIABLE_REDFINITION, /**< RBBI rule $Variable redefined. */ + U_BRK_MISMATCHED_PAREN, /**< Mis-matched parentheses in an RBBI rule. */ + U_BRK_NEW_LINE_IN_QUOTED_STRING, /**< Missing closing quote in an RBBI rule. */ + U_BRK_UNDEFINED_VARIABLE, /**< Use of an undefined $Variable in an RBBI rule. */ + U_BRK_INIT_ERROR, /**< Initialization failure. Probable missing ICU Data. */ + U_BRK_RULE_EMPTY_SET, /**< Rule contains an empty Unicode Set. */ + U_BRK_UNRECOGNIZED_OPTION, /**< !!option in RBBI rules not recognized. */ + U_BRK_MALFORMED_RULE_TAG, /**< The {nnn} tag on a rule is mal formed */ + U_BRK_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for Break Iterator failures */ + + /* + * The error codes in the range 0x10300-0x103ff are reserved for regular expression related errrs + */ + U_REGEX_INTERNAL_ERROR=0x10300, /**< An internal error (bug) was detected. */ + U_REGEX_ERROR_START=0x10300, /**< Start of codes indicating Regexp failures */ + U_REGEX_RULE_SYNTAX, /**< Syntax error in regexp pattern. */ + U_REGEX_INVALID_STATE, /**< RegexMatcher in invalid state for requested operation */ + U_REGEX_BAD_ESCAPE_SEQUENCE, /**< Unrecognized backslash escape sequence in pattern */ + U_REGEX_PROPERTY_SYNTAX, /**< Incorrect Unicode property */ + U_REGEX_UNIMPLEMENTED, /**< Use of regexp feature that is not yet implemented. */ + U_REGEX_MISMATCHED_PAREN, /**< Incorrectly nested parentheses in regexp pattern. */ + U_REGEX_NUMBER_TOO_BIG, /**< Decimal number is too large. */ + U_REGEX_BAD_INTERVAL, /**< Error in {min,max} interval */ + U_REGEX_MAX_LT_MIN, /**< In {min,max}, max is less than min. */ + U_REGEX_INVALID_BACK_REF, /**< Back-reference to a non-existent capture group. */ + U_REGEX_INVALID_FLAG, /**< Invalid value for match mode flags. */ + U_REGEX_LOOK_BEHIND_LIMIT, /**< Look-Behind pattern matches must have a bounded maximum length. */ + U_REGEX_SET_CONTAINS_STRING, /**< Regexps cannot have UnicodeSets containing strings.*/ + U_REGEX_OCTAL_TOO_BIG, /**< Octal character constants must be <= 0377. */ + U_REGEX_MISSING_CLOSE_BRACKET, /**< Missing closing bracket on a bracket expression. */ + U_REGEX_INVALID_RANGE, /**< In a character range [x-y], x is greater than y. */ + U_REGEX_STACK_OVERFLOW, /**< Regular expression backtrack stack overflow. */ + U_REGEX_TIME_OUT, /**< Maximum allowed match time exceeded */ + U_REGEX_STOPPED_BY_CALLER, /**< Matching operation aborted by user callback fn. */ + U_REGEX_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for regexp errors */ + + /* + * The error code in the range 0x10400-0x104ff are reserved for IDNA related error codes + */ + U_IDNA_PROHIBITED_ERROR=0x10400, + U_IDNA_ERROR_START=0x10400, + U_IDNA_UNASSIGNED_ERROR, + U_IDNA_CHECK_BIDI_ERROR, + U_IDNA_STD3_ASCII_RULES_ERROR, + U_IDNA_ACE_PREFIX_ERROR, + U_IDNA_VERIFICATION_ERROR, + U_IDNA_LABEL_TOO_LONG_ERROR, + U_IDNA_ZERO_LENGTH_LABEL_ERROR, + U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR, + U_IDNA_ERROR_LIMIT, + /* + * Aliases for StringPrep + */ + U_STRINGPREP_PROHIBITED_ERROR = U_IDNA_PROHIBITED_ERROR, + U_STRINGPREP_UNASSIGNED_ERROR = U_IDNA_UNASSIGNED_ERROR, + U_STRINGPREP_CHECK_BIDI_ERROR = U_IDNA_CHECK_BIDI_ERROR, + + + U_ERROR_LIMIT=U_IDNA_ERROR_LIMIT /**< This must always be the last value to indicate the limit for UErrorCode (last error code +1) */ +} UErrorCode; + +/* Use the following to determine if an UErrorCode represents */ +/* operational success or failure. */ + +#ifdef XP_CPLUSPLUS + /** + * Does the error code indicate success? + * @stable ICU 2.0 + */ + static + inline UBool U_SUCCESS(UErrorCode code) { return (UBool)(code<=U_ZERO_ERROR); } + /** + * Does the error code indicate a failure? + * @stable ICU 2.0 + */ + static + inline UBool U_FAILURE(UErrorCode code) { return (UBool)(code>U_ZERO_ERROR); } +#else + /** + * Does the error code indicate success? + * @stable ICU 2.0 + */ +# define U_SUCCESS(x) ((x)<=U_ZERO_ERROR) + /** + * Does the error code indicate a failure? + * @stable ICU 2.0 + */ +# define U_FAILURE(x) ((x)>U_ZERO_ERROR) +#endif + +/** + * Return a string for a UErrorCode value. + * The string will be the same as the name of the error code constant + * in the UErrorCode enum above. + * @stable ICU 2.0 + */ +U_STABLE const char * U_EXPORT2 +u_errorName(UErrorCode code); + + +#endif /* _UTYPES */ diff --git a/utils/openttd/unicode/uversion.h b/utils/openttd/unicode/uversion.h new file mode 100644 index 00000000000..5bf7fda5965 --- /dev/null +++ b/utils/openttd/unicode/uversion.h @@ -0,0 +1,275 @@ +/* +******************************************************************************* +* Copyright (C) 2000-2008, International Business Machines +* Corporation and others. All Rights Reserved. +******************************************************************************* +* +* file name: uversion.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* Created by: Vladimir Weinstein +* +* Contains all the important version numbers for ICU. +* Gets included by utypes.h and Windows .rc files +*/ + +/** + * \file + * \brief C API: Contains all the important version numbers for ICU. + */ +/*===========================================================================*/ +/* Main ICU version information */ +/*===========================================================================*/ + +#ifndef UVERSION_H +#define UVERSION_H + +/** + * IMPORTANT: When updating version, the following things need to be done: + * source/common/unicode/uversion.h - this file: update major, minor, + * patchlevel, suffix, version, short version constants, namespace, + * and copyright + * source/common/common.vcproj - update 'Output file name' on the link tab so + * that it contains the new major/minor combination + * source/i18n/i18n.vcproj - same as for the common.vcproj + * source/layout/layout.vcproj - same as for the common.vcproj + * source/layoutex/layoutex.vcproj - same + * source/stubdata/stubdata.vcproj - same as for the common.vcproj + * source/io/io.vcproj - same as for the common.vcproj + * source/data/makedata.mak - change U_ICUDATA_NAME so that it contains + * the new major/minor combination + * source/tools/genren/genren.pl - use this script according to the README + * in that folder + */ + +#include "unicode/umachine.h" + +/** The standard copyright notice that gets compiled into each library. + * This value will change in the subsequent releases of ICU + * @stable ICU 2.4 + */ +#define U_COPYRIGHT_STRING \ + " Copyright (C) 2008, International Business Machines Corporation and others. All Rights Reserved. " + +/** Maximum length of the copyright string. + * @stable ICU 2.4 + */ +#define U_COPYRIGHT_STRING_LENGTH 128 + +/** The current ICU major version as an integer. + * This value will change in the subsequent releases of ICU + * @stable ICU 2.4 + */ +#define U_ICU_VERSION_MAJOR_NUM 4 + +/** The current ICU minor version as an integer. + * This value will change in the subsequent releases of ICU + * @stable ICU 2.6 + */ +#define U_ICU_VERSION_MINOR_NUM 0 + +/** The current ICU patchlevel version as an integer. + * This value will change in the subsequent releases of ICU + * @stable ICU 2.4 + */ +#define U_ICU_VERSION_PATCHLEVEL_NUM 0 + +/** The current ICU build level version as an integer. + * This value is for use by ICU clients. It defaults to 0. + * @draft ICU 4.0 + */ +#ifndef U_ICU_VERSION_BUILDLEVEL_NUM +#define U_ICU_VERSION_BUILDLEVEL_NUM 0 +#endif + +/** Glued version suffix for renamers + * This value will change in the subsequent releases of ICU + * @stable ICU 2.6 + */ +#define U_ICU_VERSION_SUFFIX _4_0 + +/** The current ICU library version as a dotted-decimal string. The patchlevel + * only appears in this string if it non-zero. + * This value will change in the subsequent releases of ICU + * @stable ICU 2.4 + */ +#define U_ICU_VERSION "4.0" + +/** The current ICU library major/minor version as a string without dots, for library name suffixes. + * This value will change in the subsequent releases of ICU + * @stable ICU 2.6 + */ +#define U_ICU_VERSION_SHORT "40" + +/** An ICU version consists of up to 4 numbers from 0..255. + * @stable ICU 2.4 + */ +#define U_MAX_VERSION_LENGTH 4 + +/** In a string, ICU version fields are delimited by dots. + * @stable ICU 2.4 + */ +#define U_VERSION_DELIMITER '.' + +/** The maximum length of an ICU version string. + * @stable ICU 2.4 + */ +#define U_MAX_VERSION_STRING_LENGTH 20 + +/** The binary form of a version on ICU APIs is an array of 4 uint8_t. + * @stable ICU 2.4 + */ +typedef uint8_t UVersionInfo[U_MAX_VERSION_LENGTH]; + +/*===========================================================================*/ +/* C++ namespace if supported. Versioned unless versioning is disabled. */ +/*===========================================================================*/ + +/** + * \def U_NAMESPACE_BEGIN + * This is used to begin a declaration of a public ICU C++ API. + * If the compiler doesn't support namespaces, this does nothing. + * @stable ICU 2.4 + */ + +/** + * \def U_NAMESPACE_END + * This is used to end a declaration of a public ICU C++ API + * If the compiler doesn't support namespaces, this does nothing. + * @stable ICU 2.4 + */ + +/** + * \def U_NAMESPACE_USE + * This is used to specify that the rest of the code uses the + * public ICU C++ API namespace. + * If the compiler doesn't support namespaces, this does nothing. + * @stable ICU 2.4 + */ + +/** + * \def U_NAMESPACE_QUALIFIER + * This is used to qualify that a function or class is part of + * the public ICU C++ API namespace. + * If the compiler doesn't support namespaces, this does nothing. + * @stable ICU 2.4 + */ + +/* Define namespace symbols if the compiler supports it. */ +#if U_HAVE_NAMESPACE && defined(XP_CPLUSPLUS) +# if U_DISABLE_RENAMING +# define U_ICU_NAMESPACE icu + namespace U_ICU_NAMESPACE { } +# else +# define U_ICU_NAMESPACE icu_4_0 + namespace U_ICU_NAMESPACE { } + namespace icu = U_ICU_NAMESPACE; +# endif + +# define U_NAMESPACE_BEGIN namespace U_ICU_NAMESPACE { +# define U_NAMESPACE_END } +# define U_NAMESPACE_USE using namespace U_ICU_NAMESPACE; +# define U_NAMESPACE_QUALIFIER U_ICU_NAMESPACE:: + +# ifndef U_USING_ICU_NAMESPACE +# define U_USING_ICU_NAMESPACE 1 +# endif +# if U_USING_ICU_NAMESPACE + U_NAMESPACE_USE +# endif +#else +# define U_NAMESPACE_BEGIN +# define U_NAMESPACE_END +# define U_NAMESPACE_USE +# define U_NAMESPACE_QUALIFIER +#endif + + +/*===========================================================================*/ +/* General version helper functions. Definitions in putil.c */ +/*===========================================================================*/ + +/** + * Parse a string with dotted-decimal version information and + * fill in a UVersionInfo structure with the result. + * Definition of this function lives in putil.c + * + * @param versionArray The destination structure for the version information. + * @param versionString A string with dotted-decimal version information, + * with up to four non-negative number fields with + * values of up to 255 each. + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +u_versionFromString(UVersionInfo versionArray, const char *versionString); + +/** + * Write a string with dotted-decimal version information according + * to the input UVersionInfo. + * Definition of this function lives in putil.c + * + * @param versionArray The version information to be written as a string. + * @param versionString A string buffer that will be filled in with + * a string corresponding to the numeric version + * information in versionArray. + * The buffer size must be at least U_MAX_VERSION_STRING_LENGTH. + * @stable ICU 2.4 + */ +U_STABLE void U_EXPORT2 +u_versionToString(UVersionInfo versionArray, char *versionString); + +/** + * Gets the ICU release version. The version array stores the version information + * for ICU. For example, release "1.3.31.2" is then represented as 0x01031F02. + * Definition of this function lives in putil.c + * + * @param versionArray the version # information, the result will be filled in + * @stable ICU 2.0 + */ +U_STABLE void U_EXPORT2 +u_getVersion(UVersionInfo versionArray); + + +/*=========================================================================== + * ICU collation framework version information + * Version info that can be obtained from a collator is affected by these + * numbers in a secret and magic way. Please use collator version as whole + *=========================================================================== + */ + +/** Collation runtime version (sort key generator, strcoll). + * If the version is different, sortkeys for the same string could be different + * version 2 was in ICU 1.8.1. changed is: compression intervals, French secondary + * compression, generating quad level always when strength is quad or more + * version 4 - ICU 2.2 - tracking UCA changes, ignore completely ignorables + * in contractions, ignore primary ignorables after shifted + * version 5 - ICU 2.8 - changed implicit generation code + * version 6 - ICU 3.4 - with the UCA 4.1, Thai tag is no longer generated or used + * This value may change in the subsequent releases of ICU + * @stable ICU 2.4 + */ +#define UCOL_RUNTIME_VERSION 6 + +/** Builder code version. When this is different, same tailoring might result + * in assigning different collation elements to code points + * version 2 was in ICU 1.8.1. added support for prefixes, tweaked canonical + * closure. However, the tailorings should probably get same CEs assigned + * version 5 - ICU 2.2 - fixed some bugs, renamed some indirect values. + * version 6 - ICU 2.8 - fixed bug in builder that allowed 0xFF in primary values + * version 7 - ICU 3.4 - with the UCA 4.1 Thai tag is no longer processed, complete ignorables + * now break contractions + * Backward compatible with the old rules. + * This value may change in the subsequent releases of ICU + * @stable ICU 2.4 + */ +#define UCOL_BUILDER_VERSION 7 + +/** This is the version of the tailorings + * This value may change in the subsequent releases of ICU + * @stable ICU 2.4 + */ +#define UCOL_TAILORINGS_VERSION 1 + +#endif diff --git a/utils/openttd/zconf.h b/utils/openttd/zconf.h new file mode 100644 index 00000000000..03a9431c8be --- /dev/null +++ b/utils/openttd/zconf.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include <sys/types.h> /* for off_t */ +# include <unistd.h> /* for SEEK_* and off_t */ +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/utils/openttd/zlib.h b/utils/openttd/zlib.h new file mode 100644 index 00000000000..022817927ce --- /dev/null +++ b/utils/openttd/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ From c7773667b1e7805ce9e49538946b1b4e7d164b64 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 31 Jan 2009 14:05:03 +0000 Subject: [PATCH 03/61] On the previous update, some files did not copy, resulting in compile errors. --- Simutrans-Experimental.vcproj | 1224 ++++++++++++++++++++++++++++++++- bauer/wegbauer.h | 4 +- boden/grund.h | 2 +- dataobj/crossing_logic.cc | 6 +- dataobj/umgebung.cc | 9 +- dataobj/umgebung.h | 9 +- gui/climates.cc | 63 +- gui/climates.h | 2 + gui/fahrplan_gui.cc | 2 + gui/label_info.cc | 9 + gui/label_info.h | 3 + gui/labellist_frame_t.h | 3 + gui/welt.cc | 22 +- makeobj/Makeobj.sln | 2 +- simline.cc | 13 +- simline.h | 96 +-- simlinemgmt.cc | 6 +- 17 files changed, 1392 insertions(+), 83 deletions(-) diff --git a/Simutrans-Experimental.vcproj b/Simutrans-Experimental.vcproj index eacb3754c0f..054d166a553 100644 --- a/Simutrans-Experimental.vcproj +++ b/Simutrans-Experimental.vcproj @@ -18,8 +18,8 @@ <Configurations> <Configuration Name="Debug|Win32" - OutputDirectory="$(SolutionDir)$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" + OutputDirectory="..\simutrans-experimental-binaries\debug" + IntermediateDirectory="..\simutrans-experimental-binaries\debug\intermediates" ConfigurationType="1" CharacterSet="1" WholeProgramOptimization="1" @@ -101,8 +101,8 @@ </Configuration> <Configuration Name="Release|Win32" - OutputDirectory="$(SolutionDir)$(ConfigurationName)" - IntermediateDirectory="$(ConfigurationName)" + OutputDirectory="..\simutrans-experimental-binaries\release" + IntermediateDirectory="..\simutrans-experimental-binaries\release\intermediates" ConfigurationType="1" CharacterSet="1" WholeProgramOptimization="1" @@ -1085,14 +1085,1230 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + <File + RelativePath=".\gui\components\action_listener.h" + > + </File> + <File + RelativePath=".\player\ai.h" + > + </File> + <File + RelativePath=".\player\ai_goods.h" + > + </File> + <File + RelativePath=".\player\ai_passenger.h" + > + </File> + <File + RelativePath=".\tpl\array2d_tpl.h" + > + </File> + <File + RelativePath=".\tpl\array_tpl.h" + > + </File> + <File + RelativePath=".\gui\banner.h" + > + </File> + <File + RelativePath=".\dings\baum.h" + > + </File> + <File + RelativePath=".\besch\baum_besch.h" + > + </File> + <File + RelativePath=".\gui\baum_edit.h" + > + </File> + <File + RelativePath=".\sucher\bauplatz_sucher.h" + > + </File> + <File + RelativePath=".\besch\bild_besch.h" + > + </File> + <File + RelativePath=".\besch\bildliste2d_besch.h" + > + </File> + <File + RelativePath=".\besch\bildliste_besch.h" + > + </File> + <File + RelativePath=".\tpl\binary_heap_tpl.h" + > + </File> + <File + RelativePath=".\boden\boden.h" + > + </File> + <File + RelativePath=".\besch\reader\bridge_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\bridge_writer.h" + > + </File> + <File + RelativePath=".\dings\bruecke.h" + > + </File> + <File + RelativePath=".\besch\bruecke_besch.h" + > + </File> + <File + RelativePath=".\bauer\brueckenbauer.h" + > + </File> + <File + RelativePath=".\boden\brueckenboden.h" + > + </File> + <File + RelativePath=".\besch\reader\building_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\building_writer.h" + > + </File> + <File + RelativePath=".\utils\cbuffer_t.h" + > + </File> + <File + RelativePath=".\gui\citybuilding_edit.h" + > + </File> + <File + RelativePath=".\besch\reader\citycar_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\citycar_writer.h" + > + </File> + <File + RelativePath=".\gui\citylist_frame_t.h" + > + </File> + <File + RelativePath=".\gui\citylist_stats_t.h" + > + </File> + <File + RelativePath=".\gui\climates.h" + > + </File> + <File + RelativePath=".\gui\colors.h" + > + </File> + <File + RelativePath=".\gui\convoi_detail_t.h" + > + </File> + <File + RelativePath=".\gui\convoi_filter_frame.h" + > + </File> + <File + RelativePath=".\gui\convoi_frame.h" + > + </File> + <File + RelativePath=".\gui\convoi_info_t.h" + > + </File> + <File + RelativePath=".\convoihandle_t.h" + > + </File> + <File + RelativePath=".\dings\crossing.h" + > + </File> + <File + RelativePath=".\dataobj\crossing_logic.h" + > + </File> + <File + RelativePath=".\besch\reader\crossing_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\crossing_writer.h" + > + </File> + <File + RelativePath=".\utils\cstring_t.h" + > + </File> + <File + RelativePath=".\gui\curiosity_edit.h" + > + </File> + <File + RelativePath=".\gui\curiositylist_frame_t.h" + > + </File> + <File + RelativePath=".\gui\curiositylist_stats_t.h" + > + </File> + <File + RelativePath=".\tpl\debug_helper.h" + > + </File> + <File + RelativePath=".\gui\depot_frame.h" + > + </File> + <File + RelativePath=".\dataobj\dingliste.h" + > + </File> + <File + RelativePath=".\utils\dr_rdgif.h" + > + </File> + <File + RelativePath=".\utils\dr_rdpng.h" + > + </File> + <File + RelativePath=".\utils\dr_rdppm.h" + > + </File> + <File + RelativePath=".\dings\dummy.h" + > + </File> + <File + RelativePath=".\dataobj\einstellungen.h" + > + </File> + <File + RelativePath=".\gui\enlarge_map_frame_t.h" + > + </File> + <File + RelativePath=".\gui\extend_edit.h" + > + </File> + <File + RelativePath=".\besch\fabrik_besch.h" + > + </File> + <File + RelativePath=".\gui\fabrik_info.h" + > + </File> + <File + RelativePath=".\bauer\fabrikbauer.h" + > + </File> + <File + RelativePath=".\gui\factory_edit.h" + > + </File> + <File + RelativePath=".\besch\reader\factory_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\factory_writer.h" + > + </File> + <File + RelativePath=".\gui\factorylist_frame_t.h" + > + </File> + <File + RelativePath=".\gui\factorylist_stats_t.h" + > + </File> + <File + RelativePath=".\ifc\fahrer.h" + > + </File> + <File + RelativePath=".\dataobj\fahrplan.h" + > + </File> + <File + RelativePath=".\gui\fahrplan_gui.h" + > + </File> + <File + RelativePath=".\dings\field.h" + > + </File> <File RelativePath=".\tpl\fixed_list_tpl.h" > </File> + <File + RelativePath=".\font.h" + > + </File> + <File + RelativePath=".\dataobj\freelist.h" + > + </File> + <File + RelativePath=".\freight_list_sorter.h" + > + </File> + <File + RelativePath=".\boden\fundament.h" + > + </File> + <File + RelativePath=".\besch\fussgaenger_besch.h" + > + </File> + <File + RelativePath=".\dings\gebaeude.h" + > + </File> + <File + RelativePath=".\besch\writer\get_climate.h" + > + </File> + <File + RelativePath=".\besch\writer\get_waytype.h" + > + </File> + <File + RelativePath=".\besch\reader\good_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\good_writer.h" + > + </File> + <File + RelativePath=".\gui\goods_frame_t.h" + > + </File> + <File + RelativePath=".\gui\goods_stats_t.h" + > + </File> + <File + RelativePath=".\gui\ground_info.h" + > + </File> + <File + RelativePath=".\besch\reader\ground_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\ground_writer.h" + > + </File> + <File + RelativePath=".\dings\groundobj.h" + > + </File> + <File + RelativePath=".\besch\groundobj_besch.h" + > + </File> + <File + RelativePath=".\besch\reader\groundobj_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\groundobj_writer.h" + > + </File> + <File + RelativePath=".\boden\grund.h" + > + </File> + <File + RelativePath=".\besch\grund_besch.h" + > + </File> + <File + RelativePath=".\ifc\gui_action_creator.h" + > + </File> + <File + RelativePath=".\gui\components\gui_button.h" + > + </File> + <File + RelativePath=".\gui\components\gui_chart.h" + > + </File> + <File + RelativePath=".\gui\components\gui_combobox.h" + > + </File> + <File + RelativePath=".\gui\gui_container.h" + > + </File> + <File + RelativePath=".\gui\gui_convoiinfo.h" + > + </File> + <File + RelativePath=".\gui\components\gui_divider.h" + > + </File> + <File + RelativePath=".\ifc\gui_fenster.h" + > + </File> + <File + RelativePath=".\gui\components\gui_flowtext.h" + > + </File> + <File + RelativePath=".\gui\gui_frame.h" + > + </File> + <File + RelativePath=".\gui\components\gui_image.h" + > + </File> + <File + RelativePath=".\gui\components\gui_image_list.h" + > + </File> + <File + RelativePath=".\ifc\gui_komponente.h" + > + </File> + <File + RelativePath=".\gui\components\gui_label.h" + > + </File> + <File + RelativePath=".\gui\components\gui_numberinput.h" + > + </File> + <File + RelativePath=".\gui\components\gui_scrollbar.h" + > + </File> + <File + RelativePath=".\gui\components\gui_scrolled_list.h" + > + </File> + <File + RelativePath=".\gui\components\gui_scrollpane.h" + > + </File> + <File + RelativePath=".\gui\components\gui_speedbar.h" + > + </File> + <File + RelativePath=".\gui\components\gui_tab_panel.h" + > + </File> + <File + RelativePath=".\gui\components\gui_textarea.h" + > + </File> + <File + RelativePath=".\gui\components\gui_textinput.h" + > + </File> + <File + RelativePath=".\gui\components\gui_world_view_t.h" + > + </File> + <File + RelativePath=".\gui\halt_detail.h" + > + </File> + <File + RelativePath=".\gui\halt_info.h" + > + </File> + <File + RelativePath=".\gui\halt_list_filter_frame.h" + > + </File> + <File + RelativePath=".\gui\halt_list_frame.h" + > + </File> + <File + RelativePath=".\gui\halt_list_stats.h" + > + </File> + <File + RelativePath=".\halthandle_t.h" + > + </File> + <File + RelativePath=".\tpl\hashtable_tpl.h" + > + </File> + <File + RelativePath=".\besch\haus_besch.h" + > + </File> + <File + RelativePath=".\bauer\hausbauer.h" + > + </File> + <File + RelativePath=".\gui\help_frame.h" + > + </File> + <File + RelativePath=".\tpl\HOT_queue2_tpl.h" + > + </File> + <File + RelativePath=".\tpl\HOT_queue_tpl.h" + > + </File> + <File + RelativePath=".\besch\reader\image_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\image_writer.h" + > + </File> + <File + RelativePath=".\besch\reader\imagelist2d_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\imagelist2d_writer.h" + > + </File> + <File + RelativePath=".\besch\reader\imagelist_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\imagelist_writer.h" + > + </File> + <File + RelativePath=".\tpl\inthashtable_tpl.h" + > + </File> + <File + RelativePath=".\besch\intro_dates.h" + > + </File> + <File + RelativePath=".\gui\jump_frame.h" + > + </File> + <File + RelativePath=".\boden\wege\kanal.h" + > + </File> + <File + RelativePath=".\gui\karte.h" + > + </File> + <File + RelativePath=".\gui\kennfarbe.h" + > + </File> + <File + RelativePath=".\dataobj\koord.h" + > + </File> + <File + RelativePath=".\dataobj\koord3d.h" + > + </File> + <File + RelativePath=".\besch\kreuzung_besch.h" + > + </File> + <File + RelativePath=".\dings\label.h" + > + </File> + <File + RelativePath=".\gui\label_info.h" + > + </File> + <File + RelativePath=".\gui\labellist_frame_t.h" + > + </File> + <File + RelativePath=".\gui\labellist_stats_t.h" + > + </File> + <File + RelativePath=".\dings\lagerhaus.h" + > + </File> + <File + RelativePath=".\dings\leitung2.h" + > + </File> + <File + RelativePath=".\gui\line_item.h" + > + </File> + <File + RelativePath=".\gui\line_management_gui.h" + > + </File> + <File + RelativePath=".\linehandle_t.h" + > + </File> + <File + RelativePath=".\dataobj\linieneintrag.h" + > + </File> + <File + RelativePath=".\gui\components\list_button.h" + > + </File> + <File + RelativePath=".\gui\load_relief_frame.h" + > + </File> + <File + RelativePath=".\dataobj\loadsave.h" + > + </File> + <File + RelativePath=".\gui\loadsave_frame.h" + > + </File> + <File + RelativePath=".\utils\log.h" + > + </File> + <File + RelativePath=".\macros.h" + > + </File> + <File + RelativePath=".\boden\wege\maglev.h" + > + </File> + <File + RelativePath=".\gui\map_frame.h" + > + </File> + <File + RelativePath=".\dataobj\marker.h" + > + </File> + <File + RelativePath=".\gui\message_frame_t.h" + > + </File> + <File + RelativePath=".\gui\message_option_t.h" + > + </File> + <File + RelativePath=".\gui\message_stats_t.h" + > + </File> + <File + RelativePath=".\gui\messagebox.h" + > + </File> + <File + RelativePath=".\tpl\minivec_tpl.h" + > + </File> + <File + RelativePath=".\gui\money_frame.h" + > + </File> + <File + RelativePath=".\boden\wege\monorail.h" + > + </File> + <File + RelativePath=".\boden\monorailboden.h" + > + </File> + <File + RelativePath=".\vehicle\movingobj.h" + > + </File> + <File + RelativePath=".\music\music.h" + > + </File> + <File + RelativePath=".\boden\wege\narrowgauge.h" + > + </File> + <File + RelativePath=".\besch\obj_besch.h" + > + </File> + <File + RelativePath=".\besch\obj_besch_std_name.h" + > + </File> + <File + RelativePath=".\besch\writer\obj_node.h" + > + </File> + <File + RelativePath=".\besch\obj_node_info.h" + > + </File> + <File + RelativePath=".\besch\writer\obj_pak_exception.h" + > + </File> + <File + RelativePath=".\besch\reader\obj_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\obj_writer.h" + > + </File> + <File + RelativePath=".\besch\objversion.h" + > + </File> + <File + RelativePath=".\old_blockmanager.h" + > + </File> + <File + RelativePath=".\gui\optionen.h" + > + </File> + <File + RelativePath=".\tpl\ordered_vector_tpl.h" + > + </File> + <File + RelativePath=".\vehicle\overtaker.h" + > + </File> + <File + RelativePath=".\gui\pakselector.h" + > + </File> + <File + RelativePath=".\pathes.h" + > + </File> + <File + RelativePath=".\besch\reader\pedestrian_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\pedestrian_writer.h" + > + </File> + <File + RelativePath=".\dings\pillar.h" + > + </File> + <File + RelativePath=".\sucher\platzsucher.h" + > + </File> + <File + RelativePath=".\gui\player_frame_t.h" + > + </File> + <File + RelativePath=".\dataobj\powernet.h" + > + </File> + <File + RelativePath=".\tpl\prioqueue_tpl.h" + > + </File> + <File + RelativePath=".\tpl\ptrhashtable_tpl.h" + > + </File> + <File + RelativePath=".\tpl\quickstone_tpl.h" + > + </File> + <File + RelativePath=".\dataobj\ribi.h" + > + </File> + <File + RelativePath=".\dings\roadsign.h" + > + </File> + <File + RelativePath=".\besch\roadsign_besch.h" + > + </File> + <File + RelativePath=".\besch\reader\roadsign_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\roadsign_writer.h" + > + </File> + <File + RelativePath=".\besch\reader\root_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\root_writer.h" + > + </File> + <File + RelativePath=".\dataobj\route.h" + > + </File> + <File + RelativePath=".\boden\wege\runway.h" + > + </File> + <File + RelativePath=".\gui\savegame_frame.h" + > + </File> + <File + RelativePath=".\dataobj\scenario.h" + > + </File> + <File + RelativePath=".\gui\scenario_frame.h" + > + </File> + <File + RelativePath=".\gui\schedule_list.h" + > + </File> + <File + RelativePath=".\boden\wege\schiene.h" + > + </File> + <File + RelativePath=".\scrolltext.h" + > + </File> + <File + RelativePath=".\utils\searchfolder.h" + > + </File> + <File + RelativePath=".\dings\signal.h" + > + </File> + <File + RelativePath=".\simcity.h" + > + </File> + <File + RelativePath=".\simcolor.h" + > + </File> + <File + RelativePath=".\simconst.h" + > + </File> + <File + RelativePath=".\simconvoi.h" + > + </File> + <File + RelativePath=".\simdebug.h" + > + </File> + <File + RelativePath=".\simdepot.h" + > + </File> + <File + RelativePath=".\simdings.h" + > + </File> + <File + RelativePath=".\simevent.h" + > + </File> + <File + RelativePath=".\simfab.h" + > + </File> + <File + RelativePath=".\simgraph.h" + > + </File> + <File + RelativePath=".\simhalt.h" + > + </File> + <File + RelativePath=".\simimg.h" + > + </File> + <File + RelativePath=".\simintr.h" + > + </File> + <File + RelativePath=".\simio.h" + > + </File> + <File + RelativePath=".\simline.h" + > + </File> + <File + RelativePath=".\simlinemgmt.h" + > + </File> + <File + RelativePath=".\simmain.h" + > + </File> + <File + RelativePath=".\simmem.h" + > + </File> + <File + RelativePath=".\simmenu.h" + > + </File> + <File + RelativePath=".\simmesg.h" + > + </File> + <File + RelativePath=".\vehicle\simpeople.h" + > + </File> + <File + RelativePath=".\simplan.h" + > + </File> + <File + RelativePath=".\player\simplay.h" + > + </File> + <File + RelativePath=".\simskin.h" + > + </File> + <File + RelativePath=".\simsound.h" + > + </File> + <File + RelativePath=".\utils\simstring.h" + > + </File> + <File + RelativePath=".\simsys.h" + > + </File> + <File + RelativePath=".\simticker.h" + > + </File> + <File + RelativePath=".\simtools.h" + > + </File> + <File + RelativePath=".\simtypes.h" + > + </File> <File RelativePath=".\vehicle\simvehikel.h" > </File> + <File + RelativePath=".\vehicle\simverkehr.h" + > + </File> + <File + RelativePath=".\simversion.h" + > + </File> + <File + RelativePath=".\simview.h" + > + </File> + <File + RelativePath=".\simware.h" + > + </File> + <File + RelativePath=".\simwerkz.h" + > + </File> + <File + RelativePath=".\simwin.h" + > + </File> + <File + RelativePath=".\simworld.h" + > + </File> + <File + RelativePath=".\besch\skin_besch.h" + > + </File> + <File + RelativePath=".\besch\reader\skin_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\skin_writer.h" + > + </File> + <File + RelativePath=".\tpl\slist_tpl.h" + > + </File> + <File + RelativePath=".\tpl\sorted_heap_tpl.h" + > + </File> + <File + RelativePath=".\sound\sound.h" + > + </File> + <File + RelativePath=".\besch\sound_besch.h" + > + </File> + <File + RelativePath=".\gui\sound_frame.h" + > + </File> + <File + RelativePath=".\besch\reader\sound_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\sound_writer.h" + > + </File> + <File + RelativePath=".\besch\spezial_obj_tpl.h" + > + </File> + <File + RelativePath=".\gui\sprachen.h" + > + </File> + <File + RelativePath=".\gui\stadt_info.h" + > + </File> + <File + RelativePath=".\besch\stadtauto_besch.h" + > + </File> + <File + RelativePath=".\boden\wege\strasse.h" + > + </File> + <File + RelativePath=".\tpl\stringhashtable_tpl.h" + > + </File> + <File + RelativePath=".\ifc\sync_steppable.h" + > + </File> + <File + RelativePath=".\dataobj\tabfile.h" + > + </File> + <File + RelativePath=".\besch\text_besch.h" + > + </File> + <File + RelativePath=".\besch\reader\text_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\text_writer.h" + > + </File> + <File + RelativePath=".\gui\thing_info.h" + > + </File> + <File + RelativePath=".\dataobj\translator.h" + > + </File> + <File + RelativePath=".\besch\reader\tree_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\tree_writer.h" + > + </File> + <File + RelativePath=".\dings\tunnel.h" + > + </File> + <File + RelativePath=".\besch\tunnel_besch.h" + > + </File> + <File + RelativePath=".\besch\reader\tunnel_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\tunnel_writer.h" + > + </File> + <File + RelativePath=".\bauer\tunnelbauer.h" + > + </File> + <File + RelativePath=".\boden\tunnelboden.h" + > + </File> + <File + RelativePath=".\dataobj\umgebung.h" + > + </File> + <File + RelativePath=".\unicode.h" + > + </File> + <File + RelativePath=".\tpl\vector_tpl.h" + > + </File> + <File + RelativePath=".\besch\reader\vehicle_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\vehicle_writer.h" + > + </File> + <File + RelativePath=".\besch\vehikel_besch.h" + > + </File> + <File + RelativePath=".\bauer\vehikelbauer.h" + > + </File> + <File + RelativePath=".\besch\ware_besch.h" + > + </File> + <File + RelativePath=".\bauer\warenbauer.h" + > + </File> + <File + RelativePath=".\dataobj\warenziel.h" + > + </File> + <File + RelativePath=".\boden\wasser.h" + > + </File> + <File + RelativePath=".\besch\way_obj_besch.h" + > + </File> + <File + RelativePath=".\besch\reader\way_obj_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\way_obj_writer.h" + > + </File> + <File + RelativePath=".\besch\reader\way_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\way_writer.h" + > + </File> + <File + RelativePath=".\dings\wayobj.h" + > + </File> + <File + RelativePath=".\boden\wege\weg.h" + > + </File> + <File + RelativePath=".\besch\weg_besch.h" + > + </File> + <File + RelativePath=".\bauer\wegbauer.h" + > + </File> + <File + RelativePath=".\tpl\weighted_vector_tpl.h" + > + </File> + <File + RelativePath=".\gui\welt.h" + > + </File> + <File + RelativePath=".\gui\werkzeug_waehler.h" + > + </File> + <File + RelativePath=".\dings\wolke.h" + > + </File> + <File + RelativePath=".\besch\xref_besch.h" + > + </File> + <File + RelativePath=".\besch\reader\xref_reader.h" + > + </File> + <File + RelativePath=".\besch\writer\xref_writer.h" + > + </File> + <File + RelativePath=".\dings\zeiger.h" + > + </File> </Filter> <Filter Name="Resource Files" diff --git a/bauer/wegbauer.h b/bauer/wegbauer.h index 833a854b3f8..ca3508a9a8c 100644 --- a/bauer/wegbauer.h +++ b/bauer/wegbauer.h @@ -64,6 +64,7 @@ class wegbauer_t luft=air_wt, narrowgauge=narrowgauge_wt, leitung=powerline_wt, + river=127, bautyp_mask=255, bot_flag=0x100, // do not connect to other ways elevated_flag=0x200, // elevated structure @@ -163,11 +164,12 @@ class wegbauer_t void baue_strasse(); void baue_schiene(); void baue_leitung(); + void baue_fluss(); public: koord3d get_route_bei(int i) const { return route[i]; } - int n, max_n; + sint32 n, max_n; /** * If a way is built on top of another way, should the type diff --git a/boden/grund.h b/boden/grund.h index e10d39c0375..d16b842a674 100644 --- a/boden/grund.h +++ b/boden/grund.h @@ -376,7 +376,7 @@ class grund_t halthandle_t get_halt() const; bool is_halt() const { return flags & is_halt_flag; } - inline sint16 get_hoehe() const {return pos.z;} + inline sint8 get_hoehe() const {return pos.z;} void set_hoehe(int h) { pos.z = h;} diff --git a/dataobj/crossing_logic.cc b/dataobj/crossing_logic.cc index a4c58a6373e..159db7005d8 100644 --- a/dataobj/crossing_logic.cc +++ b/dataobj/crossing_logic.cc @@ -46,11 +46,11 @@ void crossing_logic_t::info(cbuffer_t & buf) const { static const char *state_str[4] = { "invalid", "open", "request closing", "closed" }; assert(zustand<4); - buf.append( translator::translate("\nway1 reserved by ") ); + buf.append( translator::translate("\nway1 reserved by") ); buf.append( on_way1.get_count() ); - buf.append( translator::translate("cars.\nway2 reserved by ") ); + buf.append( translator::translate("\nway1 reserved by") ); buf.append( on_way2.get_count() ); - buf.append( translator::translate( "cars.\nstate ") ); + buf.append( translator::translate( "cars.\nstate") ); buf.append( translator::translate(state_str[zustand]) ); } diff --git a/dataobj/umgebung.cc b/dataobj/umgebung.cc index e5c67b006eb..de60f87d52c 100644 --- a/dataobj/umgebung.cc +++ b/dataobj/umgebung.cc @@ -71,7 +71,14 @@ sint32 umgebung_t::intercity_road_length = 8000; * * @author Hj. Malthaner */ -cstring_t *umgebung_t::intercity_road_type = new cstring_t( "cobblestone_road" ); +const char *umgebung_t::intercity_road_type = NULL; + +const char *umgebung_t::river_type[10] = { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, +}; +uint8 umgebung_t::river_types = 0; + /* prissi: autosave every x months (0=off) */ sint32 umgebung_t::autosave = 0; diff --git a/dataobj/umgebung.h b/dataobj/umgebung.h index a0f9565d235..85d879e077e 100644 --- a/dataobj/umgebung.h +++ b/dataobj/umgebung.h @@ -170,7 +170,14 @@ class umgebung_t * * @author Hj. Malthaner */ - static cstring_t *intercity_road_type; + static const char *intercity_road_type; + + /** + * Name of rivers; first the river with the lowest number + * @author prissi + */ + static const char *river_type[10]; + static uint8 river_types; /** * show month in date? diff --git a/gui/climates.cc b/gui/climates.cc index 486456b1eff..6af72224fe0 100644 --- a/gui/climates.cc +++ b/gui/climates.cc @@ -46,7 +46,7 @@ DBG_MESSAGE("","sizeof(stat)=%d, sizeof(tm)=%d",sizeof(struct stat),sizeof(struc this->welt_gui = welt_gui; // select map stuff .. - int intTopOfButton = 16; + int intTopOfButton = 4; // mountian/water stuff water_level[0].init( button_t::repeatarrowleft, NULL, koord(LEFT_ARROW,intTopOfButton) ); @@ -134,14 +134,42 @@ DBG_MESSAGE("","sizeof(stat)=%d, sizeof(tm)=%d",sizeof(struct stat),sizeof(struc intTopOfButton += 12; // the rocky will be alway below the snow line; no need to set this explicitely + intTopOfButton += 4; - set_fenstergroesse( koord(RIGHT_ARROW+16, intTopOfButton+14+8+16) ); - - no_tree.init( button_t::square, "no tree", koord(14,intTopOfButton+7), koord(BUTTON_WIDTH,BUTTON_HEIGHT)); // right align + no_tree.init( button_t::square, "no tree", koord(10,intTopOfButton), koord(BUTTON_WIDTH,BUTTON_HEIGHT)); // right align no_tree.pressed=umgebung_t::no_tree; no_tree.add_listener( this ); add_komponente( &no_tree ); + intTopOfButton += 12+4; + + river_n.set_pos(koord(LEFT_ARROW,intTopOfButton) ); + river_n.set_groesse(koord(RIGHT_ARROW-LEFT_ARROW+10, 12)); + river_n.add_listener(this); + river_n.set_limits(0,1024); + river_n.set_value( sets->get_river_number() ); + river_n.wrap_mode( false ); + add_komponente( &river_n ); + intTopOfButton += 12; + + river_min.set_pos(koord(LEFT_ARROW,intTopOfButton) ); + river_min.set_groesse(koord(RIGHT_ARROW-LEFT_ARROW+10, 12)); + river_min.add_listener(this); + river_min.set_limits(0,1024); + river_min.set_value( sets->get_min_river_length() ); + river_min.wrap_mode( false ); + add_komponente( &river_min ); + intTopOfButton += 12; + + river_max.set_pos(koord(LEFT_ARROW,intTopOfButton) ); + river_max.set_groesse(koord(RIGHT_ARROW-LEFT_ARROW+10, 12)); + river_max.add_listener(this); + river_max.set_limits(0,1024); + river_max.set_value( sets->get_max_river_length() ); + river_max.wrap_mode( false ); + add_komponente( &river_max ); intTopOfButton += 12; + + set_fenstergroesse( koord(RIGHT_ARROW+16, intTopOfButton+4+16) ); } @@ -153,13 +181,13 @@ DBG_MESSAGE("","sizeof(stat)=%d, sizeof(tm)=%d",sizeof(struct stat),sizeof(struc * @author Hj. Malthaner */ bool -climate_gui_t::action_triggered( gui_action_creator_t *komp,value_t /* */) +climate_gui_t::action_triggered( gui_action_creator_t *komp, value_t v) { if(komp==&no_tree) { umgebung_t::no_tree ^= 1; no_tree.pressed ^= 1; welt_gui->update_preview(); - } + } else if(komp==water_level+0) { if(sets->get_grundwasser() > -10*Z_TILE_STEP ) { sets->set_grundwasser( sets->get_grundwasser() - Z_TILE_STEP ); @@ -200,7 +228,15 @@ climate_gui_t::action_triggered( gui_action_creator_t *komp,value_t /* */) welt_gui->update_preview(); } } - + else if(komp==&river_n) { + sets->set_river_number( v.i ); + } + else if(komp==&river_min) { + sets->set_min_river_length( v.i ); + } + else if(komp==&river_max) { + sets->set_max_river_length( v.i ); + } else { // all climate borders from here on sint16 *climate_borders = (sint16 *)sets->get_climate_borders(); @@ -284,14 +320,14 @@ climate_gui_t::action_triggered( gui_action_creator_t *komp,value_t /* */) void climate_gui_t::zeichnen(koord pos, koord gr) { - no_tree.pressed=umgebung_t::no_tree; + no_tree.pressed = umgebung_t::no_tree; no_tree.set_text( "no tree" ); gui_frame_t::zeichnen(pos, gr); const int x = pos.x+10; - int y = pos.y+16+16; + int y = pos.y+16+4; const sint16 water_level = (sets->get_grundwasser()/Z_TILE_STEP)+6; const sint16 *climate_borders = sets->get_climate_borders(); @@ -334,4 +370,13 @@ void climate_gui_t::zeichnen(koord pos, koord gr) display_proportional_clip(x, y, translator::translate(grund_besch_t::get_climate_name_from_bit(rocky_climate)), ALIGN_LEFT, COL_BLACK, true); display_proportional_clip(x+TEXT_RIGHT, y, ntos(climate_borders[rocky_climate], 0), ALIGN_RIGHT, COL_WHITE, true); y += 12; + + y += 12+4+4; // no tree + + display_proportional_clip(x, y, translator::translate("Number of rivers"), ALIGN_LEFT, COL_BLACK, true); + y += 12; + display_proportional_clip(x, y, translator::translate("minimum length of rivers"), ALIGN_LEFT, COL_BLACK, true); + y += 12; + display_proportional_clip(x, y, translator::translate("maximum length of rivers"), ALIGN_LEFT, COL_BLACK, true); + y += 12; } diff --git a/gui/climates.h b/gui/climates.h index 9d7666a5a67..f296a11f151 100644 --- a/gui/climates.h +++ b/gui/climates.h @@ -46,6 +46,8 @@ class climate_gui_t : public gui_frame_t, private action_listener_t button_t no_tree; // without tree + gui_numberinput_t river_n, river_min, river_max; + public: climate_gui_t(welt_gui_t* welt_gui, einstellungen_t* sets); diff --git a/gui/fahrplan_gui.cc b/gui/fahrplan_gui.cc index d077afa069d..55c2dac398c 100644 --- a/gui/fahrplan_gui.cc +++ b/gui/fahrplan_gui.cc @@ -502,7 +502,9 @@ DBG_MESSAGE("fahrplan_gui_t::action_triggered()","komp=%p combo=%p",komp,&line_s line_selector.set_selection( 0 ); } } else if (komp == &bt_promote_to_line) { + this->fpl->eingabe_abschliessen(); new_line = sp->simlinemgmt.create_line(fpl->get_type(), sp, this->fpl); + this->fpl->eingabe_beginnen(); init_line_selector(); } // recheck lines diff --git a/gui/label_info.cc b/gui/label_info.cc index 4f8883a58d1..f700ef5f16c 100644 --- a/gui/label_info.cc +++ b/gui/label_info.cc @@ -74,3 +74,12 @@ bool label_info_t::action_triggered( gui_action_creator_t *komp,value_t /* */) return true; } + + + +void label_info_t::map_rotate90( sint16 new_ysize ) +{ + koord3d l = view.get_location(); + l.rotate90( new_ysize ); + view.set_location( l ); +} diff --git a/gui/label_info.h b/gui/label_info.h index a592971865e..7874a09df31 100644 --- a/gui/label_info.h +++ b/gui/label_info.h @@ -51,6 +51,9 @@ class label_info_t : public gui_frame_t, private action_listener_t * V.Meyer */ bool action_triggered( gui_action_creator_t *komp, value_t extra); + + // rotated map need new info ... + void map_rotate90( sint16 ); }; #endif diff --git a/gui/labellist_frame_t.h b/gui/labellist_frame_t.h index c056fedf3b6..768adec8a79 100644 --- a/gui/labellist_frame_t.h +++ b/gui/labellist_frame_t.h @@ -69,6 +69,9 @@ class labellist_frame_t : public gui_frame_t, private action_listener_t * V.Meyer */ bool action_triggered( gui_action_creator_t *komp, value_t extra); + + // rotated map need new info ... + void map_rotate90( sint16 ) { display_list(); } }; #endif diff --git a/gui/welt.cc b/gui/welt.cc index 1eff029ed7d..ffc9c1fd2dc 100644 --- a/gui/welt.cc +++ b/gui/welt.cc @@ -79,7 +79,6 @@ DBG_MESSAGE("","sizeof(stat)=%d, sizeof(tm)=%d",sizeof(struct stat),sizeof(struc inp_x_size.set_pos(koord(LEFT_ARROW,intTopOfButton) ); inp_x_size.set_groesse(koord(RIGHT_ARROW-LEFT_ARROW+10, 12)); inp_x_size.add_listener(this); - inp_x_size.set_limits(64,4096); inp_x_size.set_value( sets->get_groesse_x() ); inp_x_size.set_limits( 64, min(32766,4194304/sets->get_groesse_y()) ); inp_x_size.set_increment_mode( sets->get_groesse_x()>=512 ? 128 : 64 ); @@ -176,7 +175,8 @@ DBG_MESSAGE("","sizeof(stat)=%d, sizeof(tm)=%d",sizeof(struct stat),sizeof(struc // other settings intTopOfButton += 5; use_intro_dates.set_pos( koord(10,intTopOfButton) ); - use_intro_dates.set_typ( button_t::square ); + use_intro_dates.set_typ( button_t::square_state ); + use_intro_dates.pressed = sets->get_use_timeline()&1; use_intro_dates.add_listener( this ); add_komponente( &use_intro_dates ); @@ -191,15 +191,17 @@ DBG_MESSAGE("","sizeof(stat)=%d, sizeof(tm)=%d",sizeof(struct stat),sizeof(struc intTopOfButton += 5; allow_player_change.set_pos( koord(10,intTopOfButton) ); - allow_player_change.set_typ( button_t::square ); + allow_player_change.set_typ( button_t::square_state ); allow_player_change.add_listener( this ); + allow_player_change.pressed = sets->get_allow_player_change(); add_komponente( &allow_player_change ); intTopOfButton += 12; intTopOfButton += 5; use_beginner_mode.set_pos( koord(10,intTopOfButton) ); - use_beginner_mode.set_typ( button_t::square ); + use_beginner_mode.set_typ( button_t::square_state ); use_beginner_mode.add_listener( this ); + use_beginner_mode.pressed = sets->get_beginner_mode(); add_komponente( &use_beginner_mode ); intTopOfButton += 12; @@ -386,13 +388,16 @@ welt_gui_t::action_triggered( gui_action_creator_t *komp,value_t v) knr = sets->get_karte_nummer(); // otherwise using cancel would not show the normal generated map again } else if(komp==&use_intro_dates) { - sets->set_use_timeline( !(sets->get_use_timeline()&1) ); + sets->set_use_timeline( use_intro_dates.pressed^1 ); + use_intro_dates.pressed = sets->get_use_timeline(); } else if(komp==&allow_player_change) { - sets->set_allow_player_change( !sets->get_allow_player_change() ); + sets->set_allow_player_change( allow_player_change.pressed^1 ); + allow_player_change.pressed = sets->get_allow_player_change(); } else if(komp==&use_beginner_mode) { - sets->set_beginner_mode( !sets->get_beginner_mode() ); + sets->set_beginner_mode( use_beginner_mode.pressed^1 ); + use_intro_dates.pressed = sets->get_beginner_mode(); } else if(komp==&load_game) { load = true; @@ -445,9 +450,6 @@ void welt_gui_t::zeichnen(koord pos, koord gr) sets->heightfield = ""; } } - use_intro_dates.pressed = sets->get_use_timeline()&1; - allow_player_change.pressed = sets->get_allow_player_change(); - use_beginner_mode.pressed = sets->get_beginner_mode(); if(old_lang!=translator::get_language()) { // update button texts! diff --git a/makeobj/Makeobj.sln b/makeobj/Makeobj.sln index e3447a94956..cb23159d2c6 100644 --- a/makeobj/Makeobj.sln +++ b/makeobj/Makeobj.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Makeobj", "Makeobj.vcproj", "{24CE8A5F-8B92-40EE-9491-31E2DFF019F9}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Makeobj", "Makeobj-experimental.vcproj", "{24CE8A5F-8B92-40EE-9491-31E2DFF019F9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/simline.cc b/simline.cc index 2acd7fa3e40..1878a0a8d5f 100644 --- a/simline.cc +++ b/simline.cc @@ -26,6 +26,15 @@ simline_t::simline_t(karte_t* welt, spieler_t* sp) this->old_fpl = NULL; this->fpl = NULL; this->sp = sp; + state_color = COL_YELLOW; +} + + + +void simline_t::set_line_id(uint32 id) +{ + this->id = id; + sprintf( name, "(%i) %s", id, translator::translate("Line") ); } @@ -101,9 +110,7 @@ void simline_t::add_convoy(convoihandle_t cnv) // will not hurt ... financial_history[0][LINE_CONVOIS] = count_convoys(); - if(state_color==COL_BLACK && cnv->has_obsolete_vehicles()) { - state_color = COL_DARK_BLUE; - } + recalc_status(); // do we need to tell the world about our new schedule? if( update_schedules ) { diff --git a/simline.h b/simline.h index 4f7d0836fda..b0473d29f90 100644 --- a/simline.h +++ b/simline.h @@ -34,21 +34,67 @@ class karte_t; class simlinemgmt_t; class simline_t { + +public: + enum linetype { line = 0, truckline = 1, trainline = 2, shipline = 3, airline = 4, monorailline=5, tramline=6, maglevline=7, narrowgaugeline=8}; + static uint8 convoi_to_line_catgory[MAX_CONVOI_COST]; + protected: simline_t(karte_t* welt, spieler_t*sp); -public: + schedule_t * fpl, *old_fpl; + linetype type; + spieler_t *sp; + +private: + static karte_t * welt; + char name[128]; + /** * Handle for ourselves. Can be used like the 'this' pointer * @author Hj. Malthaner */ linehandle_t self; - enum linetype { line = 0, truckline = 1, trainline = 2, shipline = 3, airline = 4, monorailline=5, tramline=6, maglevline=7, narrowgaugeline=8}; - static uint8 convoi_to_line_catgory[MAX_CONVOI_COST]; + /* + * the line id + * @author hsiegeln + */ + uint16 id; + + /* + * the current state saved as color + * Meanings are BLACK (ok), WHITE (no convois), YELLOW (no vehicle moved), RED (last month income minus), BLUE (at least one convoi vehicle is obsolete) + */ + uint8 state_color; + + /* + * a list of all convoys assigned to this line + * @author hsiegeln + */ + vector_tpl<convoihandle_t> line_managed_convoys; + + /* + * a list of all convoys assigned to this line + * @author hsiegeln + */ + minivec_tpl<uint8> goods_catg_index; + + /* + * struct holds new financial history for line + * @author hsiegeln + */ + sint64 financial_history[MAX_MONTHS][MAX_LINE_COST]; + + void init_financial_history(); + void recalc_status(); + +public: ~simline_t(); + linehandle_t get_handle() const { return self; } + /* * add convoy to route * @author hsiegeln @@ -99,7 +145,7 @@ class simline_t { uint16 get_line_id() const {return id;} - void set_line_id(uint32 id) {this->id=id;} + void set_line_id(uint32 id); /* * load or save the line @@ -154,51 +200,9 @@ class simline_t { // recalculates the good transported by this line and (in case of changes) will start schedule recalculation void recalc_catg_index(); -protected: - schedule_t * fpl, *old_fpl; - linetype type; - spieler_t *sp; - public: spieler_t *get_besitzer() const {return sp;} -private: - static karte_t * welt; - char name[128]; - - /* - * the line id - * @author hsiegeln - */ - uint16 id; - - /* - * the current state saved as color - * Meanings are BLACK (ok), WHITE (no convois), YELLOW (no vehicle moved), RED (last month income minus), BLUE (at least one convoi vehicle is obsolete) - */ - uint8 state_color; - - /* - * a list of all convoys assigned to this line - * @author hsiegeln - */ - vector_tpl<convoihandle_t> line_managed_convoys; - - /* - * a list of all convoys assigned to this line - * @author hsiegeln - */ - minivec_tpl<uint8> goods_catg_index; - - /* - * struct holds new financial history for line - * @author hsiegeln - */ - sint64 financial_history[MAX_MONTHS][MAX_LINE_COST]; - - void init_financial_history(); - - void recalc_status(); }; diff --git a/simlinemgmt.cc b/simlinemgmt.cc index 8bdbe81308a..cffa88b72ac 100644 --- a/simlinemgmt.cc +++ b/simlinemgmt.cc @@ -162,7 +162,7 @@ DBG_MESSAGE("simlinemgmt_t::rdwr()","number of lines=%i",totalLines); dbg->fatal( "simlinemgmt_t::create_line()", "Cannot create default line!" ); } line->rdwr(file); - add_line(line->self); + add_line( line->get_handle() ); } } } @@ -282,8 +282,8 @@ simlinemgmt_t::create_line(int ltype, spieler_t * sp) dbg->fatal( "simlinemgmt_t::create_line()", "Cannot create default line!" ); break; } - add_line( line->self ); - return line->self; + add_line( line->get_handle() ); + return line->get_handle(); } From 06eae5f24bde8a512d48c8d6ab14ed26831b76d6 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 31 Jan 2009 18:51:22 +0000 Subject: [PATCH 04/61] Improved hill function: now, hills get increasingly hard to climb for up to 5 tiles. Also, cleaned the hill code and improved the fixed-sized ordered list template. --- Simutrans-Experimental.sln | 20 +++ tpl/fixed_list_tpl.h | 15 ++ tpl/ordered_vector_tpl.h | 324 +++++++++++++++++++++++++++++++++++++ vehicle/simvehikel.cc | 66 ++++---- 4 files changed, 397 insertions(+), 28 deletions(-) create mode 100644 Simutrans-Experimental.sln create mode 100644 tpl/ordered_vector_tpl.h diff --git a/Simutrans-Experimental.sln b/Simutrans-Experimental.sln new file mode 100644 index 00000000000..f521e11686b --- /dev/null +++ b/Simutrans-Experimental.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Simutrans-Experimental", "Simutrans-Experimental.vcproj", "{0621B295-BEB7-4767-82F1-F27995610323}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0621B295-BEB7-4767-82F1-F27995610323}.Debug|Win32.ActiveCfg = Debug|Win32 + {0621B295-BEB7-4767-82F1-F27995610323}.Debug|Win32.Build.0 = Debug|Win32 + {0621B295-BEB7-4767-82F1-F27995610323}.Release|Win32.ActiveCfg = Release|Win32 + {0621B295-BEB7-4767-82F1-F27995610323}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tpl/fixed_list_tpl.h b/tpl/fixed_list_tpl.h index fbe5b5be43e..7b9fae16190 100644 --- a/tpl/fixed_list_tpl.h +++ b/tpl/fixed_list_tpl.h @@ -24,6 +24,21 @@ template<class T, int N> class fixed_list_tpl fixed_list_tpl() : size(0), head(0), tail(0), placeholder(0), placeholder_set(false) { } T get_element(uint8 e) + { + //Depracated, retained for backwards compatibility. + //Use [] instead. + if(e > size) + { + return NULL; + } + else + { + uint8 i = add_index(head, e, N); + return data[i]; + } + } + + T operator[](uint8 e) { if(e > size) { diff --git a/tpl/ordered_vector_tpl.h b/tpl/ordered_vector_tpl.h new file mode 100644 index 00000000000..fab318b0ac5 --- /dev/null +++ b/tpl/ordered_vector_tpl.h @@ -0,0 +1,324 @@ +#ifndef TPL_ORDERED_VECTOR_TPL_H +#define TPL_ORDERED_VECTOR_TPL_H +#include "../simtypes.h" +#include "../simdebug.h" +#include "../convoihandle_t.h" +#include "../linehandle_t.h" +#include "../halthandle_t.h" + +template<class T, class inttype> class ordered_vector_tpl; + +//Doesn't work: :-( +//template<class T> typedef ordered_vector_tpl<T, uint32> ordered_vector; +//template<class T> typedef ordered_vector_tpl<T, uint8> ordered_minivec; + +typedef ordered_vector_tpl<uint8, uint8> catg_index_vec; +typedef ordered_vector_tpl<halthandle_t, uint16> halthandle_vec; +typedef ordered_vector_tpl<linehandle_t, uint16> linehandle_vec; +typedef ordered_vector_tpl<convoihandle_t, uint16> convoihandle_vec; + +/* + * Template class for a increasingly ordered vector with unique entries. + * It needs <= and == for the class T. + * Since we have also a template for the count and size-variables + * we are able to define short and long vectors with this class. + */ +template<class T, class inttype> class ordered_vector_tpl +{ + private: + T* data; + inttype size; ///< Capacity + inttype count; ///< Number of elements in vector + + public: + ordered_vector_tpl() : + data(NULL), + size(0), + count(0) {} + /** Construct a vector for new_size elements */ + explicit ordered_vector_tpl(inttype new_size) : + data(new_size > 0 ? new T[new_size] : NULL), + size(new_size), + count(0) {} + + ordered_vector_tpl(const ordered_vector_tpl<T,inttype> &vT) + { + count = size = 0; + data = NULL; + resize( vT.get_count() ); + count = vT.get_count(); + for( inttype i=0; i<count; i++ ) { + data[i] = vT.data[i]; + } + } + + ordered_vector_tpl& operator = (const ordered_vector_tpl<T, inttype> &vT) + { + if( this != &vT ) { // Otherwise we will lost all our data! + count = 0; // Clear our elements so resize will work properly. + resize( vT.get_count() ); + count = vT.get_count(); + for( inttype i=0; i<count; i++ ) { + data[i] = vT.data[i]; + } + } + return *this; + } + + ~ordered_vector_tpl() { + if( data ) { + delete [] data; + } + } + + /** sets the vector to empty */ + void clear() { count = 0; } + + // Check if elem is contained. + bool contains(T elem) const + { + inttype index = intern_search(elem); + if( index < count && data[index] == elem ) { + return true; + } + else { + return false; + } + } + + /* + * Insert only if elem isn't yet contained. + * Returns false if elem already contained. + */ + bool insert_unique(T elem, inttype i = 1) + { + if( count == size ) { + if( i == 0 ) { + resize( size == 0 ? 1 : 2*size ); + } + else { + resize( size + i ); + } + } + inttype index = intern_search(elem); + if( index < count && data[index] == elem ) { + return false; + } + move_data(index, count, +1); + data[index] = elem; + count++; + return true; + } + + // Removes elem. + bool remove(T elem) + { + inttype index = intern_search(elem); + if( index < count && data[index] == elem ) { + remove_at(index); + return true; + } + return false; + } + + //Removes the element at the given pos. + void remove_at(inttype pos) + { + move_data(pos+1, count, -1); + count--; + } + + /* + * Handle set operations. + * Assume that all values in this and vT are unique and + * in the right order! + */ + void set_union(const ordered_vector_tpl<T, inttype> vT) + { + T* old_data = data; + inttype old_count = count; + + data = new T[ count + vT.count ]; + count = 0; + + inttype i,j; + i = j = 0; + while( i < old_count && j < vT.count ) { + if( old_data[i] == vT.data[j] ) { + data[ count++ ] = old_data[i]; + i++; + j++; + } + else + if( old_data[i] <= vT.data[j] ) { + data[ count++ ] = old_data[i]; + i++; + } + else + { + data[ count++ ] = vT.data[j]; + j++; + } + } + while( i < old_count ) { + data[ count++ ] = old_data[i]; + i++; + } + while( j < vT.count ) { + data[ count++ ] = vT.data[j]; + j++; + } + }; + + void set_diff(const ordered_vector_tpl<T, inttype> vT) + { + inttype i,j; + i = j = 0; + while( i < count && j < vT.count ) { + if( data[i] == vT.data[j] ) { + i++; + j++; + } + else + if( data[i] <= vT.data[j] ) { + remove_at(i); + } + else + { + j++; + } + } + // Delete remaining elements: + count = i; + }; + + void set_minus(const ordered_vector_tpl<T, inttype> vT) + { + inttype i,j; + i = j = 0; + while( i < count && j < vT.count ) { + if( data[i] == vT.data[j] ) { + remove_at(i); + j++; + } + else + if( data[i] <= vT.data[j] ) { + i++; + } + else + { + j++; + } + } + }; + + /** + * Resizes the maximum data that can be hold by this vector. + * Existing entries are preserved, new_size must be big enough to hold them. + */ + void resize(inttype new_size) + { + if ( new_size < count || new_size == size ) { + return; + } + + T* new_data; + if( new_size > 0 ) { + new_data = new T[new_size]; + } + else { + new_data = NULL; + } + if(size>0) { + for (inttype i = 0; i < count; i++) { + new_data[i] = data[i]; + } + delete [] data; + } + size = new_size; + data = new_data; + } + + // Returns index of elem. + inttype index_of(T elem) const + { + inttype index = intern_search(elem); + if( index < count && data[index] == elem ){ + return index; + } + else + { + assert(false); + return 0-1; + } + } + + // Useful if accessing the vector by a pointer: + T& get_by_index (inttype i) { return data[i]; } + + const T& get_by_index (inttype i) const { return data[i]; } + + T& operator [] (inttype i) { return data[i]; } + + const T& operator [] (inttype i) const { return data[i]; } + + inttype get_count() const { return count; } + + inttype get_size() const { return size; } + + bool is_empty() const { return count==0; } + private: + /* + * Moves the elements data[start_index]..data[end_index-1] to + * data[start_index+offset]..data[end_index-1+offset] + */ + void move_data(inttype start_index, inttype end_index, sint8 offset) + { + inttype num = end_index - start_index; + if( offset < 0 ) { + for( inttype i=0; i<num ; i++ ){ + data[start_index+i+offset] = data[start_index+i]; + } + } + else if( offset > 0 ) { + for( inttype i=num ; i>0 ; i-- ){ + data[start_index+i+offset-1] = data[start_index+i-1]; + } + } + } + + /* + * Returns an index i with the following properties: + * 0<= i <= count + * data[i-1] < elem (if 0<= i-1 < count) + * data[i] >= elem (if 0<= i < count) + */ + inttype intern_search(T elem) const + { + // Test some special cases: + if( count == 0 || !(elem <= data[count-1]) ) { + return count; + } + if( elem <= data[0] ) { + return 0; + } + inttype index_bottom=0, index_top=count-1; + inttype index_mid; + while( index_top > index_bottom + 1 ){ + /* + * In this loop the following two statements hold + * data[index_bottom] < elem + * data[index_top] >= elem + */ + index_mid = (index_top + index_bottom) / 2; + if( elem <= data[index_mid] ){ + index_top = index_mid; + } + else { + index_bottom = index_mid; + } + } + return index_top; + } +}; +#endif \ No newline at end of file diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index c13da33618d..2a9d9005c8e 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -104,7 +104,7 @@ fixed_list_tpl<sint16, 16> pre_corner_direction; sint16 direction_steps = 4; -bool hill[2]; +fixed_list_tpl<bool, 5> hill; bool is_overweight = false; // set only once, before loading! @@ -1371,38 +1371,48 @@ vehikel_t::calc_akt_speed(const grund_t *gr) //,const int h_alt, const int h_neu // or a hill? // Cumulative drag for hills: @author: jamespetts const hang_t::typ hang = gr->get_weg_hang(); - hill[2] = hill[1]; - hill[1] = hill[0]; - if(hang!=hang_t::flach) { - hill[0] = (ribi_typ(hang)==fahrtrichtung); - if(hill[0]) + if(hang!=hang_t::flach) + { + hill.add_to_head(ribi_typ(hang)==fahrtrichtung); + uint8 hill_number; + for(hill_number = 0; hill_number < 5; hill_number ++) { - // hill up, since height offsets are negative: heavy deccelerate - - if(!hill[1]) - { - //No hill last tile, minimal friction increase. - current_friction += 18; - } - else if(hill[1] && !hill[2]) + if(!hill[hill_number]) { - //Hill last tile, but not the tile before. Moderate friction increase. - current_friction += 25; - } - else if(hill[1] && hill[2]) - { - //Hill last two tiles. Maximum friction increase. - current_friction += 32; + break; } } - else { - // hill down: accelrate + + switch(hill_number) + { + case 0: + //Must be downhill current_friction += -13; - } - } - else - { - hill[0] = false; + break; + + case 1: + current_friction += 18; + break; + + case 2: + current_friction += 25; + break; + + case 3: + current_friction += 32; + break; + + case 4: + current_friction += 38; + break; + + case 5: + current_friction += 45; + break; + + default: + break; + }; } if(ist_erstes) { //"Is the first" (Google) From 1b21f4ebfc26e89437fcb5592a12822c341751b1 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 1 Feb 2009 11:20:01 +0000 Subject: [PATCH 05/61] Improved steam engine physics. --- simconvoi.cc | 86 ++++++++++++++++++++++++++++++++++++++++++- simconvoi.h | 14 +++++++ vehicle/simvehikel.cc | 2 +- 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/simconvoi.cc b/simconvoi.cc index 1a5b7df596a..a1faf83bd79 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -110,7 +110,7 @@ void convoi_t::init(karte_t *wl, spieler_t *sp) besitzer_p = sp; is_electric = false; - sum_gesamtgewicht = sum_gewicht = sum_gear_und_leistung = sum_leistung = 0; + sum_gesamtgewicht = sum_gewicht = sum_gear_und_leistung = sum_leistung = power_from_steam = power_from_steam_with_gear = 0; previous_delta_v = 0; min_top_speed = 9999999; @@ -449,7 +449,9 @@ void convoi_t::calc_acceleration(long delta_t) // prissi: // integer sucks with planes => using floats ... - sint32 delta_v = (sint32)( ( (double)( (akt_speed>akt_speed_soll?0l:sum_gear_und_leistung) - deccel)*(double)delta_t)/(double)sum_gesamtgewicht); + //sint32 delta_v = (sint32)( ( (double)( (akt_speed>akt_speed_soll?0l:sum_gear_und_leistung) - deccel)*(double)delta_t)/(double)sum_gesamtgewicht); + sint32 delta_v = (sint32)( ( (double)( (akt_speed>akt_speed_soll?0l:calc_adjusted_power()) - deccel)*(double)delta_t)/(double)sum_gesamtgewicht); + //"leistung" = "performance" (Google) // we normalize delta_t to 1/64th and check for speed limit */ // sint32 delta_v = ( ( (akt_speed>akt_speed_soll?0l:sum_gear_und_leistung) - deccel) * delta_t)/sum_gesamtgewicht; @@ -480,6 +482,71 @@ void convoi_t::calc_acceleration(long delta_t) } } +sint32 convoi_t::calc_adjusted_power() +{ + if(power_from_steam < 1 && speed_to_kmh(akt_speed) < 50) + { + // Either no steam engines, or going fast + // enough that it makes no difference, + // so the simple formula prevails. + return sum_gear_und_leistung; + } + // There must be a steam engine here. + // So, reduce the power at lower speeds. + // Should be approx: 40% power at 15kph + // 70% power at 25kph; 85% power at 32kph + // and 100% power at >50kph. + // See here for details: http://www.railway-technical.com/st-vs-de.shtml + + //This is needed to add back at the end. + uint32 power_without_steam = sum_gear_und_leistung - power_from_steam_with_gear; + + float speed_factor = 1.0; + uint16 current_speed = speed_to_kmh(akt_speed); + + // Manually (with some manual interpretation) because formula not linear, + // and actual formula not known to me. + if(current_speed <= 10) + { + speed_factor = 0.3; + } + else if(current_speed <=15) + { + speed_factor = 0.4; + } + else if(current_speed <= 20) + { + speed_factor = 0.55; + } + else if(current_speed <= 25) + { + speed_factor = 0.7; + } + else if(current_speed <= 28) + { + speed_factor = 0.775; + } + else if(current_speed <= 32) + { + speed_factor = 0.85; + } + else if(current_speed <= 38) + { + speed_factor = 0.9; + } + else if(current_speed <= 43) + { + speed_factor = 0.92; + } + else + { + speed_factor = 0.96; + } + + uint32 modified_power_from_steam = power_from_steam_with_gear * speed_factor; + return modified_power_from_steam + power_without_steam; +} + int convoi_t::get_vehicle_at_length(uint16 length) @@ -1034,6 +1101,11 @@ DBG_MESSAGE("convoi_t::add_vehikel()","extend array_tpl to %i totals.",max_rail_ is_electric |= info->get_engine_type()==vehikel_besch_t::electric; } sum_leistung += info->get_leistung(); + if(info->get_engine_type() == vehikel_besch_t::steam) + { + power_from_steam += info->get_leistung(); + power_from_steam_with_gear += info->get_leistung()*info->get_gear(); + } sum_gear_und_leistung += info->get_leistung()*info->get_gear(); sum_gewicht += info->get_gewicht(); min_top_speed = min( min_top_speed, kmh_to_speed( v->get_besch()->get_geschw() ) ); @@ -1075,6 +1147,11 @@ convoi_t::remove_vehikel_bei(uint16 i) const vehikel_besch_t *info = v->get_besch(); sum_leistung -= info->get_leistung(); + if(info->get_engine_type() == vehikel_besch_t::steam) + { + power_from_steam -= info->get_leistung(); + power_from_steam_with_gear -= info->get_leistung()*info->get_gear(); + } sum_gear_und_leistung -= info->get_leistung()*info->get_gear(); sum_gewicht -= info->get_gewicht(); } @@ -1603,6 +1680,11 @@ convoi_t::rdwr(loadsave_t *file) // info if(info) { sum_leistung += info->get_leistung(); + if(info->get_engine_type() == vehikel_besch_t::steam) + { + power_from_steam += info->get_leistung(); + power_from_steam_with_gear += info->get_leistung()*info->get_gear(); + } sum_gear_und_leistung += info->get_leistung()*info->get_gear(); sum_gewicht += info->get_gewicht(); is_electric |= info->get_engine_type()==vehikel_besch_t::electric; diff --git a/simconvoi.h b/simconvoi.h index e9b4cdaf36a..e6f7614ab4e 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -196,6 +196,11 @@ class convoi_t : public sync_steppable, public overtaker_t */ uint32 sum_leistung; + // How much of the convoy's power comes from steam engines? + // Needed when applying realistic physics to steam engines. + // @author: jamespetts + uint32 power_from_steam; + /** * Gesamtleistung mit Gear. Wird nicht gespeichert, sondern aus den Einzelleistungen * errechnet. @@ -203,6 +208,9 @@ class convoi_t : public sync_steppable, public overtaker_t */ sint32 sum_gear_und_leistung; + // @author: jamespetts + sint32 power_from_steam_with_gear; + /* sum_gewicht: leergewichte aller vehicles * * sum_gesamtgewicht: gesamtgewichte aller vehicles * * Werden nicht gespeichert, sondern aus den Einzelgewichten @@ -318,6 +326,10 @@ class convoi_t : public sync_steppable, public overtaker_t */ void calc_acceleration(long delta_t); + // Calculate the total power as adjusted to take account of steam engine physics + //@author: jamespetts + sint32 calc_adjusted_power(); + /** * Convoi haelt an Haltestelle und setzt quote fuer Fracht * @author Hj. Malthaner @@ -502,6 +514,8 @@ class convoi_t : public sync_steppable, public overtaker_t * @author Hj. Malthaner */ const uint32 & get_sum_leistung() const {return sum_leistung;} + const uint32 & get_power_from_steam() const {return power_from_steam;} + const uint32 & get_power_from_steam_with_gear() const {return power_from_steam_with_gear;} const sint32 & get_min_top_speed() const {return min_top_speed;} const sint32 & get_sum_gewicht() const {return sum_gewicht;} const sint32 & get_sum_gesamtgewicht() const {return sum_gesamtgewicht;} diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 2a9d9005c8e..1f0055f0cfb 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -1387,7 +1387,7 @@ vehikel_t::calc_akt_speed(const grund_t *gr) //,const int h_alt, const int h_neu { case 0: //Must be downhill - current_friction += -13; + current_friction -= 13; break; case 1: From 817538ba84101cf78a532ec1d2af4e0d56c6844f Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 1 Feb 2009 14:28:08 +0000 Subject: [PATCH 06/61] Fixed some merge errors with the standard Simutrans trunk that stopped the code from compiling. --- dataobj/einstellungen.cc | 2 +- dataobj/einstellungen.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index b88019e1cd2..153f888aca0 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -195,7 +195,7 @@ einstellungen_t::einstellungen_t() : uint8 max_alternative_destinations = 3; // this will pay for distance to next change station - pay_for_total_distance = TO_PREVIOUS; + pay_for_total_distance = 0; } diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index 4998f3bc9f9..d5284a1a6f1 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -379,7 +379,7 @@ class einstellungen_t bool is_seperate_halt_capacities() const { return seperate_halt_capacities ; } void set_seperate_halt_capacities( bool b ) { seperate_halt_capacities = b; } - sint16 get_river_number() const { return river_number; } void set_river_number( sint16 n ) { river_number=n; } sint16 get_min_river_length() const { return min_river_length; } void set_min_river_length( sint16 n ) { min_river_length=n; } sint16 get_max_river_length() const { return max_river_length; } void set_max_river_length( sint16 n ) { max_river_length=n; } uint16 get_min_bonus_max_distance() const { return min_bonus_max_distance; } + uint16 get_min_bonus_max_distance() const { return min_bonus_max_distance; } uint16 get_max_bonus_min_distance() const { return max_bonus_min_distance; } uint16 get_local_bonus_multiplier() const { return local_bonus_multiplier; } From a637b17c72f9278ed2ee802f0162bf9a3027f712 Mon Sep 17 00:00:00 2001 From: Ansgar Burchardt <ansgar@2008.43-1.org> Date: Sun, 1 Feb 2009 19:07:40 +0100 Subject: [PATCH 07/61] Fix compiler errors and warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit boden/wege/weg.h:160: error: extra qualification ‘weg_t::’ on member ‘reset_way_constraints’ besch/vehikel_besch.h:236: error: storage class specifiers invalid in parameter declarations besch/vehikel_besch.h:236: error: storage class specified for parameter ‘welt’ simconvoi.h:518: warning: returning reference to temporary vehicle/simvehikel.h:249: error: extra qualification ‘vehikel_t::’ on member ‘check_way_constraints’ vehicle/simvehikel.h:304: error: storage class specifiers invalid in parameter declarations vehicle/simvehikel.h:304: error: storage class specified for parameter ‘welt’ vehicle/simvehikel.h:400: error: a storage class can only be specified for objects and functions vehicle/simvehikel.h:404: error: extra qualification ‘vehikel_t::’ on member ‘compare_directions’ simcity.h:88: error: extra qualification ‘stadt_t::’ on member ‘privatecar_init’ simcity.h:89: error: extra qualification ‘stadt_t::’ on member ‘get_private_car_ownership’ dataobj/einstellungen.cc:677: error: ‘waytype_t’ is not a class or namespace vehicle/simvehikel.cc: In member function ‘bool vehikel_t::check_way_constraints(const weg_t*) const’: vehicle/simvehikel.cc:1987: error: expected unqualified-id before ‘||’ token vehicle/simvehikel.cc:1988: error: expected primary-expression before ‘||’ token vehicle/simvehikel.cc:1988: error: expected primary-expression before ‘;’ token vehicle/simvehikel.cc:1992: error: expected primary-expression before ‘||’ token vehicle/simvehikel.cc:1992: error: expected primary-expression before ‘=’ token vehicle/simvehikel.cc:1993: error: expected primary-expression before ‘||’ token vehicle/simvehikel.cc:1993: error: expected primary-expression before ‘;’ token Signed-off-by: Ansgar Burchardt <ansgar@2008.43-1.org> --- besch/vehikel_besch.cc | 2 +- besch/vehikel_besch.h | 2 +- boden/wege/weg.h | 2 +- dataobj/einstellungen.cc | 110 +++++++++++++++++++-------------------- simcity.h | 4 +- simconvoi.h | 12 ++--- vehicle/simvehikel.cc | 8 +-- vehicle/simvehikel.h | 8 +-- 8 files changed, 74 insertions(+), 74 deletions(-) diff --git a/besch/vehikel_besch.cc b/besch/vehikel_besch.cc index 4485616bf5b..9486a8cdebe 100644 --- a/besch/vehikel_besch.cc +++ b/besch/vehikel_besch.cc @@ -3,7 +3,7 @@ // Get running costs. Running costs increased if the vehicle is obsolete. // @author: jamespetts uint16 -vehikel_besch_t::get_betriebskosten(static karte_t* welt) const +vehikel_besch_t::get_betriebskosten(karte_t* welt) const { uint16 month_now = welt->get_current_month(); int normal_running_costs = get_betriebskosten(); diff --git a/besch/vehikel_besch.h b/besch/vehikel_besch.h index 63f49f7508f..fcc29c5cc35 100644 --- a/besch/vehikel_besch.h +++ b/besch/vehikel_besch.h @@ -233,7 +233,7 @@ class vehikel_besch_t : public obj_besch_std_name_t { uint16 get_gewicht() const { return gewicht; } uint32 get_leistung() const { return leistung; } uint16 get_betriebskosten() const { return betriebskosten; } - uint16 get_betriebskosten(static karte_t *welt) const; //Overloaded method - includes increase for obsolescence. + uint16 get_betriebskosten(karte_t *welt) const; //Overloaded method - includes increase for obsolescence. sint8 get_sound() const { return sound; } diff --git a/boden/wege/weg.h b/boden/wege/weg.h index 465aab57c6b..c8210a40ffb 100644 --- a/boden/wege/weg.h +++ b/boden/wege/weg.h @@ -157,7 +157,7 @@ class weg_t : public ding_t void add_way_constraints(const uint8 permissive, const uint8 prohibitive); //Resets constraints to their base values. Used when removing way objects. - void weg_t::reset_way_constraints(); + void reset_way_constraints(); uint8 get_way_constraints_permissive() const { return way_constraints_permissive; } uint8 get_way_constraints_prohibitive() const { return way_constraints_prohibitive; } diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index 153f888aca0..68a2f5c3eb7 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -637,61 +637,61 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s congestion_density_factor = contents.get_int("congestion_density_factor", 12); //Cornering settings - max_corner_limit[waytype_t::road_wt] = contents.get_int("max_corner_limit_road", 200); - min_corner_limit[waytype_t::road_wt] = contents.get_int("min_corner_limit_road", 30); - max_corner_adjustment_factor[waytype_t::road_wt] = contents.get_int("max_corner_adjustment_factor_road", 75); - min_corner_adjustment_factor[waytype_t::road_wt] = contents.get_int("min_corner_adjustment_factor_road", 97); - min_direction_steps[waytype_t::road_wt] = contents.get_int("min_direction_steps_road", 3); - max_direction_steps[waytype_t::road_wt] = contents.get_int("max_direction_steps_road", 6); - curve_friction_factor[waytype_t::road_wt] = contents.get_int("curve_friction_factor_road", 0); - - max_corner_limit[waytype_t::track_wt] = contents.get_int("max_corner_limit_track", 425); - min_corner_limit[waytype_t::track_wt] = contents.get_int("min_corner_limit_track", 45); - max_corner_adjustment_factor[waytype_t::track_wt] = contents.get_int("max_corner_adjustment_factor_track", 50); - min_corner_adjustment_factor[waytype_t::track_wt] = contents.get_int("min_corner_adjustment_factor_track", 85); - min_direction_steps[waytype_t::track_wt] = contents.get_int("min_direction_steps_track", 4); - max_direction_steps[waytype_t::track_wt] = contents.get_int("max_direction_steps_track", 14); - curve_friction_factor[waytype_t::track_wt] = contents.get_int("curve_friction_factor_track", 0); - - max_corner_limit[waytype_t::tram_wt] = contents.get_int("max_corner_limit_tram", 425); - min_corner_limit[waytype_t::tram_wt] = contents.get_int("min_corner_limit_tram", 45); - max_corner_adjustment_factor[waytype_t::tram_wt] = contents.get_int("max_corner_adjustment_factor_tram", 50); - min_corner_adjustment_factor[waytype_t::tram_wt] = contents.get_int("min_corner_adjustment_factor_tram", 85); - min_direction_steps[waytype_t::tram_wt] = contents.get_int("min_direction_steps_tram", 4); - max_direction_steps[waytype_t::tram_wt] = contents.get_int("max_direction_steps_tram", 14); - curve_friction_factor[waytype_t::tram_wt] = contents.get_int("curve_friction_factor_tram", 0); - - max_corner_limit[waytype_t::tram_wt] = contents.get_int("max_corner_limit_tram", 250); - min_corner_limit[waytype_t::tram_wt] = contents.get_int("min_corner_limit_tram", 30); - max_corner_adjustment_factor[waytype_t::tram_wt] = contents.get_int("max_corner_adjustment_factor_tram", 60); - min_corner_adjustment_factor[waytype_t::tram_wt] = contents.get_int("min_corner_adjustment_factor_tram", 90); - min_direction_steps[waytype_t::tram_wt] = contents.get_int("min_direction_steps_tram", 3); - max_direction_steps[waytype_t::tram_wt] = contents.get_int("max_direction_steps_tram", 10); - curve_friction_factor[waytype_t::tram_wt] = contents.get_int("curve_friction_factor_tram", 0); - - max_corner_limit[waytype_t::monorail_wt] = contents.get_int("max_corner_limit_monorail", 425); - min_corner_limit[waytype_t::monorail_wt] = contents.get_int("min_corner_limit_monorail", 75); - max_corner_adjustment_factor[waytype_t::monorail_wt] = contents.get_int("max_corner_adjustment_factor_monorail", 50); - min_corner_adjustment_factor[waytype_t::monorail_wt] = contents.get_int("min_corner_adjustment_factor_monorail", 85); - min_direction_steps[waytype_t::monorail_wt] = contents.get_int("min_direction_steps_monorail", 5); - max_direction_steps[waytype_t::monorail_wt] = contents.get_int("max_direction_steps_monorail", 16); - curve_friction_factor[waytype_t::monorail_wt] = contents.get_int("curve_friction_factor_monorail", 0); - - max_corner_limit[waytype_t::maglev_wt] = contents.get_int("max_corner_limit_maglev", 500); - min_corner_limit[waytype_t::maglev_wt] = contents.get_int("min_corner_limit_maglev", 50); - max_corner_adjustment_factor[waytype_t::maglev_wt] = contents.get_int("max_corner_adjustment_factor_maglev", 40); - min_corner_adjustment_factor[waytype_t::maglev_wt] = contents.get_int("min_corner_adjustment_factor_maglev", 80); - min_direction_steps[waytype_t::maglev_wt] = contents.get_int("min_direction_steps_maglev", 4); - max_direction_steps[waytype_t::maglev_wt] = contents.get_int("max_direction_steps_maglev", 16); - curve_friction_factor[waytype_t::maglev_wt] = contents.get_int("curve_friction_factor_maglev", 0); - - max_corner_limit[waytype_t::narrowgauge_wt] = contents.get_int("max_corner_limit_narrowgauge", 250); - min_corner_limit[waytype_t::narrowgauge_wt] = contents.get_int("min_corner_limit_narrowgauge", 30); - max_corner_adjustment_factor[waytype_t::narrowgauge_wt] = contents.get_int("max_corner_adjustment_factor_narrowgauge", 66); - min_corner_adjustment_factor[waytype_t::narrowgauge_wt] = contents.get_int("min_corner_adjustment_factor_narrowgauge", 92); - min_direction_steps[waytype_t::narrowgauge_wt] = contents.get_int("min_direction_steps_narrowgauge", 3); - max_direction_steps[waytype_t::narrowgauge_wt] = contents.get_int("max_direction_steps_narrowgauge", 8); - curve_friction_factor[waytype_t::narrowgauge_wt] = contents.get_int("curve_friction_factor_narrowgauge", 0); + max_corner_limit[waytype_t(road_wt)] = contents.get_int("max_corner_limit_road", 200); + min_corner_limit[waytype_t(road_wt)] = contents.get_int("min_corner_limit_road", 30); + max_corner_adjustment_factor[waytype_t(road_wt)] = contents.get_int("max_corner_adjustment_factor_road", 75); + min_corner_adjustment_factor[waytype_t(road_wt)] = contents.get_int("min_corner_adjustment_factor_road", 97); + min_direction_steps[waytype_t(road_wt)] = contents.get_int("min_direction_steps_road", 3); + max_direction_steps[waytype_t(road_wt)] = contents.get_int("max_direction_steps_road", 6); + curve_friction_factor[waytype_t(road_wt)] = contents.get_int("curve_friction_factor_road", 0); + + max_corner_limit[waytype_t(track_wt)] = contents.get_int("max_corner_limit_track", 425); + min_corner_limit[waytype_t(track_wt)] = contents.get_int("min_corner_limit_track", 45); + max_corner_adjustment_factor[waytype_t(track_wt)] = contents.get_int("max_corner_adjustment_factor_track", 50); + min_corner_adjustment_factor[waytype_t(track_wt)] = contents.get_int("min_corner_adjustment_factor_track", 85); + min_direction_steps[waytype_t(track_wt)] = contents.get_int("min_direction_steps_track", 4); + max_direction_steps[waytype_t(track_wt)] = contents.get_int("max_direction_steps_track", 14); + curve_friction_factor[waytype_t(track_wt)] = contents.get_int("curve_friction_factor_track", 0); + + max_corner_limit[waytype_t(tram_wt)] = contents.get_int("max_corner_limit_tram", 425); + min_corner_limit[waytype_t(tram_wt)] = contents.get_int("min_corner_limit_tram", 45); + max_corner_adjustment_factor[waytype_t(tram_wt)] = contents.get_int("max_corner_adjustment_factor_tram", 50); + min_corner_adjustment_factor[waytype_t(tram_wt)] = contents.get_int("min_corner_adjustment_factor_tram", 85); + min_direction_steps[waytype_t(tram_wt)] = contents.get_int("min_direction_steps_tram", 4); + max_direction_steps[waytype_t(tram_wt)] = contents.get_int("max_direction_steps_tram", 14); + curve_friction_factor[waytype_t(tram_wt)] = contents.get_int("curve_friction_factor_tram", 0); + + max_corner_limit[waytype_t(tram_wt)] = contents.get_int("max_corner_limit_tram", 250); + min_corner_limit[waytype_t(tram_wt)] = contents.get_int("min_corner_limit_tram", 30); + max_corner_adjustment_factor[waytype_t(tram_wt)] = contents.get_int("max_corner_adjustment_factor_tram", 60); + min_corner_adjustment_factor[waytype_t(tram_wt)] = contents.get_int("min_corner_adjustment_factor_tram", 90); + min_direction_steps[waytype_t(tram_wt)] = contents.get_int("min_direction_steps_tram", 3); + max_direction_steps[waytype_t(tram_wt)] = contents.get_int("max_direction_steps_tram", 10); + curve_friction_factor[waytype_t(tram_wt)] = contents.get_int("curve_friction_factor_tram", 0); + + max_corner_limit[waytype_t(monorail_wt)] = contents.get_int("max_corner_limit_monorail", 425); + min_corner_limit[waytype_t(monorail_wt)] = contents.get_int("min_corner_limit_monorail", 75); + max_corner_adjustment_factor[waytype_t(monorail_wt)] = contents.get_int("max_corner_adjustment_factor_monorail", 50); + min_corner_adjustment_factor[waytype_t(monorail_wt)] = contents.get_int("min_corner_adjustment_factor_monorail", 85); + min_direction_steps[waytype_t(monorail_wt)] = contents.get_int("min_direction_steps_monorail", 5); + max_direction_steps[waytype_t(monorail_wt)] = contents.get_int("max_direction_steps_monorail", 16); + curve_friction_factor[waytype_t(monorail_wt)] = contents.get_int("curve_friction_factor_monorail", 0); + + max_corner_limit[waytype_t(maglev_wt)] = contents.get_int("max_corner_limit_maglev", 500); + min_corner_limit[waytype_t(maglev_wt)] = contents.get_int("min_corner_limit_maglev", 50); + max_corner_adjustment_factor[waytype_t(maglev_wt)] = contents.get_int("max_corner_adjustment_factor_maglev", 40); + min_corner_adjustment_factor[waytype_t(maglev_wt)] = contents.get_int("min_corner_adjustment_factor_maglev", 80); + min_direction_steps[waytype_t(maglev_wt)] = contents.get_int("min_direction_steps_maglev", 4); + max_direction_steps[waytype_t(maglev_wt)] = contents.get_int("max_direction_steps_maglev", 16); + curve_friction_factor[waytype_t(maglev_wt)] = contents.get_int("curve_friction_factor_maglev", 0); + + max_corner_limit[waytype_t(narrowgauge_wt)] = contents.get_int("max_corner_limit_narrowgauge", 250); + min_corner_limit[waytype_t(narrowgauge_wt)] = contents.get_int("min_corner_limit_narrowgauge", 30); + max_corner_adjustment_factor[waytype_t(narrowgauge_wt)] = contents.get_int("max_corner_adjustment_factor_narrowgauge", 66); + min_corner_adjustment_factor[waytype_t(narrowgauge_wt)] = contents.get_int("min_corner_adjustment_factor_narrowgauge", 92); + min_direction_steps[waytype_t(narrowgauge_wt)] = contents.get_int("min_direction_steps_narrowgauge", 3); + max_direction_steps[waytype_t(narrowgauge_wt)] = contents.get_int("max_direction_steps_narrowgauge", 8); + curve_friction_factor[waytype_t(narrowgauge_wt)] = contents.get_int("curve_friction_factor_narrowgauge", 0); /* * Selection of savegame format through inifile diff --git a/simcity.h b/simcity.h index b18713e25e4..f0b645beefb 100644 --- a/simcity.h +++ b/simcity.h @@ -85,8 +85,8 @@ class stadt_t * @author Hj. Malthaner */ static bool cityrules_init(cstring_t objpathname); - static void stadt_t::privatecar_init(cstring_t objfilename); - sint16 stadt_t::get_private_car_ownership(sint32 monthyear); + static void privatecar_init(cstring_t objfilename); + sint16 get_private_car_ownership(sint32 monthyear); private: static karte_t *welt; diff --git a/simconvoi.h b/simconvoi.h index e6f7614ab4e..d853b428f88 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -513,12 +513,12 @@ class convoi_t : public sync_steppable, public overtaker_t * @return total power of this convoi * @author Hj. Malthaner */ - const uint32 & get_sum_leistung() const {return sum_leistung;} - const uint32 & get_power_from_steam() const {return power_from_steam;} - const uint32 & get_power_from_steam_with_gear() const {return power_from_steam_with_gear;} - const sint32 & get_min_top_speed() const {return min_top_speed;} - const sint32 & get_sum_gewicht() const {return sum_gewicht;} - const sint32 & get_sum_gesamtgewicht() const {return sum_gesamtgewicht;} + uint32 get_sum_leistung() const {return sum_leistung;} + uint32 get_power_from_steam() const {return power_from_steam;} + uint32 get_power_from_steam_with_gear() const {return power_from_steam_with_gear;} + sint32 get_min_top_speed() const {return min_top_speed;} + sint32 get_sum_gewicht() const {return sum_gewicht;} + sint32 get_sum_gesamtgewicht() const {return sum_gesamtgewicht;} uint32 get_length() const; diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index b8b111d98cd..835ef248454 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -1984,13 +1984,13 @@ bool vehikel_t::check_way_constraints(const weg_t *way) const { // Permissive way constraints // If vehicle has it, way must have it. - uint8 or = besch->get_permissive_constraints() | way->get_way_constraints_permissive(); - bool permissive = way->get_way_constraints_permissive() ^ or; + uint8 my_or = besch->get_permissive_constraints() | way->get_way_constraints_permissive(); + bool permissive = way->get_way_constraints_permissive() ^ my_or; // Prohibitive way constraints // If way has it, vehicle must have it. - or = besch->get_prohibitive_constraints() | way->get_way_constraints_prohibitive(); - bool prohibitive = besch->get_prohibitive_constraints() ^ or; + my_or = besch->get_prohibitive_constraints() | way->get_way_constraints_prohibitive(); + bool prohibitive = besch->get_prohibitive_constraints() ^ my_or; return (!permissive) && (!prohibitive); } diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index 115f6e0010c..a7268182c1b 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -246,7 +246,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t virtual bool ist_befahrbar(const grund_t* ) const {return false;} - bool vehikel_t::check_way_constraints(const weg_t *way) const; + bool check_way_constraints(const weg_t *way) const; public: // the coordinates, where the vehicle was loaded the last time @@ -301,7 +301,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t * @author Hj. Malthaner */ int get_betriebskosten() const { return besch->get_betriebskosten(); } - int get_betriebskosten(static karte_t* welt) const { return besch->get_betriebskosten(welt); } + int get_betriebskosten(karte_t* welt) const { return besch->get_betriebskosten(welt); } /** * spielt den Sound, wenn das Vehikel sichtbar ist @@ -388,7 +388,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t // Check for straightness of way. //@author jamespetts - static enum direction_degrees { + enum direction_degrees { North = 360, Northeast = 45, East = 90, @@ -401,7 +401,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t direction_degrees get_direction_degrees(ribi_t::ribi); - sint16 vehikel_t::compare_directions(sint16 first_direction, sint16 second_direction); + sint16 compare_directions(sint16 first_direction, sint16 second_direction); /** * loescht alle fracht aus dem Fahrzeug From a968dd34efa6aa77f2b88c8bf8a1773d684dff77 Mon Sep 17 00:00:00 2001 From: Ansgar Burchardt <ansgar@2008.43-1.org> Date: Sun, 1 Feb 2009 19:08:05 +0100 Subject: [PATCH 08/61] Compile besch/vehikel_besch.cc Signed-off-by: Ansgar Burchardt <ansgar@2008.43-1.org> --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index a0c8019a4c4..245c1878a2c 100644 --- a/Makefile +++ b/Makefile @@ -143,6 +143,7 @@ SOURCES += besch/reader/way_reader.cc SOURCES += besch/reader/xref_reader.cc SOURCES += besch/sound_besch.cc SOURCES += besch/tunnel_besch.cc +SOURCES += besch/vehikel_besch.cc SOURCES += besch/ware_besch.cc SOURCES += boden/boden.cc SOURCES += boden/brueckenboden.cc From a7dbbeed8dadc72555032ddcff57311738d32a56 Mon Sep 17 00:00:00 2001 From: Ansgar Burchardt <ansgar@2008.43-1.org> Date: Sun, 1 Feb 2009 19:11:54 +0100 Subject: [PATCH 09/61] Avoid code duplication Signed-off-by: Ansgar Burchardt <ansgar@2008.43-1.org> --- tpl/fixed_list_tpl.h | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tpl/fixed_list_tpl.h b/tpl/fixed_list_tpl.h index 7b9fae16190..7b8dddfb2dd 100644 --- a/tpl/fixed_list_tpl.h +++ b/tpl/fixed_list_tpl.h @@ -27,15 +27,7 @@ template<class T, int N> class fixed_list_tpl { //Depracated, retained for backwards compatibility. //Use [] instead. - if(e > size) - { - return NULL; - } - else - { - uint8 i = add_index(head, e, N); - return data[i]; - } + return (*this)[e]; } T operator[](uint8 e) From 82c68e5654d380633a80a3a388069fb92dedf3c7 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 1 Feb 2009 23:27:18 +0000 Subject: [PATCH 10/61] Further improvements to the steam locomotive physics: differences between smaller and larger locomotives are now handled better. --- simconvoi.cc | 68 +++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/simconvoi.cc b/simconvoi.cc index a1faf83bd79..8d6b15a940b 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -484,7 +484,11 @@ void convoi_t::calc_acceleration(long delta_t) sint32 convoi_t::calc_adjusted_power() { - if(power_from_steam < 1 && speed_to_kmh(akt_speed) < 50) + uint16 max_speed = speed_to_kmh(fahr[0]->get_besch()->get_geschw()); + float highpoint_speed = (max_speed >= 30) ? max_speed - 30 : 30; + uint16 current_speed = speed_to_kmh(akt_speed); + + if(power_from_steam < 1 || speed_to_kmh(current_speed) > highpoint_speed) { // Either no steam engines, or going fast // enough that it makes no difference, @@ -493,54 +497,52 @@ sint32 convoi_t::calc_adjusted_power() } // There must be a steam engine here. // So, reduce the power at lower speeds. - // Should be approx: 40% power at 15kph - // 70% power at 25kph; 85% power at 32kph - // and 100% power at >50kph. + // Should be approx (for medium speed locomotive): + // 40% power at 15kph 70% power at 25kph; + // 85% power at 32kph; and 100% power at >50kph. // See here for details: http://www.railway-technical.com/st-vs-de.shtml //This is needed to add back at the end. uint32 power_without_steam = sum_gear_und_leistung - power_from_steam_with_gear; - float speed_factor = 1.0; - uint16 current_speed = speed_to_kmh(akt_speed); + float speed_factor; - // Manually (with some manual interpretation) because formula not linear, - // and actual formula not known to me. - if(current_speed <= 10) - { - speed_factor = 0.3; - } - else if(current_speed <=15) - { - speed_factor = 0.4; - } - else if(current_speed <= 20) - { - speed_factor = 0.55; - } - else if(current_speed <= 25) - { - speed_factor = 0.7; - } - else if(current_speed <= 28) + if(power_from_steam > 500) { - speed_factor = 0.775; + speed_factor = 1.0; } - else if(current_speed <= 32) + else { - speed_factor = 0.85; + float difference = 450 - (power_from_steam - 50); + float proportion = difference / 450.0; + float factor = 0.66 * proportion; + speed_factor = 1 + factor; } - else if(current_speed <= 38) + + + //These values are needed to apply different power reduction factors + //depending on the maximum speed. + + float lowpoint_speed = highpoint_speed * 0.3; + float midpoint_speed = lowpoint_speed * 2; + + if(current_speed <= lowpoint_speed) { - speed_factor = 0.9; + speed_factor *= 0.4; } - else if(current_speed <= 43) + else if(current_speed <= midpoint_speed) { - speed_factor = 0.92; + float speed_differential_actual = (float)current_speed - (float)lowpoint_speed; + float speed_differential_maximum = (float)midpoint_speed - (float)lowpoint_speed; + float factor_modification = speed_differential_actual / speed_differential_maximum; + speed_factor *= ((factor_modification * 0.4) + 0.4); } else { - speed_factor = 0.96; + float speed_differential_actual = (float)current_speed - (float)midpoint_speed; + float speed_differential_maximum = (float)highpoint_speed - (float)lowpoint_speed; + float factor_modification = speed_differential_actual / speed_differential_maximum; + speed_factor *= ((factor_modification * 0.15) + 0.8); } uint32 modified_power_from_steam = power_from_steam_with_gear * speed_factor; From c7f2153cf15abd1601efcd143c0352648e34610d Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Thu, 5 Feb 2009 21:35:30 +0000 Subject: [PATCH 11/61] Industries de-link themselves from the chain and display a message when they close down. Also, merged changes in the trunk up to 4th of February 2009. --- besch/fabrik_besch.h | 14 +++++++------- besch/reader/factory_reader.cc | 16 ++++++++-------- gui/map_frame.h | 1 + simfab.cc | 22 ++++++++++++++++++++++ simfab.h | 6 +++--- simworld.h | 2 +- 6 files changed, 42 insertions(+), 19 deletions(-) diff --git a/besch/fabrik_besch.h b/besch/fabrik_besch.h index 168d273b022..67d1a9b4fed 100644 --- a/besch/fabrik_besch.h +++ b/besch/fabrik_besch.h @@ -156,13 +156,13 @@ class fabrik_besch_t : public obj_besch_t { enum platzierung {Land, Wasser, Stadt}; private: - enum platzierung platzierung; - uint16 produktivitaet; - uint16 bereich; - uint16 gewichtung; // Wie wahrscheinlich soll der Bau sein? - uint8 kennfarbe; - uint16 lieferanten; - uint16 produkte; + enum platzierung platzierung; //"placement" (Babelfish) + uint16 produktivitaet; //"productivity" (Babelfish) + uint16 bereich; //"range" (Babelfish) + uint16 gewichtung; // Wie wahrscheinlich soll der Bau sein? ("How likely will the building be?" (Google)). + uint8 kennfarbe; //"identification colour code" (Babelfish) + uint16 lieferanten; //"supplier" (Babelfish) + uint16 produkte; //"products" (Babelfish) uint8 fields; // only if there are any ... uint16 pax_level; bool electricity_producer; diff --git a/besch/reader/factory_reader.cc b/besch/reader/factory_reader.cc index 4064fe3ff62..c048177b21b 100644 --- a/besch/reader/factory_reader.cc +++ b/besch/reader/factory_reader.cc @@ -176,14 +176,14 @@ factory_reader_t::read_node(FILE *fp, obj_node_info_t &node) if(version == 2) { // Versioned node, version 2 - besch->platzierung = (enum fabrik_besch_t::platzierung)decode_uint16(p); - besch->produktivitaet = decode_uint16(p); - besch->bereich = decode_uint16(p); - besch->gewichtung = decode_uint16(p); - besch->kennfarbe = decode_uint8(p); - besch->fields = decode_uint8(p); - besch->lieferanten = decode_uint16(p); - besch->produkte = decode_uint16(p); + besch->platzierung = (enum fabrik_besch_t::platzierung)decode_uint16(p); //"placement" (Babelfish) + besch->produktivitaet = decode_uint16(p); //"productivity" (Babelfish) + besch->bereich = decode_uint16(p); //"range" (Babelfish) + besch->gewichtung = decode_uint16(p); //"weighting" (Babelfish) + besch->kennfarbe = decode_uint8(p); //"identification colour code" (Babelfish) + besch->fields = decode_uint8(p); //"fields" (Babelfish) + besch->lieferanten = decode_uint16(p); //"supplier" (Babelfish) + besch->produkte = decode_uint16(p); //"products" (Babelfish) besch->pax_level = decode_uint16(p); DBG_DEBUG("factory_reader_t::read_node()","version=2, platz=%i, lieferanten=%i, pax=%i", besch->platzierung, besch->lieferanten, besch->pax_level ); } else if(version == 1) { diff --git a/gui/map_frame.h b/gui/map_frame.h index 87cfc6f6b1c..2740c36878e 100644 --- a/gui/map_frame.h +++ b/gui/map_frame.h @@ -25,6 +25,7 @@ class karte_t; /** * Reliefkartenfenster für Simutrans. + * Relief map window for Simutrans. (Babelfish) * * @author Hj. Malthaner * @date 03-Mar-01 diff --git a/simfab.cc b/simfab.cc index 5b23b006b51..dc89ba2c49d 100644 --- a/simfab.cc +++ b/simfab.cc @@ -189,6 +189,28 @@ fabrik_t::~fabrik_t() plan->boden_ersetzen( gr, new boden_t( welt, gr->get_pos(), hang_t::flach ) ); plan->get_kartenboden()->calc_bild(); } + + //Disconnect this factory from all chains. + //@author: jamespetts + uint32 number_of_customers = lieferziele.get_count(); + uint32 number_of_suppliers = suppliers.get_count(); + + if (!welt->get_is_shutting_down()) + { + char buf[192]; + uint16 jobs = besch->get_pax_level(); + sprintf(buf, translator::translate("Industry: %s has closed down, with the loss of %d jobs. %d upstream suppliers and %d downstream customers are affected."), translator::translate(get_name()), jobs, number_of_suppliers, number_of_customers); + welt->get_message()->add_message(buf, pos.get_2d(),message_t::general,COL_RED,skinverwaltung_t::neujahrsymbol->get_bild_nr(0)); + for(sint32 i = number_of_customers - 1; i >= 0; i --) + { + get_fab(welt, lieferziele[i])->rem_lieferziel(pos.get_2d()); + } + + for(sint32 i = number_of_suppliers - 1; i >= 0; i --) + { + get_fab(welt, suppliers[i])->rem_supplier(pos.get_2d()); + } + } } diff --git a/simfab.h b/simfab.h index df45b22359e..7d7c3f39808 100644 --- a/simfab.h +++ b/simfab.h @@ -107,7 +107,7 @@ class fabrik_t */ slist_tpl<stadt_t *> arbeiterziele; - spieler_t *besitzer_p; + spieler_t *besitzer_p; //"possessive" (Google) karte_t *welt; const fabrik_besch_t *besch; @@ -133,8 +133,8 @@ class fabrik_t */ sint32 prodfaktor; - vector_tpl<ware_production_t> eingang; //< das einganslagerfeld - vector_tpl<ware_production_t> ausgang; //< das ausgangslagerfeld + vector_tpl<ware_production_t> eingang; //< das einganslagerfeld ("in goose camp field" (!!) (Babelfish) + vector_tpl<ware_production_t> ausgang; //< das ausgangslagerfeld ("the output camp field") (Babelfish) /** * Zeitakkumulator für Produktion diff --git a/simworld.h b/simworld.h index 82a98175606..16fab7aef92 100644 --- a/simworld.h +++ b/simworld.h @@ -88,7 +88,7 @@ class karte_t #define MAX_WORLD_HISTORY_YEARS (12) // number of years to keep history #define MAX_WORLD_HISTORY_MONTHS (12) // number of months to keep history - bool get_is_shutting_down() { return is_shutting_down; } + bool get_is_shutting_down() const { return is_shutting_down; } // City cars that are not assigned to a particular city are stored in this list. // @author:jamespetts From 9d173a38e922d09d1d830d5704b6e338e814082a Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Fri, 6 Feb 2009 23:10:14 +0000 Subject: [PATCH 12/61] Added a small comment. --- vehicle/simvehikel.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 835ef248454..d7ebe657490 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -734,7 +734,8 @@ vehikel_t::unload_freight(halthandle_t halt) // halt->get_name()); // hier sollte nur ordentliche ware verabeitet werden - int menge = halt->liefere_an(tmp); + // "here only tidy commodity should be processed" (Babelfish) + int menge = halt->liefere_an(tmp); //"supply" (Babelfish) sum_menge += menge; // book delivered goods to destination From 41a2cf7e434dc3f293b18a447df5d966464e4f9d Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 7 Feb 2009 00:25:55 +0000 Subject: [PATCH 13/61] Add MSVC++ file for Makeobj-Experimental --- makeobj/Makeobj-experimental.vcproj | 506 ++++++++++++++++++++++++++++ 1 file changed, 506 insertions(+) create mode 100644 makeobj/Makeobj-experimental.vcproj diff --git a/makeobj/Makeobj-experimental.vcproj b/makeobj/Makeobj-experimental.vcproj new file mode 100644 index 00000000000..2b6ebd7d9b6 --- /dev/null +++ b/makeobj/Makeobj-experimental.vcproj @@ -0,0 +1,506 @@ +<?xml version="1.0" encoding="windows-1250"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="Makeobj" + ProjectGUID="{24CE8A5F-8B92-40EE-9491-31E2DFF019F9}" + RootNamespace="Makeobj" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="..\..\simutrans-experimental-binaries\debug" + IntermediateDirectory="..\..\simutrans-experimental-binaries\debug\intermediates" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;MAKEOBJ" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libpng.lib zlibstat.lib" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="..\..\simutrans-experimental-binaries\release" + IntermediateDirectory="..\..\simutrans-experimental-binaries\release\intermediates" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="3" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath="..\besch\writer\bridge_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\building_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\citycar_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\crossing_writer.cc" + > + </File> + <File + RelativePath="..\utils\cstring_t.cc" + > + </File> + <File + RelativePath="..\tpl\debug_helper.cc" + > + </File> + <File + RelativePath="..\utils\dr_rdpng.c" + > + </File> + <File + RelativePath="..\besch\writer\factory_writer.cc" + > + </File> + <File + RelativePath="..\dataobj\freelist.cc" + > + </File> + <File + RelativePath="..\besch\writer\get_climate.cc" + > + </File> + <File + RelativePath="..\besch\writer\get_waytype.cc" + > + </File> + <File + RelativePath="..\besch\writer\good_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\ground_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\groundobj_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\image_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\imagelist2d_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\imagelist_writer.cc" + > + </File> + <File + RelativePath="..\utils\log.cc" + > + </File> + <File + RelativePath="..\makeobj\makeobj.cc" + > + </File> + <File + RelativePath="..\besch\writer\obj_node.cc" + > + </File> + <File + RelativePath="..\besch\writer\obj_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\pedestrian_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\roadsign_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\root_writer.cc" + > + </File> + <File + RelativePath="..\utils\searchfolder.cc" + > + </File> + <File + RelativePath="..\besch\writer\sim_writer.cc" + > + </File> + <File + RelativePath="..\simdebug.cc" + > + </File> + <File + RelativePath="..\simmem.cc" + > + </File> + <File + RelativePath="..\utils\simstring.cc" + > + </File> + <File + RelativePath="..\simtools.cc" + > + </File> + <File + RelativePath="..\besch\writer\skin_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\sound_writer.cc" + > + </File> + <File + RelativePath="..\dataobj\tabfile.cc" + > + </File> + <File + RelativePath="..\besch\writer\text_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\tree_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\tunnel_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\vehicle_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\way_obj_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\way_writer.cc" + > + </File> + <File + RelativePath="..\besch\writer\xref_writer.cc" + > + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath="..\besch\writer\bridge_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\building_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\citycar_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\crossing_writer.h" + > + </File> + <File + RelativePath="..\utils\cstring_t.h" + > + </File> + <File + RelativePath="..\tpl\debug_helper.h" + > + </File> + <File + RelativePath="..\utils\dr_rdpng.h" + > + </File> + <File + RelativePath="..\besch\writer\factory_writer.h" + > + </File> + <File + RelativePath="..\dataobj\freelist.h" + > + </File> + <File + RelativePath="..\besch\writer\get_climate.h" + > + </File> + <File + RelativePath="..\besch\writer\get_waytype.h" + > + </File> + <File + RelativePath="..\besch\writer\good_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\ground_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\groundobj_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\image_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\imagelist2d_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\imagelist_writer.h" + > + </File> + <File + RelativePath="..\utils\log.h" + > + </File> + <File + RelativePath="..\besch\writer\obj_node.h" + > + </File> + <File + RelativePath="..\besch\writer\obj_pak_exception.h" + > + </File> + <File + RelativePath="..\besch\writer\obj_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\pedestrian_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\roadsign_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\root_writer.h" + > + </File> + <File + RelativePath="..\utils\searchfolder.h" + > + </File> + <File + RelativePath="..\simdebug.h" + > + </File> + <File + RelativePath="..\simmem.h" + > + </File> + <File + RelativePath="..\utils\simstring.h" + > + </File> + <File + RelativePath="..\simtools.h" + > + </File> + <File + RelativePath="..\besch\writer\skin_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\sound_writer.h" + > + </File> + <File + RelativePath="..\dataobj\tabfile.h" + > + </File> + <File + RelativePath="..\besch\writer\text_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\tree_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\tunnel_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\vehicle_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\way_obj_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\way_writer.h" + > + </File> + <File + RelativePath="..\besch\writer\xref_writer.h" + > + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> From c0f207d3075a3f22a7410cead1774277cfbd9f21 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 8 Feb 2009 00:28:59 +0000 Subject: [PATCH 14/61] Industries now close down between 0 and 30 years (random) of becoming obsolete, and all orphaned industries in the chain are also closed down. To do: automatically re-connect orphaned industries to any other suitable industries on the map. --- bauer/fabrikbauer.cc | 49 ++++++++---- bauer/hausbauer.cc | 2 +- besch/fabrik_besch.h | 14 ++-- dataobj/einstellungen.cc | 3 + dataobj/einstellungen.h | 6 ++ gui/factorylist_stats_t.cc | 11 ++- gui/karte.cc | 12 ++- player/ai_goods.cc | 11 ++- simcity.cc | 12 ++- simfab.cc | 159 ++++++++++++++++++++++++++++++++++--- simfab.h | 3 + simwerkz.cc | 36 ++++++--- simworld.cc | 150 +++++++++++++++++++++------------- simworld.h | 10 ++- 14 files changed, 358 insertions(+), 120 deletions(-) diff --git a/bauer/fabrikbauer.cc b/bauer/fabrikbauer.cc index 7fc29bb2c14..c69c3cbe857 100644 --- a/bauer/fabrikbauer.cc +++ b/bauer/fabrikbauer.cc @@ -66,9 +66,13 @@ void init_fab_map( karte_t *welt ) for( int i=0; i<fab_map_w*welt->get_groesse_y(); i++ ) { fab_map[i] = 0; } - slist_iterator_tpl <fabrik_t *> iter(welt->get_fab_list()); - while(iter.next()) { - add_factory_to_fab_map( welt, iter.get_current() ); + //slist_iterator_tpl <fabrik_t *> iter(welt->get_fab_list()); + //vector_tpl<fabrik_t*> factories = welt->get_fab_list(); + for(sint16 i = welt->get_fab_list().get_count() - 1; i >= 0; i --) + { + //while(iter.next()) { + //add_factory_to_fab_map( welt, iter.get_current() ); + add_factory_to_fab_map( welt, welt->get_fab_list()[i] ); } } @@ -612,18 +616,22 @@ int fabrikbauer_t::baue_link_hierarchie(const fabrik_t* our_fab, const fabrik_be DBG_MESSAGE("fabrikbauer_t::baue_hierarchie","lieferanten %i, lcount %i (need %i of %s)",info->get_lieferanten(),lcount,verbrauch,ware->get_name()); // Hajo: search if there already is one or two (crossconnect everything if possible) - const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); - slist_iterator_tpl <fabrik_t *> iter (list); + //const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); + const vector_tpl<fabrik_t *> & list = welt->get_fab_list(); + //slist_iterator_tpl <fabrik_t *> iter (list); bool found = false; - while( iter.next() && + //while( iter.next() && + for(sint16 i = list.get_count() - 1; (i >= 0) && ( (lcount==0 && verbrauch>0) || (lcount>=lfound+1) ); i --) + { // try to find matching factories for this consumption - ( (lcount==0 && verbrauch>0) || + //( (lcount==0 && verbrauch>0) || // but don't find more than two times number of factories requested - (lcount>=lfound+1) ) - ) - { - fabrik_t * fab = iter.get_current(); + //(lcount>=lfound+1) ) + //) + //{ + //fabrik_t * fab = iter.get_current(); + fabrik_t * fab = list[i]; // connect to an existing one, if this is an producer if(fab->vorrat_an(ware) > -1) { @@ -815,9 +823,12 @@ int fabrikbauer_t::increase_industry_density( karte_t *welt, bool tell_me ) // find last consumer if(!welt->get_fab_list().empty()) { - slist_iterator_tpl<fabrik_t*> iter (welt->get_fab_list()); - while(iter.next()) { - fabrik_t *fab = iter.get_current(); + //slist_iterator_tpl<fabrik_t*> iter (welt->get_fab_list()); + //while(iter.next()) { + for(sint16 i = welt->get_fab_list().get_count() - 1; i >= 0; i --) + { + //fabrik_t *fab = iter.get_current(); + fabrik_t *fab = welt->get_fab_list()[i]; if(fab->get_besch()->get_produkte()==0) { last_built_consumer = fab; break; @@ -876,9 +887,13 @@ int fabrikbauer_t::increase_industry_density( karte_t *welt, bool tell_me ) uint32 total_produktivity = 1; uint32 electric_productivity = 0; - slist_iterator_tpl<fabrik_t*> iter (welt->get_fab_list()); - while(iter.next()) { - fabrik_t * fab = iter.get_current(); + //slist_iterator_tpl<fabrik_t*> iter (welt->get_fab_list()); + //vector_tpl<fabrik_t*> factories = welt->get_fab_list(); + //while(iter.next()) { + for(sint16 i = welt->get_fab_list().get_count() - 1; i >= 0; i --) + { + //fabrik_t * fab = iter.get_current(); + fabrik_t * fab = welt->get_fab_list()[i]; if(fab->get_besch()->is_electricity_producer()) { electric_productivity += fab->get_base_production(); } diff --git a/bauer/hausbauer.cc b/bauer/hausbauer.cc index 9449f161da4..df8ffa58267 100644 --- a/bauer/hausbauer.cc +++ b/bauer/hausbauer.cc @@ -225,7 +225,7 @@ void hausbauer_t::neue_karte() -void hausbauer_t::remove( karte_t *welt, spieler_t *sp, gebaeude_t *gb ) +void hausbauer_t::remove( karte_t *welt, spieler_t *sp, gebaeude_t *gb ) //gebaeude = "building" (Babelfish) { const haus_tile_besch_t *tile = gb->get_tile(); const haus_besch_t *hb = tile->get_besch(); diff --git a/besch/fabrik_besch.h b/besch/fabrik_besch.h index 67d1a9b4fed..655bdf8ce12 100644 --- a/besch/fabrik_besch.h +++ b/besch/fabrik_besch.h @@ -93,9 +93,9 @@ class fabrik_lieferant_besch_t : public obj_besch_t { public: const ware_besch_t *get_ware() const { return static_cast<const ware_besch_t *>(get_child(0)); } - int get_kapazitaet() const { return kapazitaet; } - int get_anzahl() const { return anzahl; } - int get_verbrauch() const { return verbrauch; } + int get_kapazitaet() const { return kapazitaet; } //"capacity" (Babelfish) + int get_anzahl() const { return anzahl; } //"number" (Babelfish) + int get_verbrauch() const { return verbrauch; } //"consumption" (Babelfish) }; @@ -177,7 +177,7 @@ class fabrik_besch_t : public obj_besch_t { const rauch_besch_t *get_rauch() const { return static_cast<const rauch_besch_t *>(get_child(1)); } // we must take care, for the case of no producer/consumer - const fabrik_lieferant_besch_t *get_lieferant(int i) const + const fabrik_lieferant_besch_t *get_lieferant(int i) const //"supplier" (Babelfish) { return (i >= 0 && i < lieferanten) ? static_cast<const fabrik_lieferant_besch_t *>(get_child(2 + i)) : NULL; } @@ -190,18 +190,18 @@ class fabrik_besch_t : public obj_besch_t { return static_cast<const field_besch_t *>(get_child(2 + lieferanten + produkte)); } - int get_lieferanten() const { return lieferanten; } + int get_lieferanten() const { return lieferanten; } //"supplier" (Babelfish) uint get_produkte() const { return produkte; } /* where to built */ enum platzierung get_platzierung() const { return platzierung; } int get_gewichtung() const { return gewichtung; } - uint8 get_kennfarbe() const { return kennfarbe; } + uint8 get_kennfarbe() const { return kennfarbe; } //"identification colour code" (Babelfish) void set_produktivitaet(int p) { produktivitaet=p; } int get_produktivitaet() const { return produktivitaet; } - int get_bereich() const { return bereich; } + int get_bereich() const { return bereich; } //"range" (Babelfish) /* level for post and passenger generation */ int get_pax_level() const { return pax_level; } diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index a538873876c..b9e12f3ae11 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -697,6 +697,9 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s max_direction_steps[waytype_t(narrowgauge_wt)] = contents.get_int("max_direction_steps_narrowgauge", 8); curve_friction_factor[waytype_t(narrowgauge_wt)] = contents.get_int("curve_friction_factor_narrowgauge", 0); + //Factory settings + factory_max_years_obsolete = contents.get_int("max_years_obsolete", 30); + /* * Selection of savegame format through inifile */ diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index 966b372504e..50e251660d7 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -237,6 +237,10 @@ class einstellungen_t uint8 passenger_routing_local_chance; uint8 passenger_routing_midrange_chance; + //@author: jamespetts + // Factory retirement settings + uint16 factory_max_years_obsolete; + // true if active bool automaten[MAX_PLAYER_COUNT]; // 0 = emtpy, otherwise some vaule from simplay @@ -416,6 +420,8 @@ class einstellungen_t bool is_pay_for_total_distance() const { return pay_for_total_distance ; } void set_pay_for_total_distance( bool b ) { pay_for_total_distance = b; } + uint16 get_factory_max_years_obsolete() const { return factory_max_years_obsolete; } + sint16 get_river_number() const { return river_number; } void set_river_number( sint16 n ) { river_number=n; } sint16 get_min_river_length() const { return min_river_length; } diff --git a/gui/factorylist_stats_t.cc b/gui/factorylist_stats_t.cc index 6f8e8acb332..cbc279d1625 100644 --- a/gui/factorylist_stats_t.cc +++ b/gui/factorylist_stats_t.cc @@ -210,10 +210,13 @@ class compare_factories void factorylist_stats_t::sort(factorylist::sort_mode_t sortby, bool sortreverse) { fab_list.clear(); - fab_list.resize(welt->get_fab_list().count()); - for (slist_iterator_tpl<fabrik_t*> i(welt->get_fab_list()); i.next();) { - fab_list.push_back(i.get_current()); + fab_list.resize(welt->get_fab_list().get_count()); + //for (slist_iterator_tpl<fabrik_t*> i(welt->get_fab_list()); i.next();) { + for(sint16 i = welt->get_fab_list().get_count() - 1; i >= 0; i --) + { + //fab_list.push_back(i.get_current()); + fab_list.push_back(welt->get_fab_list()[i]); } std::sort(fab_list.begin(), fab_list.end(), compare_factories(sortby, sortreverse)); - set_groesse(koord(210, welt->get_fab_list().count()*(LINESPACE+1)-10)); + set_groesse(koord(210, welt->get_fab_list().get_count()*(LINESPACE+1)-10)); } diff --git a/gui/karte.cc b/gui/karte.cc index d82d3c2e787..bd8185e8681 100644 --- a/gui/karte.cc +++ b/gui/karte.cc @@ -591,11 +591,15 @@ reliefkarte_t::calc_map() // since we do iterate the factory info list, this must be done here if(mode==MAP_FACTORIES) { - slist_iterator_tpl <fabrik_t *> iter (welt->get_fab_list()); - while(iter.next()) { - koord pos = iter.get_current()->get_pos().get_2d(); + //slist_iterator_tpl <fabrik_t *> iter (welt->get_fab_list()); + //vector_tpl <fabrik_t*> factories = welt->get_fab_list(); + for(sint16 i = welt->get_fab_list().get_count() - 1; i >= 0; i --) + { + //while(iter.next()) { + //koord pos = iter.get_current()->get_pos().get_2d(); + koord pos = welt->get_fab_list()[i]->get_pos().get_2d(); set_relief_farbe_area( pos, 9, COL_BLACK ); - set_relief_farbe_area( pos, 7, iter.get_current()->get_kennfarbe() ); + set_relief_farbe_area( pos, 7, welt->get_fab_list()[i]->get_kennfarbe() ); } return; } diff --git a/player/ai_goods.cc b/player/ai_goods.cc index eece7eee8e3..7a5f6f065b2 100755 --- a/player/ai_goods.cc +++ b/player/ai_goods.cc @@ -657,9 +657,14 @@ void ai_goods_t::step() if(root==NULL) { // find a tree root to complete weighted_vector_tpl<fabrik_t *> start_fabs(20); - slist_iterator_tpl<fabrik_t *> fabiter( welt->get_fab_list() ); - while(fabiter.next()) { - fabrik_t *fab = fabiter.get_current(); + //slist_iterator_tpl<fabrik_t *> fabiter( welt->get_fab_list() ); + //while(fabiter.next()) { + //vector_tpl<fabrik_t*> factories = welt->get_fab_list(); + sint16 number_of_factories = welt->get_fab_list().get_count(); + for(sint16 i = number_of_factories - 1; i >= 0; i --) + { + fabrik_t *fab = welt->get_fab_list()[i]; + //fabrik_t *fab = fabiter.get_current(); // consumer and not completely overcrowded if(fab->get_besch()->get_produkte()==0 && fab->get_status()!=fabrik_t::bad) { int missing = get_factory_tree_missing_count( fab ); diff --git a/simcity.cc b/simcity.cc index dfafde3e4c7..54b1af0028c 100644 --- a/simcity.cc +++ b/simcity.cc @@ -1188,10 +1188,13 @@ void stadt_t::verbinde_fabriken() { DBG_MESSAGE("stadt_t::verbinde_fabriken()", "search factories near %s (center at %i,%i)", get_name(), pos.x, pos.y); - slist_iterator_tpl<fabrik_t*> fab_iter(welt->get_fab_list()); + //slist_iterator_tpl<fabrik_t*> fab_iter(welt->get_fab_list()); arbeiterziele.clear(); - while (fab_iter.next()) { - add_factory_arbeiterziel(fab_iter.get_current()); + for(sint16 i = welt->get_fab_list().get_count() - 1; i >= 0; i --) + { + //while (fab_iter.next()) { + //add_factory_arbeiterziel(fab_iter.get_current()); + add_factory_arbeiterziel(welt->get_fab_list()[i]); } DBG_MESSAGE("stadt_t::verbinde_fabriken()", "is connected with %i factories (sum_weight=%i).", arbeiterziele.get_count(), arbeiterziele.get_sum_weight()); } @@ -1359,7 +1362,8 @@ void stadt_t::neuer_monat() //"New month" (Google) // everywhere will become completely clogged with traffic. Linear rather than logorithmic scaling so // that the player can have a better idea visually of the amount of traffic. -#ifdef DESTINATION_CITYCARS +#define DESTINATION_CITYCARS +#ifdef DESTINATION_CITYCARS // Subtract incoming trips and cars already generated to prevent double counting. sint16 factor = city_history_month[1][HIST_CITYCARS] - incoming_private_cars - current_cars.count(); diff --git a/simfab.cc b/simfab.cc index aee64763e92..8ca7af48ce3 100644 --- a/simfab.cc +++ b/simfab.cc @@ -123,6 +123,82 @@ fabrik_t::rem_lieferziel(koord ziel) lieferziele.remove(ziel); } +bool +fabrik_t::disconnect_consumer(koord pos) //Returns true if must be destroyed. +{ + rem_lieferziel(pos); + if(lieferziele.get_count() < 1) + { + // If there are no consumers left, industry is orphaned. + // Reconnect or close. + bool is_orphaned = true; + + //HACK: Avoid problematic code for the time being. + return true; + + //Attempt to reconnect. + //Note: this code has problems, because there may be multiple consumers of different types. + //slist_iterator_tpl<fabrik_t*> fab_iter(welt->get_fab_list()); + //while (fab_iter.next()) + //{ + // fabrik_t* tmp = fab_iter.get_current(); + // for(sint16 n = tmp->get_besch()->get_lieferanten() - 1; n >= 0; n --) + // { + // const ware_besch_t* input = tmp->get_besch()->get_lieferant(n)->get_ware(); + // if(input == get_besch()->get_produkt(n)->get_ware()) + // { + // //Can connect + // add_lieferziel(tmp->get_pos().get_2d()); + // tmp->add_supplier(this); + // // Only add one. + // is_orphaned = false; + // break; + // } + // } + //} + //If we have reached here, we are orphaned, and cannot reconnect. + return is_orphaned; + } + return false; +} + +bool +fabrik_t::disconnect_supplier(koord pos) //Returns true if must be destroyed. +{ + rem_supplier(pos); + if(suppliers.get_count() < 1) + { + // If there are no suppliers left, industry is orphaned. + // Reconnect or close. + + //HACK: Avoid problematic code for the time being. + return true; + + //Attempt to reconnect. + //Note: this code has problems, because there may be multiple consumers of different types. + //slist_iterator_tpl<fabrik_t*> fab_iter(welt->get_fab_list()); + //while (fab_iter.next()) + //{ + // fabrik_t* tmp = fab_iter.get_current(); + // for(sint16 n = tmp->get_besch()->get_produkte() - 1; n >= 0; n --) + // { + // const ware_besch_t* output = tmp->get_besch()->get_produkt(n)->get_ware(); + // if(output == get_besch()->get_lieferant(n)->get_ware()) + // { + // //Can connect + // add_supplier(tmp); + // tmp->add_lieferziel(get_pos().get_2d()); + // // Only add one. + // return false; + // } + // } + //} + //If we have reached here, we are orphaned, and cannot reconnect. + return true; + } + return false; +} + fabrik_t::fabrik_t(karte_t* wl, loadsave_t* file) { @@ -205,7 +281,8 @@ fabrik_t::fabrik_t(koord3d pos_, spieler_t* spieler, const fabrik_besch_t* fabes fabrik_t::~fabrik_t() { - while(!fields.empty()) { + while(!fields.empty()) + { planquadrat_t *plan = welt->access( fields.back() ); assert(plan); grund_t *gr = plan->get_kartenboden(); @@ -216,6 +293,8 @@ fabrik_t::~fabrik_t() plan->get_kartenboden()->calc_bild(); } + fabrik_t* tmp = this; + //Disconnect this factory from all chains. //@author: jamespetts uint32 number_of_customers = lieferziele.get_count(); @@ -226,15 +305,31 @@ fabrik_t::~fabrik_t() char buf[192]; uint16 jobs = besch->get_pax_level(); sprintf(buf, translator::translate("Industry: %s has closed down, with the loss of %d jobs. %d upstream suppliers and %d downstream customers are affected."), translator::translate(get_name()), jobs, number_of_suppliers, number_of_customers); - welt->get_message()->add_message(buf, pos.get_2d(),message_t::general,COL_RED,skinverwaltung_t::neujahrsymbol->get_bild_nr(0)); + welt->get_message()->add_message(buf, pos.get_2d(), message_t::general, COL_DARK_RED, skinverwaltung_t::neujahrsymbol->get_bild_nr(0)); for(sint32 i = number_of_customers - 1; i >= 0; i --) { - get_fab(welt, lieferziele[i])->rem_lieferziel(pos.get_2d()); + fabrik_t* tmp = get_fab(welt, lieferziele[i]); + if(tmp->disconnect_supplier(pos.get_2d())) + { + //Orphaned, must be deleted. + grund_t *gr = 0; + gr = welt->lookup(tmp->get_pos()); + gebaeude_t* gb = gr->find<gebaeude_t>(); + hausbauer_t::remove(welt, welt->get_spieler(1), gb); + } } for(sint32 i = number_of_suppliers - 1; i >= 0; i --) { - get_fab(welt, suppliers[i])->rem_supplier(pos.get_2d()); + fabrik_t* tmp = get_fab(welt, suppliers[i]); + if(tmp->disconnect_consumer(pos.get_2d())) + { + //Orphaned, must be deleted. + grund_t *gr = 0; + gr = welt->lookup(tmp->get_pos()); + gebaeude_t* gb = gr->find<gebaeude_t>(); + hausbauer_t::remove(welt, welt->get_spieler(1), gb); + } } } } @@ -1121,6 +1216,49 @@ fabrik_t::neuer_monat() ausgang[index].abgabe_letzt = ausgang[index].abgabe_sum; ausgang[index].abgabe_sum = 0; } + + // Check to see whether factory is obsolete. + // If it is, give it a chance of being closed down. + //@author: jamespetts + + if(welt->use_timeline() && besch->get_haus()->get_retire_year_month() < welt->get_timeline_year_month()) + { + uint32 difference = welt->get_timeline_year_month() - besch->get_haus()->get_retire_year_month(); + uint32 max_difference = welt->get_einstellungen()->get_factory_max_years_obsolete() * 12; + if(difference > max_difference) + { + uint32 number_of_customers = lieferziele.get_count(); + uint32 number_of_suppliers = suppliers.get_count(); + char buf[192]; + uint16 jobs = besch->get_pax_level(); + sprintf(buf, translator::translate("Industry: %s has closed down, with the loss of %d jobs. %d upstream suppliers and %d downstream customers are affected."), translator::translate(get_name()), jobs, number_of_suppliers, number_of_customers); + welt->get_message()->add_message(buf, pos.get_2d(), message_t::general, COL_DARK_RED, skinverwaltung_t::neujahrsymbol->get_bild_nr(0)); + grund_t *gr = 0; + gr = welt->lookup(pos); + gebaeude_t* gb = gr->find<gebaeude_t>(); + hausbauer_t::remove(welt, welt->get_spieler(1), gb); + } + else + { + float proportion = (float)difference / (float)max_difference; + proportion *= 100; //Set to percentage value. + uint8 chance = simrand(100); + if(chance <= proportion) + { + uint32 number_of_customers = lieferziele.get_count(); + uint32 number_of_suppliers = suppliers.get_count(); + char buf[192]; + uint16 jobs = besch->get_pax_level(); + sprintf(buf, translator::translate("Industry: %s has closed down, with the loss of %d jobs. %d upstream suppliers and %d downstream customers are affected."), translator::translate(get_name()), jobs, number_of_suppliers, number_of_customers); + welt->get_message()->add_message(buf, pos.get_2d(), message_t::general, COL_DARK_RED, skinverwaltung_t::neujahrsymbol->get_bild_nr(0)); + grund_t *gr = 0; + gr = welt->lookup(pos); + gebaeude_t* gb = gr->find<gebaeude_t>(); + hausbauer_t::remove(welt, welt->get_spieler(1), gb); + } + } + } + } @@ -1506,12 +1644,15 @@ fabrik_t::add_all_suppliers() const fabrik_lieferant_besch_t *lieferant = besch->get_lieferant(i); const ware_besch_t *ware = lieferant->get_ware(); - const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); - slist_iterator_tpl <fabrik_t *> iter (list); + //const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); + const vector_tpl<fabrik_t*> & list = welt->get_fab_list(); + //slist_iterator_tpl <fabrik_t *> iter (list); - while( iter.next() ) { - - fabrik_t * fab = iter.get_current(); + //while( iter.next() ) { + for(sint16 i = list.get_count() - 1; i >= 0; i --) + { + //fabrik_t * fab = iter.get_current(); + fabrik_t * fab = list[i]; // connect to an existing one, if this is an producer if(fab!=this && fab->vorrat_an(ware) > -1) { diff --git a/simfab.h b/simfab.h index 7d7c3f39808..2fa7160c8a1 100644 --- a/simfab.h +++ b/simfab.h @@ -207,6 +207,9 @@ class fabrik_t void add_lieferziel(koord ziel); void rem_lieferziel(koord pos); + bool disconnect_consumer(koord pos); + bool disconnect_supplier(koord pos); + /** * adds a supplier * @author Hj. Malthaner diff --git a/simwerkz.cc b/simwerkz.cc index 3078ce3be75..3ad6169794e 100644 --- a/simwerkz.cc +++ b/simwerkz.cc @@ -2943,10 +2943,14 @@ const char *wkz_build_industries_land_t::work( karte_t *welt, spieler_t *sp, koo // crossconnect all? if(welt->get_einstellungen()->is_crossconnect_factories()) { - const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); - slist_iterator_tpl <fabrik_t *> iter (list); - while( iter.next() ) { - iter.get_current()->add_all_suppliers(); + //const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); + const vector_tpl<fabrik_t *> & list = welt->get_fab_list(); + //slist_iterator_tpl <fabrik_t *> iter (list); + //while( iter.next() ) { + for(sint16 i = list.get_count() - 1; i >= 0; i --) + { + //iter.get_current()->add_all_suppliers(); + list[i]->add_all_suppliers(); } } return NULL; @@ -3015,10 +3019,14 @@ const char *wkz_build_industries_city_t::work( karte_t *welt, spieler_t *sp, koo // crossconnect all? if(welt->get_einstellungen()->is_crossconnect_factories()) { - const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); - slist_iterator_tpl <fabrik_t *> iter (list); - while( iter.next() ) { - iter.get_current()->add_all_suppliers(); + //const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); + const vector_tpl<fabrik_t *> & list = welt->get_fab_list(); + //slist_iterator_tpl <fabrik_t *> iter (list); + //while( iter.next() ) { + for(sint16 i = list.get_count() - 1; i >= 0; i --) + { + //iter.get_current()->add_all_suppliers(); + list[i]->add_all_suppliers(); } } // ain't going to be cheap @@ -3111,10 +3119,14 @@ const char *wkz_build_factory_t::work( karte_t *welt, spieler_t *sp, koord3d k ) // crossconnect all? if(welt->get_einstellungen()->is_crossconnect_factories()) { - const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); - slist_iterator_tpl <fabrik_t *> iter (list); - while( iter.next() ) { - iter.get_current()->add_all_suppliers(); + //const slist_tpl<fabrik_t *> & list = welt->get_fab_list(); + const vector_tpl<fabrik_t *> & list = welt->get_fab_list(); + //slist_iterator_tpl <fabrik_t *> iter (list); + //while( iter.next() ) { + for(sint16 i = list.get_count() - 1; i >= 0; i --) + { + //iter.get_current()->add_all_suppliers(); + list[i]->add_all_suppliers(); } } return NULL; diff --git a/simworld.cc b/simworld.cc index 19a09397d73..9f5de6da251 100644 --- a/simworld.cc +++ b/simworld.cc @@ -606,9 +606,13 @@ DBG_MESSAGE("karte_t::destroy()", "player destroyed"); DBG_MESSAGE("karte_t::destroy()", "lines destroyed"); // alle fabriken aufräumen - slist_iterator_tpl<fabrik_t*> fab_iter(fab_list); - while(fab_iter.next()) { - delete fab_iter.get_current(); + // "all factories clear up" (Babelfish) + //slist_iterator_tpl<fabrik_t*> fab_iter(fab_list); + //while(fab_iter.next()) { + for(sint16 i = fab_list.get_count() - 1; i >= 0; i --) + { + //delete fab_iter.get_current(); + delete fab_list[i]; } fab_list.clear(); DBG_MESSAGE("karte_t::destroy()", "factories destroyed"); @@ -687,10 +691,13 @@ bool karte_t::rem_stadt(stadt_t *s) einstellungen->set_anzahl_staedte(einstellungen->get_anzahl_staedte()-1); // remove all links from factories - DBG_MESSAGE("karte_t::rem_stadt()", "fab_list %i", fab_list.count() ); - slist_iterator_tpl<fabrik_t *> iter(fab_list); - while(iter.next()) { - (iter.get_current())->remove_arbeiterziel(s); + DBG_MESSAGE("karte_t::rem_stadt()", "fab_list %i", fab_list.get_count() ); + //slist_iterator_tpl<fabrik_t *> iter(fab_list); + //while(iter.next()) { + for(sint16 i = fab_list.get_count() - 1; i >= 0; i --) + { + //(iter.get_current())->remove_arbeiterziel(s); + fab_list[i]->remove_arbeiterziel(s); } // ok, we can delete this @@ -1094,7 +1101,7 @@ DBG_DEBUG("karte_t::init()","hausbauer_t::neue_karte()"); int progress_count = 16 + einstellungen->get_anzahl_staedte()*4 + i; display_progress(progress_count, max_display_progress ); } - finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.count(); + finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.get_count(); // tourist attractions fabrikbauer_t::verteile_tourist(this, einstellungen->get_tourist_attractions()); @@ -1388,6 +1395,8 @@ void karte_t::enlarge_map(einstellungen_t* sets, sint8 *h_field) karte_t::karte_t() : convoi_array(0), ausflugsziele(16), stadt(0), marker(0,0) { + is_shutting_down = false; + // length of day and other time stuff ticks_bits_per_tag = 20; ticks_per_tag = (1 << ticks_bits_per_tag); @@ -1936,9 +1945,12 @@ karte_t::rotate90() (*i)->rotate90( cached_groesse_karte_x ); } - slist_iterator_tpl<fabrik_t *> iter(fab_list); - while(iter.next()) { - iter.get_current()->rotate90( cached_groesse_karte_x ); + //slist_iterator_tpl<fabrik_t *> iter(fab_list); + //while(iter.next()) { + for(sint16 i = fab_list.get_count() - 1; i >= 0; i --) + { + //iter.get_current()->rotate90( cached_groesse_karte_x ); + fab_list[i]->rotate90( cached_groesse_karte_x ); } slist_iterator_tpl <halthandle_t> halt_iter (haltestelle_t::get_alle_haltestellen()); @@ -2002,7 +2014,8 @@ karte_t::add_fab(fabrik_t *fab) { //DBG_MESSAGE("karte_t::add_fab()","fab = %p",fab); assert(fab != NULL); - fab_list.insert( fab ); + //fab_list.insert( fab ); + fab_list.push_back(fab); return true; } @@ -2011,9 +2024,16 @@ karte_t::add_fab(fabrik_t *fab) // beware: must remove also links from stops and towns bool karte_t::rem_fab(fabrik_t *fab) { - if(!fab_list.remove( fab )) { + //if(!fab_list.remove( fab )) { + //if(fab_list.remove_at(fab_list.index_of(fab))) + if(!fab_list.is_contained(fab)) + { return false; } + else + { + fab_list.remove(fab); + } // now all the interwoven connections must be cleared koord pos = fab->get_pos().get_2d(); @@ -2033,12 +2053,28 @@ bool karte_t::rem_fab(fabrik_t *fab) } // remove all links from factories - slist_iterator_tpl<fabrik_t *> iter (fab_list); - while(iter.next()) { - fabrik_t * fab = iter.get_current(); - fab->rem_lieferziel(pos); - fab->rem_supplier(pos); - } + //slist_iterator_tpl<fabrik_t *> iter (fab_list); + //while(iter.next()) { + // fabrik_t * fab = iter.get_current(); + // /*fab->rem_lieferziel(pos); + // fab->rem_supplier(pos);*/ + // + // //Delete orphaned factories + // bool is_orphaned_consumer = false; + // bool is_orphaned_supplier = false; + // if(fab->get_lieferziele().get_count() > 0) + // { + // is_orphaned_consumer = fab->disconnect_consumer(fab->get_pos().get_2d()); + // } + // if(fab->get_suppliers().get_count() > 0) + // { + // is_orphaned_supplier = fab->disconnect_supplier(fab->get_pos().get_2d()); + // } + // if(is_orphaned_consumer || is_orphaned_supplier) + // { + // rem_fab(fab); + // } + //} // remove all links to cities slist_iterator_tpl<stadt_t *> iter_city (fab->get_arbeiterziele()); @@ -2058,12 +2094,12 @@ bool karte_t::rem_fab(fabrik_t *fab) fabrik_t * karte_t::get_random_fab() const { - const int anz = fab_list.count(); + const int anz = fab_list.get_count(); fabrik_t *result = NULL; if(anz > 0) { const int end = simrand( anz ); - result = fab_list.at(end); + result = fab_list[end]; } return result; } @@ -2339,31 +2375,25 @@ void karte_t::neuer_monat() INT_CHECK("simworld 1701"); + // DBG_MESSAGE("karte_t::neuer_monat()","factories"); - slist_iterator_tpl<fabrik_t*> iter (fab_list); - while(iter.next()) { - fabrik_t * fab = iter.get_current(); + //slist_iterator_tpl<fabrik_t*> iter (fab_list); + sint16 number_of_factories = fab_list.get_count(); + for(sint16 i = number_of_factories - 1; i >= 0; i--) + { + fabrik_t * fab = fab_list[i]; fab->neuer_monat(); + // The number of factories might have diminished, + // so must adjust i to prevent out of bounds errors. + sint16 difference = number_of_factories - fab_list.get_count(); + i -= difference; } + /*while(iter.next()) { + fabrik_t * fab = iter.get_current(); + fab->neuer_monat(); + }*/ INT_CHECK("simworld 1278"); - -// DBG_MESSAGE("karte_t::neuer_monat()","cities"); - // roll city history and copy the new citicens (i.e. the new weight) into the stadt array - // no INT_CHECK() here, or dialoges will go crazy!!! - weighted_vector_tpl<stadt_t*> new_weighted_stadt(stadt.get_count() + 1); - outstanding_cars = 0; - for (weighted_vector_tpl<stadt_t*>::const_iterator i = stadt.begin(), end = stadt.end(); i != end; ++i) { - stadt_t* s = *i; - s->neuer_monat(); - outstanding_cars += s->get_outstanding_cars(); - new_weighted_stadt.append(s, s->get_einwohner(), 64); - INT_CHECK("simworld 1278"); - } - swap(stadt, new_weighted_stadt); - - INT_CHECK("simworld 1282"); - // DBG_MESSAGE("karte_t::neuer_monat()","players"); // spieler for(int i=0; i<MAX_PLAYER_COUNT; i++) { @@ -2738,11 +2768,14 @@ karte_t::step() // the inhabitants stuff finance_history_month[0][WORLD_CITICENS] = bev; - slist_iterator_tpl<fabrik_t *> iter(fab_list); - while(iter.next()) { - iter.get_current()->step(delta_t); + //slist_iterator_tpl<fabrik_t *> iter(fab_list); + //while(iter.next()) { + for(sint16 i = fab_list.get_count() - 1; i >= 0; i --) + { + //iter.get_current()->step(delta_t); + fab_list[i]->step(delta_t); } - finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.count(); + finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.get_count(); // then step all players for( int i=0; i<MAX_PLAYER_COUNT; i++ ) { @@ -2865,7 +2898,7 @@ void karte_t::restore_history() void karte_t::update_history() { finance_history_year[0][WORLD_CONVOIS] = finance_history_month[0][WORLD_CONVOIS] = convoi_array.get_count(); - finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.count(); + finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.get_count(); // now step all towns (to generate passengers) sint64 bev=0; @@ -3243,11 +3276,14 @@ DBG_MESSAGE("karte_t::speichern(loadsave_t *file)", "saved tiles"); } DBG_MESSAGE("karte_t::speichern(loadsave_t *file)", "saved hgt"); - sint32 fabs = fab_list.count(); + sint32 fabs = fab_list.get_count(); file->rdwr_long(fabs, "\n"); - slist_iterator_tpl<fabrik_t*> fiter( fab_list ); - while(fiter.next()) { - (fiter.get_current())->rdwr(file); + //slist_iterator_tpl<fabrik_t*> fiter( fab_list ); + //while(fiter.next()) { + for(uint16 i = fab_list.get_count() - 1; i >= 0; i --) + { + //(fiter.get_current())->rdwr(file); + fab_list[i]->rdwr(file); if(silent) { INT_CHECK("saving"); } @@ -3564,7 +3600,8 @@ DBG_MESSAGE("karte_t::laden()","loading grid"); // liste in gleicher reihenfolge wie vor dem speichern wieder aufbauen fabrik_t *fab = new fabrik_t(this, file); if(fab->get_besch()) { - fab_list.append( fab ); + //fab_list.append( fab ); + fab_list.push_back(fab); } else { dbg->error("karte_t::laden()","Unknown fabrik skipped!"); @@ -3575,14 +3612,17 @@ DBG_MESSAGE("karte_t::laden()","loading grid"); } DBG_MESSAGE("karte_t::laden()", "clean up factories"); - slist_iterator_tpl<fabrik_t*> fiter ( fab_list ); - while(fiter.next()) { - fiter.get_current()->laden_abschliessen(); + //slist_iterator_tpl<fabrik_t*> fiter ( fab_list ); + //while(fiter.next()) { + for(sint16 i = fab_list.get_count() - 1; i >= 0; i --) + { + //fiter.get_current()->laden_abschliessen(); + fab_list[i]->laden_abschliessen(); } display_progress(get_groesse_y()+24, get_groesse_y()+256+stadt.get_count()); -DBG_MESSAGE("karte_t::laden()", "%d factories loaded", fab_list.count()); +DBG_MESSAGE("karte_t::laden()", "%d factories loaded", fab_list.get_count()); // must be done after reliefkarte is initialized int x = get_groesse_y() + 24; diff --git a/simworld.h b/simworld.h index 16fab7aef92..17a1567f6f1 100644 --- a/simworld.h +++ b/simworld.h @@ -196,7 +196,8 @@ class karte_t vector_tpl<convoihandle_t> convoi_array; - slist_tpl<fabrik_t *> fab_list; + //slist_tpl<fabrik_t *> fab_list; + vector_tpl<fabrik_t *> fab_list; weighted_vector_tpl<gebaeude_t *> ausflugsziele; @@ -212,6 +213,7 @@ class karte_t // The number of cars that should be in the world somewhere, but are not // in any particular city's list. + //@author: jamespetts sint16 outstanding_cars; // word record of speed ... @@ -289,7 +291,7 @@ class karte_t * Die Spieler * @author Hj. Malthaner */ - spieler_t *spieler[MAX_PLAYER_COUNT]; // Mensch ist spieler Nr. 0 + spieler_t *spieler[MAX_PLAYER_COUNT]; // Mensch ist spieler Nr. 0 "Humans are player no. 0" spieler_t *active_player; uint8 active_player_nr; @@ -870,8 +872,8 @@ class karte_t bool add_fab(fabrik_t *fab); bool rem_fab(fabrik_t *fab); int get_fab_index(fabrik_t* fab) { return fab_list.index_of(fab); } - fabrik_t* get_fab(unsigned index) { return index < fab_list.count() ? fab_list.at(index) : NULL; } - const slist_tpl<fabrik_t*>& get_fab_list() const { return fab_list; } + fabrik_t* get_fab(unsigned index) { return index < fab_list.get_count() ? fab_list[index] : NULL; } + const vector_tpl<fabrik_t*>& get_fab_list() const { return fab_list; } /* sucht zufaellig eine Fabrik aus der Fabrikliste * @author Hj. Malthaner From 3fffc668b5118aba30b17a8448f3addbbcd57740 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 8 Feb 2009 16:09:07 +0000 Subject: [PATCH 15/61] When industries close, other industries in the same chain attempt to connect to any remaining industries of a suitable type. --- bauer/fabrikbauer.cc | 16 ++++++++ simfab.cc | 91 +++++++++++++++++++++----------------------- simfab.h | 7 ++++ 3 files changed, 66 insertions(+), 48 deletions(-) diff --git a/bauer/fabrikbauer.cc b/bauer/fabrikbauer.cc index c69c3cbe857..2dd517f1336 100644 --- a/bauer/fabrikbauer.cc +++ b/bauer/fabrikbauer.cc @@ -375,6 +375,7 @@ void fabrikbauer_t::verteile_tourist(karte_t* welt, int max_number) /** * baue fabrik nach Angaben in info + * "build the factory, according to info" (Google) * @author Hj.Malthaner */ fabrik_t* fabrikbauer_t::baue_fabrik(karte_t* welt, koord3d* parent, const fabrik_besch_t* info, int rotate, koord3d pos, spieler_t* spieler) @@ -524,6 +525,13 @@ int fabrikbauer_t::baue_hierarchie(koord3d* parent, const fabrik_besch_t* info, // Das könnte ein Zeitproblem geben, wenn eine Stadt keine solchen Bauplatz // hat und die Suche bis zur nächsten Stadt weiterläuft // Ansonsten erscheint mir das am realistischtsten.. + + /* Three variants: + * A: + * A building site, preferably close to the town hall with a street next to it. + * This could be a temporary problem, if a city has no such site and the search until + * the next city continues Otherwise seems to me the most realistic Google)*/ + bool is_rotate=info->get_haus()->get_all_layouts()>1; k = factory_bauplatz_mit_strasse_sucher_t(welt).suche_platz(sf.stadt->get_pos(), size.x, size.y, info->get_haus()->get_allowed_climate_bits(), &is_rotate); rotate = is_rotate?1:0; @@ -533,13 +541,21 @@ int fabrikbauer_t::baue_hierarchie(koord3d* parent, const fabrik_besch_t* info, // B: // Gefällt mir auch. Die Endfabriken stehen eventuell etwas außerhalb der Stadt // aber nicht weit weg. + + // Pleases me also. The final factories stand possibly somewhat outside of the city however not far away. (Babelfish) // (does not obey climates though!) + // k = finde_zufallsbauplatz(welt, welt->lookup(sf.stadt->get_pos())->get_boden()->get_pos(), 3, land_bau.dim).get_2d(); // C: // Ein Bauplatz, möglichst nah am Rathaus. // Wenn mehrere Endfabriken bei einer Stadt landen, sind die oft hinter // einer Reihe Häuser "versteckt", von Strassen abgeschnitten. + + // A building site, as near as possible at the city hall. + // If several final factories land with a city, often behind + // a row the houses are hidden, of roads cut off.(Babelfish) + //k = bauplatz_sucher_t(welt).suche_platz(sf.stadt->get_pos(), land_bau.dim.x, land_bau.dim.y, info->get_haus()->get_allowed_climate_bits(), &is_rotate); if(k != koord::invalid) { diff --git a/simfab.cc b/simfab.cc index 8ca7af48ce3..175fc446cf2 100644 --- a/simfab.cc +++ b/simfab.cc @@ -131,33 +131,19 @@ fabrik_t::disconnect_consumer(koord pos) //Returns true if must be destroyed. { // If there are no consumers left, industry is orphaned. // Reconnect or close. - bool is_orphaned = true; - //HACK: Avoid problematic code for the time being. - return true; + //Attempt to reconnect. NOTE: This code may not work well if there are multiple supply types. - //Attempt to reconnect. - //Note: this code has problems, because there may be multiple consumers of different types. - //slist_iterator_tpl<fabrik_t*> fab_iter(welt->get_fab_list()); - //while (fab_iter.next()) - //{ - // fabrik_t* tmp = fab_iter.get_current(); - // for(sint16 n = tmp->get_besch()->get_lieferanten() - 1; n >= 0; n --) - // { - // const ware_besch_t* input = tmp->get_besch()->get_lieferant(n)->get_ware(); - // if(input == get_besch()->get_produkt(n)->get_ware()) - // { - // //Can connect - // add_lieferziel(tmp->get_pos().get_2d()); - // tmp->add_supplier(this); - // // Only add one. - // is_orphaned = false; - // break; - // } - // } - //} - //If we have reached here, we are orphaned, and cannot reconnect. - return is_orphaned; + for(sint16 i = welt->get_fab_list().get_count() - 1; i >= 0; i --) + { + fabrik_t* fab = welt->get_fab_list()[i]; + if(add_customer(fab)) + { + //Only reconnect one. + return false; + } + } + return true; } return false; } @@ -171,29 +157,18 @@ fabrik_t::disconnect_supplier(koord pos) //Returns true if must be destroyed. // If there are no suppliers left, industry is orphaned. // Reconnect or close. - //HACK: Avoid problematic code for the time being. - return true; + //Attempt to reconnect. NOTE: This code may not work well if there are multiple supply types. + + for(sint16 i = welt->get_fab_list().get_count() - 1; i >= 0; i --) + { - //Attempt to reconnect. - //Note: this code has problems, because there may be multiple consumers of different types. - //slist_iterator_tpl<fabrik_t*> fab_iter(welt->get_fab_list()); - //while (fab_iter.next()) - //{ - // fabrik_t* tmp = fab_iter.get_current(); - // for(sint16 n = tmp->get_besch()->get_produkte() - 1; n >= 0; n --) - // { - // const ware_besch_t* output = tmp->get_besch()->get_produkt(n)->get_ware(); - // if(output == get_besch()->get_lieferant(n)->get_ware()) - // { - // //Can connect - // add_supplier(tmp); - // tmp->add_lieferziel(get_pos().get_2d()); - // // Only add one. - // return false; - // } - // } - //} - //If we have reached here, we are orphaned, and cannot reconnect. + fabrik_t* fab = welt->get_fab_list()[i]; + if(add_supplier(fab)) + { + //Only reconnect one. + return false; + } + } return true; } return false; @@ -1675,7 +1650,7 @@ bool fabrik_t::add_supplier(fabrik_t* fab) const ware_besch_t *ware = lieferant->get_ware(); // connect to an existing one, if this is an producer - if(fab!=this && fab->vorrat_an(ware) > -1) { + if(fab!=this && fab->vorrat_an(ware) > -1) { //"inventory to" (Google) // add us to this factory fab->add_lieferziel(pos.get_2d()); return true; @@ -1683,3 +1658,23 @@ bool fabrik_t::add_supplier(fabrik_t* fab) } return false; } + +/* adds a new customer to this factory + * fails if no matching goods are accepted + */ + +bool fabrik_t::add_customer(fabrik_t* fab) +{ + for(int i=0; i < fab->get_besch()->get_lieferanten(); i++) { + const fabrik_lieferant_besch_t *lieferant = fab->get_besch()->get_lieferant(i); + const ware_besch_t *ware = lieferant->get_ware(); + + // connect to an existing one, if it is a consumer + if(fab!=this && vorrat_an(ware) > -1) { //"inventory to" (Google) + // add this factory + add_lieferziel(fab->pos.get_2d()); + return true; + } + } + return false; +} diff --git a/simfab.h b/simfab.h index 2fa7160c8a1..fc1b8bfe3b7 100644 --- a/simfab.h +++ b/simfab.h @@ -217,6 +217,8 @@ class fabrik_t void add_supplier(koord pos); void rem_supplier(koord pos); + + /** * @return menge der ware typ ("quantity of the goods type") * -1 wenn typ nicht produziert wird ("if not type is produced") @@ -339,6 +341,11 @@ class fabrik_t * fails if no matching goods are there */ bool add_supplier(fabrik_t* fab); + + /* adds a new customer to this factory + * fails if no matching goods are accepted + */ + bool add_customer(fabrik_t* fab); }; #endif From 1cf1a5b644b6a2f4b5391d1d4dedcabca323c716 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 9 Feb 2009 23:10:01 +0000 Subject: [PATCH 16/61] (1) Corrected a bug in the previous version that caused a crash when saving; (2) changed halt_list from an slist_tpl to a vector_tpl to improve performance; (3) added the ability to see the origin of goods/passengers/mail in the info window for stops and convoys (although note that this information is not yet properly preserved at transfer stops; this work is in preparation for the planned new revenue system). --- freight_list_sorter.cc | 50 +++++++++++++++++++++++++++++++----------- freight_list_sorter.h | 2 +- gui/convoi_frame.cc | 2 +- gui/convoi_frame.h | 2 +- gui/convoi_info_t.cc | 19 +++++++++++----- gui/convoi_info_t.h | 2 +- gui/halt_info.cc | 7 +++--- player/ai.cc | 3 ++- player/ai_passenger.cc | 12 ++++++---- player/simplay.cc | 22 ++++++++++++------- player/simplay.h | 3 ++- simworld.cc | 2 +- 12 files changed, 85 insertions(+), 41 deletions(-) diff --git a/freight_list_sorter.cc b/freight_list_sorter.cc index 9f517096ae0..c95e50922d9 100644 --- a/freight_list_sorter.cc +++ b/freight_list_sorter.cc @@ -18,6 +18,7 @@ struct travel_details ware_t ware; halthandle_t destination; halthandle_t via_destination; + halthandle_t origin; }; @@ -36,12 +37,14 @@ int freight_list_sorter_t::compare_ware(const void *td1, const void *td2) halthandle_t halt2 = td2p->destination; halthandle_t via_halt1 = td1p->via_destination; halthandle_t via_halt2 = td2p->via_destination; + halthandle_t origin_halt1 = td1p->origin; + halthandle_t origin_halt2 = td2p->origin; - if(!halt1.is_bound() || !via_halt1.is_bound()) { + if(!halt1.is_bound() || !via_halt1.is_bound() || !origin_halt1.is_bound()) { return -1; } - if( !halt2.is_bound() || !via_halt2.is_bound() ) { + if( !halt2.is_bound() || !via_halt2.is_bound() || !origin_halt2.is_bound()) { return -2; } @@ -75,6 +78,11 @@ dbg->error("freight_list_sorter::compare_ware()","illegal sort mode!"); if (order != 0) break; /* FALLTHROUGH */ + case by_origin: + order = strcmp(origin_halt1->get_name(), origin_halt2->get_name()); + if (order != 0) break; + /* FALLTHROUGH */ + case by_name: // sort by destination name order = strcmp(halt1->get_name(), halt2->get_name()); break; @@ -116,7 +124,7 @@ void freight_list_sorter_t::sort_freight(const vector_tpl<ware_t>* warray, cbuff // if there, give the capacity for each freight slist_tpl <ware_t> dummy; slist_iterator_tpl<ware_t> full_iter ( full_list==NULL ? &dummy : full_list ); - bool list_finish=1; + bool list_finish = true; // hsiegeln // added sorting to ware's destination list @@ -132,6 +140,7 @@ void freight_list_sorter_t::sort_freight(const vector_tpl<ware_t>* warray, cbuff tdlist[pos].ware = ware; tdlist[pos].destination = ware.get_ziel(); tdlist[pos].via_destination = ware.get_zwischenziel(); + tdlist[pos].origin = ware.get_origin(); // for the sorting via the number for the next stop we unify entries if(sort_mode==by_via_sum && pos>0) { //DBG_MESSAGE("freight_list_sorter_t::get_freight_info()","for halt %i check connection",pos); @@ -160,6 +169,7 @@ void freight_list_sorter_t::sort_freight(const vector_tpl<ware_t>* warray, cbuff for (int j = 0; j<pos; j++) { halthandle_t halt = tdlist[j].destination; halthandle_t via_halt = tdlist[j].via_destination; + halthandle_t origin_halt = tdlist[j].origin; const char * name = "Error in Routing"; if(halt.is_bound()) { @@ -211,25 +221,39 @@ void freight_list_sorter_t::sort_freight(const vector_tpl<ware_t>* warray, cbuff buf.append(translator::translate(ware.get_besch()->get_name())); buf.append(" > "); // the target name is not correct for the via sort - if(sortby!=by_via_sum || via_halt==halt ) { + if(sortby != by_via_sum || via_halt==halt ) + { buf.append(name); } // for debugging - const char *via_name = "Error in Routing"; - if(via_halt.is_bound()) { - via_name = via_halt->get_name(); - } - if(via_halt != halt) { + if(via_halt != halt && (sortby == by_via || sortby == by_via_sum)) + { + const char *via_name = "unknown"; + if(via_halt.is_bound()) + { + via_name = via_halt->get_name(); + } char tmp [512]; - sprintf(tmp, translator::translate("via %s\n"), via_name); + sprintf(tmp, translator::translate(" via %s"), via_name); buf.append(tmp); } - else { - buf.append("\n"); - } // debug ende + + if(sortby == by_origin) + { + const char *origin_name = "unknown"; + if(origin_halt.is_bound()) + { + origin_name = origin_halt->get_name(); + } + + char tmp [512]; + sprintf(tmp, translator::translate(" from %s"), origin_name); + buf.append(tmp); + } + buf.append("\n"); } } diff --git a/freight_list_sorter.h b/freight_list_sorter.h index 4d85a4cf3c3..9e53a19eb40 100644 --- a/freight_list_sorter.h +++ b/freight_list_sorter.h @@ -12,7 +12,7 @@ class ware_t; class freight_list_sorter_t { public: - enum sort_mode_t { by_name=0, by_via=1, by_via_sum=2, by_amount=3}; + enum sort_mode_t { by_name=0, by_via=1, by_via_sum=2, by_amount=3, by_origin=4}; static void sort_freight(const vector_tpl<ware_t>* warray, cbuffer_t& buf, sort_mode_t sort_mode, const slist_tpl<ware_t>* full_list, const char* what_doing); diff --git a/gui/convoi_frame.cc b/gui/convoi_frame.cc index f2372be4be3..5faa5b453fa 100644 --- a/gui/convoi_frame.cc +++ b/gui/convoi_frame.cc @@ -47,7 +47,7 @@ const char *convoi_frame_t::sort_text[SORT_MODES] = { "cl_btn_sort_name", "cl_btn_sort_income", "cl_btn_sort_type", - "cl_btn_sort_id" + "cl_btn_sort_id", }; diff --git a/gui/convoi_frame.h b/gui/convoi_frame.h index f4269dd9f57..3dad2a257e1 100644 --- a/gui/convoi_frame.h +++ b/gui/convoi_frame.h @@ -30,7 +30,7 @@ class convoi_frame_t : private action_listener_t //28-Dec-01 Markus Weber Added , private action_listener_t { public: - enum sort_mode_t { nach_name=0, nach_gewinn=1, nach_typ=2, nach_id=3, SORT_MODES=4 }; + enum sort_mode_t { nach_name=0, nach_gewinn=1, nach_typ=2, nach_id=3, SORT_MODES=5 }; enum filter_flag_t { any_filter=1, name_filter=2, typ_filter=4, ware_filter=8, spezial_filter=16, sub_filter=32, // Ab hier beginnen die Unterfilter! lkws_filter=32, zuege_filter=64, schiffe_filter=128, aircraft_filter=256, diff --git a/gui/convoi_info_t.cc b/gui/convoi_info_t.cc index 34fcaa02736..9fff1c203e1 100644 --- a/gui/convoi_info_t.cc +++ b/gui/convoi_info_t.cc @@ -46,17 +46,19 @@ bool convoi_info_t::route_search_in_progress=false; /** * This variable defines by which column the table is sorted - * Values: 0 = destination - * 1 = via - * 2 = via_amount - * 3 = amount - * @author prissi + * Values: 0 = destination + * 1 = via + * 2 = via_amount + * 3 = amount + * 4 = origin + * @author prissi - amended by jamespetts (origins) */ const char *convoi_info_t::sort_text[SORT_MODES] = { "Zielort", "via", "via Menge", - "Menge" + "Menge", + "origin" }; const int cost_type_color[MAX_CONVOI_COST] = @@ -197,6 +199,11 @@ convoi_info_t::convoi_info_t(convoihandle_t cnv) * komponente neu zeichnen. Die übergebenen Werte beziehen sich auf * das Fenster, d.h. es sind die Bildschirkoordinaten des Fensters * in dem die Komponente dargestellt wird. + * + * Component draw again. The handed over values refer to the window, + * i.e. there is the Bildschirkoordinaten of the window in that the + * component is represented. (Babelfish) + * * @author Hj. Malthaner */ void diff --git a/gui/convoi_info_t.h b/gui/convoi_info_t.h index 8ed7e3fe975..df8ccb252cc 100644 --- a/gui/convoi_info_t.h +++ b/gui/convoi_info_t.h @@ -30,7 +30,7 @@ class convoi_info_t : public gui_frame_t, private action_listener_t { public: - enum sort_mode_t { by_destination=0, by_via=1, by_amount_via=2, by_amount=3, SORT_MODES=4 }; + enum sort_mode_t { by_destination=0, by_via=1, by_amount_via=2, by_amount=3, by_origin=4, SORT_MODES=5 }; private: gui_scrollpane_t scrolly; diff --git a/gui/halt_info.cc b/gui/halt_info.cc index ce4f3a57736..61c3e19006a 100644 --- a/gui/halt_info.cc +++ b/gui/halt_info.cc @@ -26,11 +26,12 @@ karte_t *halt_info_t::welt = NULL; -static const char *sort_text[4] = { +static const char *sort_text[5] = { "Zielort", "via", "via Menge", - "Menge" + "Menge", + "origin" }; const char cost_type[MAX_HALT_COST][64] = @@ -275,7 +276,7 @@ bool halt_info_t::action_triggered( gui_action_creator_t *comp,value_t /* */) if (comp == &button) { // details button pressed create_win( new halt_detail_t(halt), w_info, (long)this); } else if (comp == &sort_button) { // @author hsiegeln sort button pressed - umgebung_t::default_sortmode = ((int)(halt->get_sortby())+1)%4; + umgebung_t::default_sortmode = ((int)(halt->get_sortby())+1)%5; halt->set_sortby((freight_list_sorter_t::sort_mode_t) umgebung_t::default_sortmode); sort_button.set_text(sort_text[umgebung_t::default_sortmode]); } else if (comp == &toggler) { diff --git a/player/ai.cc b/player/ai.cc index d102211f281..5140aee7be4 100755 --- a/player/ai.cc +++ b/player/ai.cc @@ -364,7 +364,8 @@ bool ai_t::built_update_headquarter() } // needs new place? if(place==koord::invalid && !halt_list.empty()) { - stadt_t *st = welt->suche_naechste_stadt(halt_list.front()->get_basis_pos()); + //stadt_t *st = welt->suche_naechste_stadt(halt_list.front()->get_basis_pos()); + stadt_t *st = welt->suche_naechste_stadt(halt_list[0]->get_basis_pos()); if(st) { bool is_rotate=besch->get_all_layouts()>1; place = ai_bauplatz_mit_strasse_sucher_t(welt).suche_platz(st->get_pos(), besch->get_b(), besch->get_h(), besch->get_allowed_climate_bits(), &is_rotate); diff --git a/player/ai_passenger.cc b/player/ai_passenger.cc index 8894816bc78..67c2490587e 100755 --- a/player/ai_passenger.cc +++ b/player/ai_passenger.cc @@ -69,14 +69,18 @@ bool ai_passenger_t::set_active(bool new_state) */ halthandle_t ai_passenger_t::get_our_hub( const stadt_t *s ) const { - slist_iterator_tpl <halthandle_t> iter( halt_list ); - while(iter.next()) { - halthandle_t halt = iter.get_current(); + //slist_iterator_tpl <halthandle_t> iter( halt_list ); + //while(iter.next()) { + for(sint16 i = halt_list.get_count() - 1; i >= 0; i --) + { + //halthandle_t halt = iter.get_current(); + halthandle_t halt = halt_list[i]; if( halt->get_pax_enabled() && (halt->get_station_type()&haltestelle_t::busstop)!=0 ) { koord h=halt->get_basis_pos(); if(h.x>=s->get_linksoben().x && h.y>=s->get_linksoben().y && h.x<=s->get_rechtsunten().x && h.y<=s->get_rechtsunten().y ) { DBG_MESSAGE("ai_passenger_t::get_our_hub()","found %s at (%i,%i)",s->get_name(),h.x,h.y); - return iter.get_current(); + //return iter.get_current(); + return halt_list[i]; } } } diff --git a/player/simplay.cc b/player/simplay.cc index c2dac6a5e2f..79e6b1d6b94 100644 --- a/player/simplay.cc +++ b/player/simplay.cc @@ -245,10 +245,13 @@ void spieler_t::step() { // die haltestellen müssen die Fahrpläne rgelmaessig pruefen uint8 i = (uint8)(welt->get_steps()+player_nr); - slist_iterator_tpl <halthandle_t> iter( halt_list ); - while(iter.next()) { + //slist_iterator_tpl <halthandle_t> iter( halt_list ); + //while(iter.next()) { + for(sint16 j = halt_list.get_count() - 1; j >= 0; j --) + { if( (i & 31) == 0 ) { - iter.get_current()->step(); + //iter.get_current()->step(); + halt_list[j]->step(); INT_CHECK("simplay 156"); } i++; @@ -497,8 +500,8 @@ halthandle_t spieler_t::halt_add(koord pos) void spieler_t::halt_add(halthandle_t halt) { - if (!halt_list.contains(halt)) { - halt_list.append(halt); + if (!halt_list.is_contained(halt)) { + halt_list.push_back(halt); haltcount ++; } } @@ -542,8 +545,11 @@ void spieler_t::ai_bankrupt() headquarter_pos = koord::invalid; // remove all stops - while(halt_list.count()>0) { - halthandle_t h = halt_list.remove_first(); + //while(halt_list.get_count() > 0) + for(sint16 i = halt_list.get_count() - 1; i >= 0; i --) + { + halthandle_t h = halt_list[0]; + halt_list.remove(h); haltestelle_t::destroy( h ); } @@ -777,7 +783,7 @@ DBG_DEBUG("spieler_t::rdwr()","player %i: loading %i halts.",welt->sp2num( this halthandle_t halt = haltestelle_t::create( welt, file ); // it was possible to have stops without ground: do not load them if(halt.is_bound()) { - halt_list.insert(halt); + halt_list.insert_at(halt_list.get_count(), halt); if(!halt->existiert_in_welt()) { dbg->warning("spieler_t::rdwr()","empty halt id %i qill be ignored", halt.get_id() ); } diff --git a/player/simplay.h b/player/simplay.h index 6ea0376ce7d..c211498f83f 100644 --- a/player/simplay.h +++ b/player/simplay.h @@ -111,7 +111,8 @@ class spieler_t */ sint32 konto_ueberzogen; - slist_tpl<halthandle_t> halt_list; ///< Liste der Haltestellen + //slist_tpl<halthandle_t> halt_list; ///< Liste der Haltestellen + vector_tpl<halthandle_t> halt_list; ///< "List of the stops" (Babelfish) class income_message_t { public: diff --git a/simworld.cc b/simworld.cc index 9f5de6da251..48cc1320b6d 100644 --- a/simworld.cc +++ b/simworld.cc @@ -3280,7 +3280,7 @@ DBG_MESSAGE("karte_t::speichern(loadsave_t *file)", "saved hgt"); file->rdwr_long(fabs, "\n"); //slist_iterator_tpl<fabrik_t*> fiter( fab_list ); //while(fiter.next()) { - for(uint16 i = fab_list.get_count() - 1; i >= 0; i --) + for(sint16 i = fab_list.get_count() - 1; i >= 0; i --) { //(fiter.get_current())->rdwr(file); fab_list[i]->rdwr(file); From 7c97d4efcffa685e07588152865a97798d10759e Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 14 Feb 2009 00:07:51 +0000 Subject: [PATCH 17/61] Updated project file to account for new addition of .cc file in simutrans-base --- Simutrans-Experimental.vcproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Simutrans-Experimental.vcproj b/Simutrans-Experimental.vcproj index 054d166a553..0442634616a 100644 --- a/Simutrans-Experimental.vcproj +++ b/Simutrans-Experimental.vcproj @@ -951,6 +951,10 @@ RelativePath=".\gui\stadt_info.cc" > </File> + <File + RelativePath=".\gui\station_building_select.cc" + > + </File> <File RelativePath=".\boden\wege\strasse.cc" > From 934cabf214d8ce40d659ec0b8f38a156df6bfb2b Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 14 Feb 2009 23:47:46 +0000 Subject: [PATCH 18/61] (1) Added new system of merging of goods to allow differentiation of origins; and (2) fixed a bug with the cornering algorithms that caused cross-contamination between cornering values of different vehicles at the same time. --- freight_list_sorter.cc | 2 +- simconvoi.cc | 45 ++++++++++++++++++++-------- simhalt.cc | 51 ++++++++++++++++++++++++------- simware.h | 18 +++++++++-- vehicle/simvehikel.cc | 68 ++++++++++++++++++++++++++++-------------- vehicle/simvehikel.h | 23 ++++++++++++++ 6 files changed, 158 insertions(+), 49 deletions(-) diff --git a/freight_list_sorter.cc b/freight_list_sorter.cc index c95e50922d9..0cd1292a5e4 100644 --- a/freight_list_sorter.cc +++ b/freight_list_sorter.cc @@ -171,7 +171,7 @@ void freight_list_sorter_t::sort_freight(const vector_tpl<ware_t>* warray, cbuff halthandle_t via_halt = tdlist[j].via_destination; halthandle_t origin_halt = tdlist[j].origin; - const char * name = "Error in Routing"; + const char * name = "unknown"; if(halt.is_bound()) { name = halt->get_name(); } diff --git a/simconvoi.cc b/simconvoi.cc index 4dd11629205..16723f4eef6 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -737,6 +737,7 @@ bool convoi_t::sync_step(long delta_t) /** * Berechne route von Start- zu Zielkoordinate + * "Compute route from starting to goal coordinate" (Babelfish) * @author Hanjsörg Malthaner */ int convoi_t::drive_to(koord3d start, koord3d ziel) @@ -757,6 +758,8 @@ int convoi_t::drive_to(koord3d start, koord3d ziel) /** * Ein Fahrzeug hat ein Problem erkannt und erzwingt die * Berechnung einer neuen Route + * + * "A vehicle recognized and forces a problem the computation of a new route" (Babelfish) * @author Hanjsörg Malthaner */ void convoi_t::suche_neue_route() @@ -1220,6 +1223,7 @@ void convoi_t::set_erstes_letztes() { // anz_vehikel muss korrekt init sein + // "anz vehicle must be correctly INIT" (Babelfish) if(anz_vehikel>0) { fahr[0]->set_erstes(true); for(unsigned i=1; i<anz_vehikel; i++) { @@ -1419,7 +1423,7 @@ convoi_t::can_go_alte_richtung() void -convoi_t::vorfahren() +convoi_t::vorfahren() //"move forward" (Babelfish) { // Hajo: init speed settings sp_soll = 0; @@ -1884,6 +1888,13 @@ convoi_t::rdwr(loadsave_t *file) file->rdwr_byte( tiles_overtaking, "o" ); set_tiles_overtaking( tiles_overtaking ); } + + // TODO: Add load/save parameters for: + // (1) origin; + // (2) last transfer; + // (3) origin departure time; and + // (4) last transfer departure time. + // Then, reversion the save game file format. } @@ -1962,16 +1973,25 @@ void convoi_t::get_freight_info(cbuffer_t & buf) slist_iterator_tpl<ware_t> iter_vehicle_ware(v->get_fracht()); while(iter_vehicle_ware.next()) { ware_t ware = iter_vehicle_ware.get_current(); - for(unsigned i=0; i<total_fracht.get_count(); i++ ) { - - //TODO: Reform the merging code to work with the new revenue system. + for(unsigned i = 0; i < total_fracht.get_count(); i++ ) { // could this be joined with existing freight? ware_t &tmp = total_fracht[i]; - // for pax: join according next stop - // for all others we *must* use target coordinates - if( ware.same_destination(tmp) ) { + /* OLD SYSTEM - no account taken of origins and timings. + * + * // for pax: join according next stop + * // for all others we *must* use target coordinates + * if( ware.same_destination(tmp) ) { + */ + + // New system: ensure that only sufficiently similar cargo + // packets are merged, to preserve, e.g., origins for revenue + // calculation. Does not require packets to be identical: + // some approximation of the timings is permitted, and intermediate + // stop data is merged without checking for equality. + if(ware.can_merge_with(tmp)) + { tmp.menge += ware.menge; ware.menge = 0; break; @@ -2125,7 +2145,7 @@ convoi_t::pruefe_vorgaenger(const vehikel_besch_t *vor, const vehikel_besch_t *h bool -convoi_t::pruefe_alle() +convoi_t::pruefe_alle() //"examine all" (Babelfish) { bool ok = (anz_vehikel == 0 || pruefe_vorgaenger(NULL, fahr[0]->get_besch())); unsigned i; @@ -2151,7 +2171,7 @@ convoi_t::pruefe_alle() * * V.Meyer: ladegrad is now stored in the object (not returned) */ -void convoi_t::laden() +void convoi_t::laden() //"load" (Babelfish) { if(state == FAHRPLANEINGABE) { return; @@ -2159,6 +2179,7 @@ void convoi_t::laden() halthandle_t halt = haltestelle_t::get_halt(welt, fpl->get_current_eintrag().pos); // eigene haltestelle ? + // "own stop?" (Babelfish) if (halt.is_bound()) { const koord k = fpl->get_current_eintrag().pos.get_2d(); const spieler_t* owner = halt->get_besitzer(); @@ -2232,12 +2253,12 @@ void convoi_t::calc_gewinn() * * V.Meyer: ladegrad is now stored in the object (not returned) */ -void convoi_t::hat_gehalten(koord k, halthandle_t halt) +void convoi_t::hat_gehalten(koord k, halthandle_t halt) //"has held" (Google) { sint64 gewinn = 0; - grund_t *gr=welt->lookup(fahr[0]->get_pos()); + grund_t *gr = welt->lookup(fahr[0]->get_pos()); - int station_lenght=0; + int station_lenght = 0; if(gr->ist_wasser()) { // habour has any size station_lenght = 24*16; diff --git a/simhalt.cc b/simhalt.cc index 72633cc370d..5b871fbddef 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -296,6 +296,13 @@ haltestelle_t::haltestelle_t(karte_t* wl, koord k, spieler_t* sp) if(welt->ist_in_kartengrenzen(k)) { welt->access(k)->set_halt(self); } + + // TODO: Add load/save parameters for: + // (1) origin; + // (2) last transfer; + // (3) origin departure time; and + // (4) last transfer departure time. + // Then, reversion the save game file format. } @@ -766,7 +773,7 @@ void haltestelle_t::reroute_goods() for(int j=warray->get_count()-1; j>=0; j-- ) { ware_t & ware = (*warray)[j]; - if(ware.menge==0) { + if(ware.menge == 0) { continue; } @@ -861,9 +868,10 @@ void haltestelle_t::hat_gehalten(const ware_besch_t *type, const schedule_t *fpl for(int i=0; i<fpl->get_count(); i++) { // Hajo: Haltestelle selbst wird nicht in Zielliste aufgenommen + //"Station itself is not in target list" (Google) halthandle_t halt = get_halt(welt, fpl->eintrag[i].pos); // not existing, or own, or not enabled => ignore - if(!halt.is_bound() || halt==self || !halt->is_enabled(type)) { + if(!halt.is_bound() || halt == self || !halt->is_enabled(type)) { continue; } @@ -1187,7 +1195,7 @@ void haltestelle_t::add_pax_unhappy(int n) -void haltestelle_t::liefere_an_fabrik(const ware_t& ware) +void haltestelle_t::liefere_an_fabrik(const ware_t& ware) //"deliver to the factory" (Google) { slist_iterator_tpl<fabrik_t *> fab_iter(fab_list); @@ -1245,8 +1253,8 @@ bool haltestelle_t::recall_ware( ware_t& w, uint32 menge ) -// will load something compatible with wtyp into the car which schedule is fpl -ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t *fpl) +// will load something compatible with wtyp into the car which schedule is fpl +ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t *fpl) //"hole from" (Google) { // prissi: first iterate over the next stop, then over the ware // might be a little slower, but ensures that passengers to nearest stop are served first @@ -1258,10 +1266,14 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t // da wir schon an der aktuellem haltestelle halten // startet die schleife ab 1, d.h. dem naechsten halt + + // because we have to keep the current haltestelle + // loop starts from 1, i.e. the next stop (Google) + for( uint8 i=1; i<count; i++ ) { const uint8 wrap_i = (i + fpl->get_aktuell()) % count; - const halthandle_t plan_halt = get_halt(welt, fpl->eintrag[wrap_i].pos); + const halthandle_t plan_halt = get_halt(welt, fpl->eintrag[wrap_i].pos); //eintrag = "entry" (Google) if(plan_halt == self) { // we will come later here again ... break; @@ -1284,7 +1296,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t } // compatible car and right target stop? - if( tmp.get_zwischenziel()==plan_halt ) { + if( tmp.get_zwischenziel() == plan_halt ) { // not too much? ware_t neu(tmp); @@ -1384,17 +1396,34 @@ uint32 haltestelle_t::sum_all_waiting_goods() const //15-Feb-2002 Markus -bool haltestelle_t::vereinige_waren(const ware_t &ware) +bool haltestelle_t::vereinige_waren(const ware_t &ware) //"unite were" (Google) { // pruefen ob die ware mit bereits wartender ware vereinigt werden kann + // "examine whether the ware with software already waiting to be united" (Google) + vector_tpl<ware_t> * warray = waren[ware.get_besch()->get_catg_index()]; if(warray!=NULL) { for(unsigned i=0; i<warray->get_count(); i++ ) { ware_t &tmp = (*warray)[i]; - // es wird auf basis von Haltestellen vereinigt - // prissi: das ist aber ein Fehler für alle anderen Güter, daher Zielkoordinaten für alles, was kein passagier ist ... - if(ware.same_destination(tmp)) { + /* + * OLD SYSTEM - did not take account of origins and timings when merging. + * + * // es wird auf basis von Haltestellen vereinigt + * // prissi: das ist aber ein Fehler für alle anderen Güter, daher Zielkoordinaten für alles, was kein passagier ist ... + * + * //it is based on uniting stops. + * //prissi: but that is a mistake for all other goods, therefore, target coordinates for everything that is not a passenger ... + * // (Google) + * + * if(ware.same_destination(tmp)) { + */ + + // NEW SYSTEM + // Checks adds a great deal more checks. + // @author: jamespetts + if(ware.can_merge_with(tmp)) + { tmp.menge += ware.menge; resort_freight_info = true; return true; diff --git a/simware.h b/simware.h index d4e4b435209..6cb31be247e 100644 --- a/simware.h +++ b/simware.h @@ -111,11 +111,22 @@ class ware_t bool is_freight() const { return index>2; } int operator==(const ware_t &w) { + return menge == w.menge && + zwischenziel == w.zwischenziel && + // No need to repeat the position checking if + // this will be done in can_merge_with. + (index < 3 || zielpos == w.zielpos) && + can_merge_with(w); + } + + // Lighter version of operator == that only checks equality + // of metrics needed for merging. + inline bool can_merge_with (const ware_t &w) const + { return index == w.index && - menge == w.menge && ziel == w.ziel && - zwischenziel == w.zwischenziel && - zielpos == w.zielpos && + // Only merge the destination *position* if the load is not freight + (index > 2 || zielpos == w.zielpos) && origin == w.origin && previous_transfer == w.previous_transfer && // Goods generated within 15 secs (at default speed) of each other @@ -126,6 +137,7 @@ class ware_t !(journey_leg_start_time < w.journey_leg_start_time - 15000); } + uint8 get_journey_steps() { return journey_steps; } void set_journey_steps(uint8 value) { journey_steps = value; } diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index d7ebe657490..3c74d0a8bc6 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -90,22 +90,7 @@ uint8 vehikel_basis_t::old_diagonal_length = 127; uint8 vehikel_basis_t::diagonal_length = 180; uint16 vehikel_basis_t::diagonal_multiplier = 724; -//@author: jamespetts -uint16 local_bonus_supplement = 0; -//A supplementary bonus for local transportation, -//if needed, to compensate for not having the effect -//of the long-distance speed bonus. - -//@author: jamespetts -// Cornering settings. - -fixed_list_tpl<bool, 16> curve_history; -fixed_list_tpl<sint16, 16> pre_corner_direction; - -sint16 direction_steps = 4; - -fixed_list_tpl<bool, 5> hill; -bool is_overweight = false; +uint16 local_bonus_supplement; // set only once, before loading! void vehikel_basis_t::set_diagonal_multiplier( uint32 multiplier, uint32 old_diagonal_multiplier ) @@ -791,9 +776,18 @@ bool vehikel_t::load_freight(halthandle_t halt) while(iter.next()) { ware_t &tmp = iter.access_current(); - // for pax: join according next stop - // for all others we *must* use target coordinates - if(ware.same_destination(tmp)) { + /* + * OLD SYSTEM - did not take account of origins, etc. + * + * // for pax: join according next stop + * // for all others we *must* use target coordinates + * if(ware.same_destination(tmp)) { + */ + + // New system: only merges if origins and timings are alike. + // @author: jamespetts + if(ware.can_merge_with(tmp)) + { tmp.menge += ware.menge; total_freight += ware.menge; ware.menge = 0; @@ -964,8 +958,16 @@ vehikel_t::vehikel_t(koord3d pos, const vehikel_besch_t* besch, spieler_t* sp) : ist_erstes = ist_letztes = false; check_for_finish = false; use_calc_height = true; - alte_fahrtrichtung = fahrtrichtung = ribi_t::keine; //I + alte_fahrtrichtung = fahrtrichtung = ribi_t::keine; target_halt = halthandle_t(); + + //@author: jamespetts +#ifdef debug_corners + current_corner = 0; +#endif + direction_steps = 4; + local_bonus_supplement = 0; + is_overweight = false; } @@ -985,7 +987,15 @@ vehikel_t::vehikel_t(karte_t *welt) : ist_erstes = ist_letztes = false; check_for_finish = false; use_calc_height = true; - alte_fahrtrichtung = fahrtrichtung = ribi_t::keine; //II + alte_fahrtrichtung = fahrtrichtung = ribi_t::keine; + + //@author: jamespetts +#ifdef debug_corners + current_corner = 0; +#endif + direction_steps = 4; + local_bonus_supplement = 0; + is_overweight = false; } @@ -1216,8 +1226,10 @@ vehikel_t::calc_modified_speed_limit(const koord3d *position, ribi_t::ribi curre static uint8 min_direction_steps = welt->get_einstellungen()->get_min_direction_steps(waytype); static uint8 max_direction_steps = welt->get_einstellungen()->get_max_direction_steps(waytype); +#ifndef debug_corners if(is_corner) { +#endif sint16 direction_difference = 0; sint16 direction = get_direction_degrees(ribi_t::get_dir(current_direction)); const koord3d *current_tile = position; @@ -1261,6 +1273,9 @@ vehikel_t::calc_modified_speed_limit(const koord3d *position, ribi_t::ribi curre } } +#ifdef debug_corners + current_corner = direction_difference; +#endif if(direction_difference == 0 && current_direction != old_direction) { //Fallback code in case the checking the histories did not work properly (for example, if the histories were cleared recently) @@ -1296,7 +1311,11 @@ vehikel_t::calc_modified_speed_limit(const koord3d *position, ribi_t::ribi curre //If we are here, there *must* be a curve, since we have already checked that. //If this is 0, this is an error, and we will assume a 45 degree bend. +#ifndef debug_corners corner_speed_limit = (base_limit * limit_adjustment_factor); +#else + corner_speed_limit = base_limit; +#endif break; case 45 : @@ -1323,8 +1342,9 @@ vehikel_t::calc_modified_speed_limit(const koord3d *position, ribi_t::ribi curre //There *must* be a curve here, as the original bool flag was triggered. corner_speed_limit = (base_limit * limit_adjustment_factor); } - +#ifndef debug_corners } +#endif //Overweight penalty not to be made cumulative to cornering penalty @@ -2034,6 +2054,10 @@ vehikel_t::display_after(int xpos, int ypos, bool is_gobal) const sprintf(tooltip_text, translator::translate("Vehicle %s is too heavy for this route: speed limited."), cnv->get_name()); color = COL_YELLOW; } +#ifdef debug_corners + sprintf(tooltip_text, translator::translate("CORNER: %i"), current_corner); + color = COL_GREEN; +#endif // something to show? diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index a7268182c1b..4073f4a9817 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -195,6 +195,29 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t */ bool load_freight(halthandle_t halt); + //@author: jamespetts + //uint16 local_bonus_supplement; + //A supplementary bonus for local transportation, + //if needed, to compensate for not having the effect + //of the long-distance speed bonus. + + //@author: jamespetts + // Cornering settings. + + fixed_list_tpl<bool, 16> curve_history; + fixed_list_tpl<sint16, 16> pre_corner_direction; + + sint16 direction_steps; + + fixed_list_tpl<bool, 5> hill; + bool is_overweight; + +//#define debug_corners + +#ifdef debug_corners + uint16 current_corner; +#endif + protected: virtual void hop(); From 4f42525fc6e61a34f09a0138e24ad97d72ef0b54 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 15 Feb 2009 16:21:19 +0000 Subject: [PATCH 19/61] Implemented Isidoro's vehicle replacement tool, adapted to work with way constraints. --- Makefile | 3 + Simutrans-Experimental.vcproj | 12 + gui/components/gui_label.h | 3 +- gui/convoi_detail_t.cc | 17 +- gui/convoi_detail_t.h | 3 +- gui/convoi_info_t.cc | 74 +-- gui/convoi_info_t.h | 3 +- gui/depot_frame.cc | 986 +++------------------------------- gui/depot_frame.h | 100 +--- simconvoi.cc | 184 ++++++- simconvoi.h | 46 ++ simdepot.cc | 58 ++ simdepot.h | 100 +--- simline.h | 4 +- 14 files changed, 451 insertions(+), 1142 deletions(-) diff --git a/Makefile b/Makefile index 0059f0bf631..bec8b21cfbb 100644 --- a/Makefile +++ b/Makefile @@ -204,6 +204,8 @@ SOURCES += gui/colors.cc SOURCES += gui/components/gui_button.cc SOURCES += gui/components/gui_chart.cc SOURCES += gui/components/gui_combobox.cc +SOURCES += gui/components/gui_convoy_assembler.cc +SOURCES += gui/components/gui_convoy_label.cc SOURCES += gui/components/gui_flowtext.cc SOURCES += gui/components/gui_image_list.cc SOURCES += gui/components/gui_label.cc @@ -261,6 +263,7 @@ SOURCES += gui/money_frame.cc SOURCES += gui/optionen.cc SOURCES += gui/pakselector.cc SOURCES += gui/player_frame_t.cc +SOURCES += gui/replace_frame.cc SOURCES += gui/savegame_frame.cc SOURCES += gui/scenario_frame.cc SOURCES += gui/schedule_list.cc diff --git a/Simutrans-Experimental.vcproj b/Simutrans-Experimental.vcproj index 0442634616a..b0ad229e829 100644 --- a/Simutrans-Experimental.vcproj +++ b/Simutrans-Experimental.vcproj @@ -451,6 +451,14 @@ RelativePath=".\gui\gui_convoiinfo.cc" > </File> + <File + RelativePath=".\gui\components\gui_convoy_assembler.cc" + > + </File> + <File + RelativePath=".\gui\components\gui_convoy_label.cc" + > + </File> <File RelativePath=".\gui\components\gui_flowtext.cc" > @@ -699,6 +707,10 @@ RelativePath=".\dataobj\powernet.cc" > </File> + <File + RelativePath=".\gui\replace_frame.cc" + > + </File> <File RelativePath=".\dataobj\ribi.cc" > diff --git a/gui/components/gui_label.h b/gui/components/gui_label.h index 6cc3b024f59..d59f23d5ec3 100644 --- a/gui/components/gui_label.h +++ b/gui/components/gui_label.h @@ -63,7 +63,7 @@ class gui_label_t : public gui_komponente_t * returns the pointer (i.e. for freeing untranslater contents) * @author Hansjörg Malthaner */ - const char * get_text_pointer() { return text; } + const char * get_text_pointer() const { return text; } /** * Zeichnet die Komponente @@ -83,6 +83,7 @@ class gui_label_t : public gui_komponente_t * @author Volker Meyer */ + align_t get_align() const {return align;} void set_align(align_t align) { this->align = align; } }; diff --git a/gui/convoi_detail_t.cc b/gui/convoi_detail_t.cc index ff60568df4b..a5bc9ece524 100644 --- a/gui/convoi_detail_t.cc +++ b/gui/convoi_detail_t.cc @@ -51,6 +51,13 @@ convoi_detail_t::convoi_detail_t(convoihandle_t cnv) withdraw_button.set_tooltip("Convoi is sold when all wagons are empty."); add_komponente(&withdraw_button); withdraw_button.add_listener(this); + retire_button.set_groesse(koord(BUTTON_WIDTH, BUTTON_HEIGHT)); + retire_button.set_pos(koord(BUTTON3_X,16+BUTTON_HEIGHT)); + retire_button.set_text("Retire"); + retire_button.set_typ(button_t::roundbox); + retire_button.set_tooltip("Convoi is sent to depot when all wagons are empty."); + add_komponente(&retire_button); + retire_button.add_listener(this); scrolly.set_pos(koord(0, 64)); add_komponente(&scrolly); @@ -80,12 +87,15 @@ convoi_detail_t::zeichnen(koord pos, koord gr) if(cnv->get_besitzer()==cnv->get_welt()->get_active_player()) { withdraw_button.enable(); sale_button.enable(); + retire_button.enable(); } else { - sale_button.disable(); withdraw_button.disable(); + sale_button.disable(); + retire_button.disable(); } withdraw_button.pressed = cnv->get_withdraw(); + retire_button.pressed = cnv->get_depot_when_empty(); // all gui stuff set => display it veh_info.set_groesse(koord(1,1)); @@ -127,6 +137,11 @@ convoi_detail_t::action_triggered(gui_action_creator_t *komp,value_t /* */) cnv->set_no_load(cnv->get_withdraw()); return true; } + else if(komp==&retire_button) { + cnv->set_depot_when_empty(!cnv->get_depot_when_empty()); + cnv->set_no_load(cnv->get_depot_when_empty()); + return true; + } } return false; } diff --git a/gui/convoi_detail_t.h b/gui/convoi_detail_t.h index eda1908dd5f..d5ddbdf0dfe 100644 --- a/gui/convoi_detail_t.h +++ b/gui/convoi_detail_t.h @@ -66,7 +66,8 @@ class convoi_detail_t : public gui_frame_t , private action_listener_t convoihandle_t cnv; button_t sale_button; - button_t withdraw_button; + button_t withdraw_button; + button_t retire_button; public: convoi_detail_t(convoihandle_t cnv); diff --git a/gui/convoi_info_t.cc b/gui/convoi_info_t.cc index 9fff1c203e1..8a25fa56f6e 100644 --- a/gui/convoi_info_t.cc +++ b/gui/convoi_info_t.cc @@ -8,6 +8,7 @@ #include <stdio.h> #include "convoi_info_t.h" +#include "replace_frame.h" #include "../simconvoi.h" #include "../simdepot.h" @@ -178,6 +179,14 @@ convoi_info_t::convoi_info_t(convoihandle_t cnv) add_komponente(&no_load_button); no_load_button.add_listener(this); + replace_button.set_groesse(koord(BUTTON_WIDTH, BUTTON_HEIGHT)); + replace_button.set_pos(koord(BUTTON3_X,76+BUTTON_HEIGHT+1)); + replace_button.set_text("Replace"); + replace_button.set_typ(button_t::box); + replace_button.set_tooltip("Automatically replace this convoy."); + add_komponente(&replace_button); + replace_button.add_listener(this); + follow_button.set_groesse(koord(66, BUTTON_HEIGHT)); follow_button.set_text("follow me"); follow_button.set_typ(button_t::roundbox_state); @@ -238,6 +247,9 @@ convoi_info_t::zeichnen(koord pos, koord gr) } no_load_button.pressed = cnv->get_no_load(); no_load_button.enable(); + replace_button.background= cnv->get_replace()?COL_LIGHT_RED:MN_GREY3; + replace_button.set_text(cnv->get_replace()?"Replacing":"Replace"); + replace_button.enable(); } else { if( line_bound ) { @@ -248,6 +260,7 @@ convoi_info_t::zeichnen(koord pos, koord gr) button.disable(); go_home_button.disable(); no_load_button.disable(); + replace_button.disable(); } follow_button.pressed = (cnv->get_welt()->get_follow_convoi()==cnv); @@ -366,60 +379,17 @@ bool convoi_info_t::action_triggered( gui_action_creator_t *komp,value_t /* */) return true; } - if(komp == &go_home_button && !route_search_in_progress) { - // limit update to certain states that are considered to be save for fahrplan updates - int state = cnv->get_state(); - if(state==convoi_t::FAHRPLANEINGABE) { -DBG_MESSAGE("convoi_info_t::action_triggered()","convoi state %i => cannot change schedule ... ", state ); + if(komp == &replace_button) { + if (cnv->get_replace()) { + cnv->set_replace(false); return true; } - route_search_in_progress = true; - - // iterate over all depots and try to find shortest route - slist_iterator_tpl<depot_t *> depot_iter(depot_t::get_depot_list()); - route_t * shortest_route = new route_t(); - route_t * route = new route_t(); - koord3d home = koord3d(0,0,0); - while (depot_iter.next()) { - depot_t *depot = depot_iter.get_current(); - if(depot->get_wegtyp()!=cnv->get_vehikel(0)->get_besch()->get_waytype() || depot->get_besitzer()!=cnv->get_besitzer()) { - continue; - } - koord3d pos = depot->get_pos(); - if(!shortest_route->empty() && abs_distance(pos.get_2d(),cnv->get_pos().get_2d())>=shortest_route->get_max_n()) { - // the current route is already shorter, no need to search further - continue; - } - bool found = cnv->get_vehikel(0)->calc_route(cnv->get_pos(), pos, 50, route); // do not care about speed - if (found) { - if( route->get_max_n() < shortest_route->get_max_n() || shortest_route->empty() ) { - shortest_route->kopiere(route); - home = pos; - } - } - } - delete route; - DBG_MESSAGE("shortest route has ", "%i hops", shortest_route->get_max_n()); - - // if route to a depot has been found, update the convoi's schedule - bool b_depot_found = false; - if(!shortest_route->empty()) { - schedule_t *fpl = cnv->get_schedule(); - fpl->insert(cnv->get_welt()->lookup(home)); - fpl->set_aktuell( (fpl->get_aktuell()+fpl->get_count()-1)%fpl->get_count() ); - b_depot_found = cnv->set_schedule(fpl); - } - delete shortest_route; - route_search_in_progress = false; - - // show result - const char* txt; - if (b_depot_found) { - txt = "Convoi has been sent\nto the nearest depot\nof appropriate type.\n"; - } else { - txt = "Home depot not found!\nYou need to send the\nconvoi to the depot\nmanually."; - } - create_win( new news_img(txt), w_time_delete, magic_none); + create_win(20, 20, new replace_frame_t(cnv, get_name()), w_info, (long)this); + return true; + } + if(komp == &go_home_button && !route_search_in_progress) { + cnv->go_to_depot(true); + return true; } // end go home button } diff --git a/gui/convoi_info_t.h b/gui/convoi_info_t.h index df8ccb252cc..49f258cd4af 100644 --- a/gui/convoi_info_t.h +++ b/gui/convoi_info_t.h @@ -46,6 +46,7 @@ class convoi_info_t : public gui_frame_t, private action_listener_t button_t follow_button; button_t go_home_button; button_t no_load_button; + button_t replace_button; button_t filterButtons[7]; button_t sort_button; @@ -68,10 +69,10 @@ class convoi_info_t : public gui_frame_t, private action_listener_t */ cbuffer_t freight_info; - static bool route_search_in_progress; static const char *sort_text[SORT_MODES]; public: + static bool route_search_in_progress; convoi_info_t(convoihandle_t cnv); /** diff --git a/gui/depot_frame.cc b/gui/depot_frame.cc index 8f38d82a099..d6d7f2250cc 100644 --- a/gui/depot_frame.cc +++ b/gui/depot_frame.cc @@ -43,45 +43,14 @@ char depot_frame_t::no_line_text[128]; // contains the current translation of "<no line>" -static const char * engine_type_names [9] = -{ - "unknown", - "steam", - "diesel", - "electric", - "bio", - "sail", - "fuel_cell", - "hydrogene", - "battery" -}; - - -bool depot_frame_t::show_retired_vehicles = false; - -bool depot_frame_t::show_all = true; - depot_frame_t::depot_frame_t(depot_t* depot) : gui_frame_t(txt_title, depot->get_besitzer()), depot(depot), icnv(depot->convoi_count()-1), lb_convois(NULL, COL_BLACK, gui_label_t::left), - lb_convoi_count(NULL, COL_BLACK, gui_label_t::left), - lb_convoi_speed(NULL, COL_BLACK, gui_label_t::left), lb_convoi_value(NULL, COL_BLACK, gui_label_t::right), - lb_convoi_line(NULL, COL_BLACK, gui_label_t::left), - lb_veh_action("Fahrzeuge:", COL_BLACK, gui_label_t::left), - convoi_pics(depot->get_max_convoi_length()), - convoi(&convoi_pics), - pas(&pas_vec), - electrics(&electrics_vec), - loks(&loks_vec), - waggons(&waggons_vec), - scrolly_electrics(&cont_electrics), - scrolly_pas(&cont_pas), - scrolly_loks(&cont_loks), - scrolly_waggons(&cont_waggons) + lb_convoi_line(NULL, COL_BLACK, gui_label_t::left) { DBG_DEBUG("depot_frame_t::depot_frame_t()","get_max_convoi_length()=%i",depot->get_max_convoi_length()); selected_line = depot->get_selected_line(); //linehandle_t(); @@ -90,8 +59,19 @@ DBG_DEBUG("depot_frame_t::depot_frame_t()","get_max_convoi_length()=%i",depot->g sprintf(txt_title, "(%d,%d) %s", depot->get_pos().x, depot->get_pos().y, translator::translate(depot->get_name())); /* - * [SELECT]: - */ + * [CONVOY ASSEMBLER] + */ + const waytype_t wt = depot->get_wegtyp(); + const weg_t *w = get_welt()->lookup(depot->get_pos())->get_weg(wt!=tram_wt ? wt : track_wt); + const bool weg_electrified = w ? w->is_electrified() : false; + convoy_assembler = new gui_convoy_assembler_t(get_welt(), wt, weg_electrified, depot->get_player_nr() ); + convoy_assembler->set_depot_frame(this); + convoy_assembler->add_listener(this); + update_convoy(); + + /* + * [SELECT]: + */ add_komponente(&lb_convois); bt_prev.set_typ(button_t::arrowleft); @@ -112,15 +92,6 @@ DBG_DEBUG("depot_frame_t::depot_frame_t()","get_max_convoi_length()=%i",depot->g add_komponente(&line_selector); depot->get_besitzer()->simlinemgmt.sort_lines(); - /* - * [CONVOI] - */ - convoi.set_player_nr(depot->get_player_nr()); - convoi.add_listener(this); - - add_komponente(&convoi); - add_komponente(&lb_convoi_count); - add_komponente(&lb_convoi_speed); add_komponente(&lb_convoi_value); add_komponente(&lb_convoi_line); @@ -170,93 +141,6 @@ DBG_DEBUG("depot_frame_t::depot_frame_t()","get_max_convoi_length()=%i",depot->g bt_copy_convoi.set_tooltip("Copy the selected convoi and its schedule or line"); add_komponente(&bt_copy_convoi); - /* - * [PANEL] - * to test for presence, we must fist switch on all vehicles, - * and switch off the timeline ... - * otherwise the tabs will not be present at all - */ - bool old_retired=show_retired_vehicles; - bool old_show_all=show_all; - show_retired_vehicles = true; - show_all = true; - einstellungen_t* e = get_welt()->get_einstellungen(); - char timeline = e->get_use_timeline(); - e->set_use_timeline(0); - build_vehicle_lists(); - e->set_use_timeline(timeline); - show_retired_vehicles = old_retired; - show_all = old_show_all; - - cont_pas.add_komponente(&pas); - scrolly_pas.set_show_scroll_x(false); - scrolly_pas.set_size_corner(false); - scrolly_pas.set_read_only(false); - - // always add - tabs.add_tab(&scrolly_pas, translator::translate( depot->get_passenger_name() ) ); - - cont_electrics.add_komponente(&electrics); - scrolly_electrics.set_show_scroll_x(false); - scrolly_electrics.set_size_corner(false); - scrolly_electrics.set_read_only(false); - // add only if there are any trolleybuses - if(!electrics_vec.empty()) { - tabs.add_tab(&scrolly_electrics, translator::translate( depot->get_electrics_name() ) ); - } - - cont_loks.add_komponente(&loks); - scrolly_loks.set_show_scroll_x(false); - scrolly_loks.set_size_corner(false); - scrolly_loks.set_read_only(false); - // add, if waggons are there ... - if (!loks_vec.empty() || !waggons_vec.empty()) { - tabs.add_tab(&scrolly_loks, translator::translate( depot->get_zieher_name() ) ); - } - - cont_waggons.add_komponente(&waggons); - scrolly_waggons.set_show_scroll_x(false); - scrolly_waggons.set_size_corner(false); - scrolly_waggons.set_read_only(false); - // only add, if there are waggons - if (!waggons_vec.empty()) { - tabs.add_tab(&scrolly_waggons, translator::translate( depot->get_haenger_name() ) ); - } - - pas.set_player_nr(depot->get_player_nr()); - pas.add_listener(this); - - electrics.set_player_nr(depot->get_player_nr()); - electrics.add_listener(this); - - loks.set_player_nr(depot->get_player_nr()); - loks.add_listener(this); - - waggons.set_player_nr(depot->get_player_nr()); - waggons.add_listener(this); - - add_komponente(&tabs); - add_komponente(&div_tabbottom); - add_komponente(&lb_veh_action); - - veh_action = va_append; - bt_veh_action.set_typ(button_t::roundbox); - bt_veh_action.add_listener(this); - bt_veh_action.set_tooltip("Choose operation executed on clicking stored/new vehicles"); - add_komponente(&bt_veh_action); - - bt_obsolete.set_typ(button_t::square); - bt_obsolete.set_text("Show obsolete"); - bt_obsolete.add_listener(this); - bt_obsolete.set_tooltip("Show also vehicles no longer in production."); - add_komponente(&bt_obsolete); - - bt_show_all.set_typ(button_t::square); - bt_show_all.set_text("Show all"); - bt_show_all.add_listener(this); - bt_show_all.set_tooltip("Show also vehicles that do not match for current action."); - add_komponente(&bt_show_all); - koord gr = koord(0,0); layout(&gr); update_data(); @@ -264,53 +148,37 @@ DBG_DEBUG("depot_frame_t::depot_frame_t()","get_max_convoi_length()=%i",depot->g // text will be translated by ourselves (after update data)! lb_convois.set_text_pointer(txt_convois); - lb_convoi_count.set_text_pointer(txt_convoi_count); - lb_convoi_speed.set_text_pointer(txt_convoi_speed); lb_convoi_value.set_text_pointer(txt_convoi_value); lb_convoi_line.set_text_pointer(txt_convoi_line); + add_komponente(convoy_assembler); + // Hajo: Trigger layouting set_resizemode(diagonal_resize); } - +depot_frame_t::~depot_frame_t() +{ + delete convoy_assembler; +} void depot_frame_t::layout(koord *gr) { - koord placement; - koord grid; - int grid_dx; - int placement_dx; - koord fgr = (gr!=NULL)? *gr : get_fenstergroesse(); - /* - * These parameter are adjusted to resolution. - * - Some extra space looks nicer. - */ - grid.x = depot->get_x_grid() * get_base_tile_raster_width() / 64 + 4; - grid.y = depot->get_y_grid() * get_base_tile_raster_width() / 64 + 6; - placement.x = depot->get_x_placement() * get_base_tile_raster_width() / 64 + 2; - placement.y = depot->get_y_placement() * get_base_tile_raster_width() / 64 + 2; - if(depot->get_wegtyp()==road_wt && umgebung_t::drive_on_left) { - // correct for dive on left - placement.x -= (12*get_base_tile_raster_width())/64; - placement.y -= (6*get_base_tile_raster_width())/64; - } - grid_dx = depot->get_x_grid() * get_base_tile_raster_width() / 64 / 2; - placement_dx = depot->get_x_grid() * get_base_tile_raster_width() / 64 / 4; - /* * Dialog format: * * Main structure are these parts from top to bottom: * * [SELECT] convoi-selector - * [CONVOI] current convoi + * [CONVOI] current convoi (*) * [ACTIONS] convoi action buttons - * [PANEL] vehicle panel - * [VINFO] vehicle infotext + * [PANEL] vehicle panel (*) + * [VINFO] vehicle infotext (*) + * + * (*) In CONVOI ASSEMBLER * * * Structure of [SELECT] is: @@ -322,19 +190,6 @@ void depot_frame_t::layout(koord *gr) */ int SELECT_HEIGHT = 14; - /* - * Structure of [CONVOI] is a image_list and an infos: - * - * [List] - * [Info] - * - * The image list is horizontally "condensed". - */ - int CINFO_HEIGHT = 14; - int CLIST_WIDTH = depot->get_max_convoi_length() * (grid.x - grid_dx) + 2 * gui_image_list_t::BORDER; - int CLIST_HEIGHT = grid.y + 2 * gui_image_list_t::BORDER; - int CONVOI_WIDTH = CLIST_WIDTH + placement_dx; - /* * Structure of [ACTIONS] is a row of buttons: * @@ -345,26 +200,20 @@ void depot_frame_t::layout(koord *gr) int ABUTTON_HEIGHT = 14; int ACTIONS_WIDTH = 4 * ABUTTON_WIDTH; int ACTIONS_HEIGHT = ABUTTON_HEIGHT + ABUTTON_HEIGHT; // @author hsiegeln: added "+ ABUTTON_HEIGHT" - - /* - * Structure of [VINFO] is one multiline text. - */ - int VINFO_HEIGHT = 185; + convoy_assembler->set_convoy_tabs_skip(ACTIONS_HEIGHT); /* * Total width is the max from [CONVOI] and [ACTIONS] width. */ - int MIN_TOTAL_WIDTH = max(CONVOI_WIDTH, ACTIONS_WIDTH); - int TOTAL_WIDTH = max(fgr.x,max(CONVOI_WIDTH, ACTIONS_WIDTH)); + int MIN_TOTAL_WIDTH = max(convoy_assembler->get_convoy_image_width(), ACTIONS_WIDTH); + int TOTAL_WIDTH = max(fgr.x,max(convoy_assembler->get_convoy_image_width(), ACTIONS_WIDTH)); /* * Now we can do the first vertical adjustement: */ int SELECT_VSTART = 16; - int CONVOI_VSTART = SELECT_VSTART + SELECT_HEIGHT + LINESPACE; - int CINFO_VSTART = CONVOI_VSTART + CLIST_HEIGHT; - int ACTIONS_VSTART = CINFO_VSTART + CINFO_HEIGHT + 2 + LINESPACE * 2; - int PANEL_VSTART = ACTIONS_VSTART + ACTIONS_HEIGHT + 8; + int ASSEMBLER_VSTART = SELECT_VSTART + SELECT_HEIGHT + LINESPACE; + int ACTIONS_VSTART = ASSEMBLER_VSTART + convoy_assembler->get_convoy_height(); /* * Now we determine the row/col layout for the panel and the total panel @@ -372,19 +221,13 @@ void depot_frame_t::layout(koord *gr) * build_vehicle_lists() fills loks_vec and waggon_vec. * Total width will be expanded to match completo columns in panel. */ - int total_h = PANEL_VSTART+VINFO_HEIGHT + 17 + gui_tab_panel_t::HEADER_VSIZE + 2 * gui_image_list_t::BORDER; - int PANEL_ROWS = max(1, ((fgr.y-total_h)/grid.y) ); - if(gr && gr->y==0) { - PANEL_ROWS = 3; - } - int PANEL_HEIGHT = PANEL_ROWS * grid.y + gui_tab_panel_t::HEADER_VSIZE + 2 * gui_image_list_t::BORDER; - int MIN_PANEL_HEIGHT = grid.y + gui_tab_panel_t::HEADER_VSIZE + 2 * gui_image_list_t::BORDER; + convoy_assembler->set_panel_rows(gr && gr->y==0?-1:fgr.y-ASSEMBLER_VSTART); /* * Now we can do the complete vertical adjustement: */ - int TOTAL_HEIGHT = PANEL_VSTART + PANEL_HEIGHT + VINFO_HEIGHT + 17; - int MIN_TOTAL_HEIGHT = PANEL_VSTART + MIN_PANEL_HEIGHT + VINFO_HEIGHT + 17; + int TOTAL_HEIGHT = ASSEMBLER_VSTART + convoy_assembler->get_height(); + int MIN_TOTAL_HEIGHT = ASSEMBLER_VSTART + convoy_assembler->get_min_height(); /* * DONE with layout planning - now build everything. @@ -424,15 +267,13 @@ void depot_frame_t::layout(koord *gr) /* * [CONVOI] */ - convoi.set_grid(koord(grid.x - grid_dx, grid.y)); - convoi.set_placement(koord(placement.x - placement_dx, placement.y)); - convoi.set_pos(koord((TOTAL_WIDTH-CLIST_WIDTH)/2, CONVOI_VSTART)); - convoi.set_groesse(koord(CLIST_WIDTH, CLIST_HEIGHT)); + convoy_assembler->set_pos(koord(0,ASSEMBLER_VSTART)); + convoy_assembler->set_groesse(koord(TOTAL_WIDTH,convoy_assembler->get_height())); + convoy_assembler->layout(); - lb_convoi_count.set_pos(koord(4, CINFO_VSTART)); - lb_convoi_speed.set_pos(koord(4, CINFO_VSTART + LINESPACE)); - lb_convoi_value.set_pos(koord(TOTAL_WIDTH-10, CINFO_VSTART)); - lb_convoi_line.set_pos(koord(4, CINFO_VSTART + LINESPACE * 2)); + lb_convoi_value.set_pos(koord(TOTAL_WIDTH-10, ASSEMBLER_VSTART + convoy_assembler->get_convoy_image_height())); + lb_convoi_line.set_pos(koord(4, ASSEMBLER_VSTART + convoy_assembler->get_convoy_image_height() + LINESPACE * 2)); + /* * [ACTIONS] @@ -472,61 +313,6 @@ void depot_frame_t::layout(koord *gr) bt_copy_convoi.set_pos(koord(TOTAL_WIDTH*3/4, ACTIONS_VSTART+ABUTTON_HEIGHT)); bt_copy_convoi.set_groesse(koord(TOTAL_WIDTH-TOTAL_WIDTH*3/4, ABUTTON_HEIGHT)); bt_copy_convoi.set_text("Copy Convoi"); - - /* - * [PANEL] - */ - tabs.set_pos(koord(0, PANEL_VSTART)); - tabs.set_groesse(koord(TOTAL_WIDTH, PANEL_HEIGHT)); - - pas.set_grid(grid); - pas.set_placement(placement); - pas.set_groesse(tabs.get_groesse()); - pas.recalc_size(); - pas.set_pos(koord(1,1)); - cont_pas.set_groesse(pas.get_groesse()); - scrolly_pas.set_groesse(scrolly_pas.get_groesse()); - - electrics.set_grid(grid); - electrics.set_placement(placement); - electrics.set_groesse(tabs.get_groesse()); - electrics.recalc_size(); - electrics.set_pos(koord(1,1)); - cont_electrics.set_groesse(electrics.get_groesse()); - scrolly_electrics.set_groesse(scrolly_electrics.get_groesse()); - - loks.set_grid(grid); - loks.set_placement(placement); - loks.set_groesse(tabs.get_groesse()); - loks.recalc_size(); - loks.set_pos(koord(1,1)); - cont_loks.set_pos(koord(0,0)); - cont_loks.set_groesse(loks.get_groesse()); - scrolly_loks.set_groesse(scrolly_loks.get_groesse()); - - waggons.set_grid(grid); - waggons.set_placement(placement); - waggons.set_groesse(tabs.get_groesse()); - waggons.recalc_size(); - waggons.set_pos(koord(1,1)); - cont_waggons.set_groesse(waggons.get_groesse()); - scrolly_waggons.set_groesse(scrolly_waggons.get_groesse()); - - div_tabbottom.set_pos(koord(0,PANEL_VSTART+PANEL_HEIGHT)); - div_tabbottom.set_groesse(koord(TOTAL_WIDTH,0)); - - lb_veh_action.set_pos(koord(TOTAL_WIDTH-ABUTTON_WIDTH, PANEL_VSTART + PANEL_HEIGHT+4)); - - bt_veh_action.set_pos(koord(TOTAL_WIDTH-ABUTTON_WIDTH, PANEL_VSTART + PANEL_HEIGHT + 14)); - bt_veh_action.set_groesse(koord(ABUTTON_WIDTH, ABUTTON_HEIGHT)); - - bt_show_all.set_pos(koord(TOTAL_WIDTH-(ABUTTON_WIDTH*5)/2, PANEL_VSTART + PANEL_HEIGHT + 4 )); - bt_show_all.set_groesse(koord(ABUTTON_WIDTH, ABUTTON_HEIGHT)); - bt_show_all.pressed = show_all; - - bt_obsolete.set_pos(koord(TOTAL_WIDTH-(ABUTTON_WIDTH*5)/2, PANEL_VSTART + PANEL_HEIGHT + 16)); - bt_obsolete.set_groesse(koord(ABUTTON_WIDTH, ABUTTON_HEIGHT)); - bt_obsolete.pressed = show_retired_vehicles; } @@ -540,146 +326,6 @@ void depot_frame_t::set_fenstergroesse( koord gr ) gui_frame_t::set_fenstergroesse(gr); } - -// true if already stored here -bool depot_frame_t::is_contained(const vehikel_besch_t *info) -{ - if(depot->vehicle_count()>0) { - slist_iterator_tpl<vehikel_t *> iter(depot->get_vehicle_list()); - while(iter.next()) { - if(iter.get_current()->get_besch()==info) { - return true; - } - } - } - return false; -} - - -// add a single vehicle (helper function) -void depot_frame_t::add_to_vehicle_list(const vehikel_besch_t *info) -{ - // prissi: ist a non-electric track? - // Hajo: check for timeline - // prissi: and retirement date - gui_image_list_t::image_data_t img_data; - - img_data.image = info->get_basis_bild(); - img_data.count = 0; - img_data.lcolor = img_data.rcolor = EMPTY_IMAGE_BAR; - img_data.text = info->get_name(); - - if( info->get_engine_type() == vehikel_besch_t::electric && (info->get_ware()==warenbauer_t::passagiere || info->get_ware()==warenbauer_t::post) ) { - electrics_vec.push_back(img_data); - vehicle_map.set(info, &electrics_vec.back()); - } - // since they come "pre-sorted" for the vehikelbauer, we have to do nothing to keep them sorted - else if(info->get_ware()==warenbauer_t::passagiere || info->get_ware()==warenbauer_t::post) { - pas_vec.push_back(img_data); - vehicle_map.set(info, &pas_vec.back()); - } - else if(info->get_leistung() > 0 || info->get_zuladung()==0) { - loks_vec.push_back(img_data); - vehicle_map.set(info, &loks_vec.back()); - } - else { - waggons_vec.push_back(img_data); - vehicle_map.set(info, &waggons_vec.back()); - } -} - - - -// add all current vehicles -void depot_frame_t::build_vehicle_lists() -{ - if(depot->get_vehicle_type()==NULL) { - // there are tracks etc. but now vehicles => do nothing - return; - } - - const int month_now = get_welt()->get_timeline_year_month(); - - if(electrics_vec.empty() && pas_vec.empty() && loks_vec.empty() && waggons_vec.empty()) { - int loks = 0, waggons = 0, pax=0, electrics = 0; - slist_iterator_tpl<const vehikel_besch_t*> vehinfo(depot->get_vehicle_type()); - while (vehinfo.next()) { - const vehikel_besch_t* info = vehinfo.get_current(); - if( info->get_engine_type() == vehikel_besch_t::electric && (info->get_ware()==warenbauer_t::passagiere || info->get_ware()==warenbauer_t::post)) { - electrics++; - } - else if(info->get_ware()==warenbauer_t::passagiere || info->get_ware()==warenbauer_t::post) { - pax++; - } - else if(info->get_leistung() > 0 || info->get_zuladung()==0) { - loks++; - } - else { - waggons++; - } - } - pas_vec.resize(pax); - electrics_vec.resize(electrics); - loks_vec.resize(loks); - waggons_vec.resize(waggons); - } - pas_vec.clear(); - electrics_vec.clear(); - loks_vec.clear(); - waggons_vec.clear(); - - vehicle_map.clear(); - - // we do not allow to built electric vehicle in a depot without electrification - const waytype_t wt = depot->get_wegtyp(); - const weg_t *w = get_welt()->lookup(depot->get_pos())->get_weg(wt!=tram_wt ? wt : track_wt); - const bool weg_electrified = w ? w->is_electrified() : false; - - // use this to show only sellable vehicles - if(!show_all && veh_action==va_sell) { - // just list the one to sell - slist_iterator_tpl<vehikel_t *> iter2(depot->get_vehicle_list()); - while(iter2.next()) { - if(vehicle_map.get(iter2.get_current()->get_besch())) { - continue; - } - add_to_vehicle_list( iter2.get_current()->get_besch() ); - } - } - else { - // list only matching ones - slist_iterator_tpl<const vehikel_besch_t*> vehinfo(depot->get_vehicle_type()); - while (vehinfo.next()) { - const vehikel_besch_t* info = vehinfo.get_current(); - const vehikel_besch_t *veh = NULL; - convoihandle_t cnv = depot->get_convoi(icnv); - if(cnv.is_bound() && cnv->get_vehikel_anzahl()>0) { - veh = (veh_action == va_insert) ? cnv->get_vehikel(0)->get_besch() : cnv->get_vehikel(cnv->get_vehikel_anzahl() - 1)->get_besch(); - } - - // current vehicle - if( is_contained(info) || - ((weg_electrified || info->get_engine_type()!=vehikel_besch_t::electric) && - ((!info->is_future(month_now)) && (show_retired_vehicles || (!info->is_retired(month_now)) ) ) )) { - // check, if allowed - bool append = true; - if(!show_all) { - if(veh_action == va_insert) { - append = !(!convoi_t::pruefe_nachfolger(info, veh) || (veh && !convoi_t::pruefe_vorgaenger(info, veh))); - } else if(veh_action == va_append) { - append = convoi_t::pruefe_vorgaenger(veh, info); //"Pruefe vorgaenger" = check predecessors (Google) - } - } - if(append) { - add_to_vehicle_list( info ); - } - } - } - } -DBG_DEBUG("depot_frame_t::build_vehicle_lists()","finally %i passenger vehicle, %i engines, %i good wagons",pas_vec.get_count(),loks_vec.get_count(),waggons_vec.get_count()); -} - - static void get_line_list(const depot_t* depot, vector_tpl<linehandle_t>* lines) { depot->get_besitzer()->simlinemgmt.get_lines(depot->get_line_type(), lines); @@ -688,13 +334,6 @@ static void get_line_list(const depot_t* depot, vector_tpl<linehandle_t>* lines) void depot_frame_t::update_data() { - static const char *txt_veh_action[3] = { "anhaengen", "voranstellen", "verkaufen" }; - - // change green into blue for retired vehicles - const int month_now = get_welt()->get_timeline_year_month(); - - bt_veh_action.set_text(txt_veh_action[veh_action]); - switch(depot->convoi_count()) { case 0: tstrncpy(txt_convois, translator::translate("no convois"), lengthof(txt_convois)); @@ -719,105 +358,9 @@ void depot_frame_t::update_data() * Reset counts and check for valid vehicles */ convoihandle_t cnv = depot->get_convoi(icnv); - const vehikel_besch_t *veh = NULL; - - convoi_pics.clear(); if(cnv.is_bound() && cnv->get_vehikel_anzahl() > 0) { - tstrncpy(txt_cnv_name, cnv->get_internal_name(), lengthof(txt_cnv_name)); inp_name.set_text(txt_cnv_name, lengthof(txt_cnv_name)); - - unsigned i; - for(i=0; i<cnv->get_vehikel_anzahl(); i++) { - - // just make sure, there is this vehicle also here! - const vehikel_besch_t *info=cnv->get_vehikel(i)->get_besch(); - if(vehicle_map.get(info)==NULL) { - add_to_vehicle_list( info ); - } - - gui_image_list_t::image_data_t img_data; - img_data.image = cnv->get_vehikel(i)->get_besch()->get_basis_bild(); - img_data.count = 0; - img_data.lcolor = img_data.rcolor= EMPTY_IMAGE_BAR; - img_data.text = cnv->get_vehikel(i)->get_besch()->get_name(); - convoi_pics.push_back(img_data); - } - - /* color bars for current convoi: */ - convoi_pics[0].lcolor = convoi_t::pruefe_vorgaenger(NULL, cnv->get_vehikel(0)->get_besch()) ? COL_GREEN : COL_YELLOW; - for( i=1; i<cnv->get_vehikel_anzahl(); i++) { - convoi_pics[i - 1].rcolor = convoi_t::pruefe_nachfolger(cnv->get_vehikel(i - 1)->get_besch(), cnv->get_vehikel(i)->get_besch()) ? COL_GREEN : COL_RED; - convoi_pics[i].lcolor = convoi_t::pruefe_vorgaenger(cnv->get_vehikel(i - 1)->get_besch(), cnv->get_vehikel(i)->get_besch()) ? COL_GREEN : COL_RED; - } - convoi_pics[i - 1].rcolor = convoi_t::pruefe_nachfolger(cnv->get_vehikel(i - 1)->get_besch(), NULL) ? COL_GREEN : COL_YELLOW; - - // change grren into blue for retired vehicles - for(i=0; i<cnv->get_vehikel_anzahl(); i++) { - if(cnv->get_vehikel(i)->get_besch()->is_future(month_now) || cnv->get_vehikel(i)->get_besch()->is_retired(month_now)) { - if (convoi_pics[i].lcolor == COL_GREEN) { - convoi_pics[i].lcolor = COL_BLUE; - } - if (convoi_pics[i].rcolor == COL_GREEN) { - convoi_pics[i].rcolor = COL_BLUE; - } - } - } - - if(veh_action == va_insert) { - veh = cnv->get_vehikel(0)->get_besch(); - } else if(veh_action == va_append) { - veh = cnv->get_vehikel(cnv->get_vehikel_anzahl() - 1)->get_besch(); - } - } - - ptrhashtable_iterator_tpl<const vehikel_besch_t *, gui_image_list_t::image_data_t *> iter1(vehicle_map); - while(iter1.next()) { - const vehikel_besch_t *info = iter1.get_current_key(); - const uint8 ok_color = info->is_future(month_now) || info->is_retired(month_now) ? COL_BLUE: COL_GREEN; - - iter1.get_current_value()->count = 0; - iter1.get_current_value()->lcolor = ok_color; - iter1.get_current_value()->rcolor = ok_color; - - /* - * color bars for current convoi: - * green/green okay to append/insert - * red/red cannot be appended/inserted - * green/yellow append okay, cannot be end of train - * yellow/green insert okay, cannot be start of train - */ - - if(veh_action == va_insert) { - if (!convoi_t::pruefe_nachfolger(info, veh) || (veh && !convoi_t::pruefe_vorgaenger(info, veh))) { - iter1.get_current_value()->lcolor = COL_RED; - iter1.get_current_value()->rcolor = COL_RED; - } else if(!convoi_t::pruefe_vorgaenger(NULL, info)) { - iter1.get_current_value()->lcolor = COL_YELLOW; - } - } else if(veh_action == va_append) { - if(!convoi_t::pruefe_vorgaenger(veh, info) || (veh && !convoi_t::pruefe_nachfolger(veh, info))) { - iter1.get_current_value()->lcolor = COL_RED; - iter1.get_current_value()->rcolor = COL_RED; - } else if(!convoi_t::pruefe_nachfolger(info, NULL)) { - iter1.get_current_value()->rcolor = COL_YELLOW; - } - } - -//DBG_DEBUG("depot_frame_t::update_data()","current %i = %s with color %i",info->get_name(),iter1.get_current_value()->lcolor); - } - - slist_iterator_tpl<vehikel_t *> iter2(depot->get_vehicle_list()); - while(iter2.next()) { - gui_image_list_t::image_data_t *imgdat=vehicle_map.get(iter2.get_current()->get_besch()); - // can fail, if currently not visible - if(imgdat) { - imgdat->count++; - if(veh_action == va_sell) { - imgdat->lcolor = COL_GREEN; - imgdat->rcolor = COL_GREEN; - } - } } // update the line selector @@ -837,158 +380,10 @@ void depot_frame_t::update_data() line_selector.set_selection( line_selector.count_elements()-1 ); } } + convoy_assembler->update_data(); } -sint32 depot_frame_t::calc_restwert(const vehikel_besch_t *veh_type) -{ - sint32 wert = 0; - - slist_iterator_tpl<vehikel_t *> iter(depot->get_vehicle_list()); - while(iter.next()) { - if(iter.get_current()->get_besch() == veh_type) { - wert += iter.get_current()->calc_restwert(); - } - } - return wert; -} - - -// returns the indest of the old/newest vehicle in a list -vehikel_t* depot_frame_t::find_oldest_newest(const vehikel_besch_t* besch, bool old) -{ - vehikel_t* found_veh = NULL; - slist_iterator_tpl<vehikel_t*> iter(depot->get_vehicle_list()); - while (iter.next()) { - vehikel_t* veh = iter.get_current(); - if (veh->get_besch() == besch) { - // joy of XOR, finally a line where I could use it! - if (found_veh == NULL || - old ^ (found_veh->get_insta_zeit() > veh->get_insta_zeit())) { - found_veh = veh; - } - } - } - return found_veh; -} - - - -void depot_frame_t::image_from_storage_list(gui_image_list_t::image_data_t *bild_data) -{ - if(bild_data->lcolor != COL_RED && bild_data->rcolor != COL_RED) { - // we buy/sell all vehicles together! - slist_tpl<const vehikel_besch_t *>new_vehicle_info; - const vehikel_besch_t *info = vehikelbauer_t::get_info(bild_data->text); - const vehikel_besch_t *start_info = info; - - if(veh_action==va_insert || veh_action==va_sell) { - // start of composition - while (info->get_vorgaenger_count() == 1 && info->get_vorgaenger(0) != NULL) { - info = info->get_vorgaenger(0); - new_vehicle_info.insert(info); - } - info = start_info; - } - // not get the end ... - while(info) { - new_vehicle_info.append( info ); -DBG_MESSAGE("depot_frame_t::image_from_storage_list()","appended %s",info->get_name() ); - if(info->get_nachfolger_count()!=1 || (veh_action==va_insert && info==start_info)) { - break; - } - info = info->get_nachfolger(0); - } - - if(veh_action == va_sell) { - while(new_vehicle_info.count()) { - /* - * We sell the newest vehicle - gives most money back. - */ - vehikel_t* veh = find_oldest_newest(new_vehicle_info.remove_first(), false); - if (veh != NULL) { - depot->sell_vehicle(veh); - } - } - } - else { - - // append/insert into convoi - convoihandle_t cnv = depot->get_convoi(icnv); - if(!cnv.is_bound()) { - // create a new convoi - cnv = depot->add_convoi(); - icnv = depot->convoi_count() - 1; - cnv->set_name(new_vehicle_info.front()->get_name()); - } - - if(cnv->get_vehikel_anzahl()+new_vehicle_info.count() <= depot->get_max_convoi_length()) { - - for( unsigned i=0; i<new_vehicle_info.count(); i++ ) { - // insert/append needs reverse order - unsigned nr = (veh_action == va_insert) ? new_vehicle_info.count()-i-1 : i; - // We add the oldest vehicle - newer stay for selling - const vehikel_besch_t* vb = new_vehicle_info.at(nr); - vehikel_t* veh = find_oldest_newest(vb, true); -DBG_MESSAGE("depot_frame_t::image_from_storage_list()","built nr %i", nr); - if (veh == NULL) { - // nothing there => we buy it - veh = depot->buy_vehicle(vb); - } - depot->append_vehicle(cnv, veh, veh_action == va_insert); - } - } - } - - build_vehicle_lists(); - update_data(); - layout(NULL); - } -} - - - -void depot_frame_t::image_from_convoi_list(uint nr) -{ - const convoihandle_t cnv = depot->get_convoi(icnv); - -//DBG_DEBUG("depot_frame_t::bild_gewaehlt()","convoi index %i",nr); - if(cnv.is_bound() && nr<cnv->get_vehikel_anzahl() ) { - - // we remove all connected vehicles together! - // find start - unsigned start_nr = nr; - while(start_nr>0) { - start_nr --; - const vehikel_besch_t *info = cnv->get_vehikel(start_nr)->get_besch(); - if(info->get_nachfolger_count()!=1) { - start_nr ++; - break; - } - } - // find end - while(nr<cnv->get_vehikel_anzahl()) { - const vehikel_besch_t *info = cnv->get_vehikel(nr)->get_besch(); - nr ++; - if(info->get_nachfolger_count()!=1) { - break; - } - } - // now remove the vehicles - if(cnv->get_vehikel_anzahl()==nr-start_nr) { - depot->disassemble_convoi(cnv, false); - icnv--; - } - else { - for( unsigned i=start_nr; i<nr; i++ ) { - depot->remove_vehicle(cnv, start_nr); - } - } - } -} - - - bool depot_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) { convoihandle_t cnv = depot->get_convoi(icnv); @@ -997,9 +392,46 @@ bool depot_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) } if(komp != NULL) { // message from outside! - if(komp == &bt_start) { + if(komp == convoy_assembler) { + const koord k=*static_cast<const koord *>(p.p); + switch (k.x) { + case gui_convoy_assembler_t::clear_convoy_action: + if (cnv.is_bound()) { + depot->disassemble_convoi(cnv, false); + icnv--; + update_convoy(); + } + break; + case gui_convoy_assembler_t::remove_vehicle_action: + if (cnv.is_bound()) { + depot->remove_vehicle(cnv, k.y); + } + break; + default: // append/insert_in_front + if(!cnv.is_bound()) { + // create a new convoi + cnv = depot->add_convoi(); + icnv = depot->convoi_count() - 1; + cnv->set_name((*convoy_assembler->get_vehicles())[0]->get_name()); + } + const vehikel_besch_t* vb; + if (k.x==gui_convoy_assembler_t::insert_vehicle_in_front_action) { + vb=(*convoy_assembler->get_vehicles())[0]; + } else { + vb=(*convoy_assembler->get_vehicles())[convoy_assembler->get_vehicles()->get_count()-1]; + } + vehikel_t* veh = depot->find_oldest_newest(vb, true); + if (veh == NULL) { + // nothing there => we buy it + veh = depot->buy_vehicle(vb); + } + depot->append_vehicle(cnv, veh, k.x == gui_convoy_assembler_t::insert_vehicle_in_front_action); + break; + } + } else if(komp == &bt_start) { if (depot->start_convoi(cnv)) { icnv--; + update_convoy(); } } else if(komp == &bt_schedule) { fahrplaneingabe(); @@ -1007,41 +439,23 @@ bool depot_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) } else if(komp == &bt_destroy) { if (depot->disassemble_convoi(cnv, false)) { icnv--; + update_convoy(); } } else if(komp == &bt_sell) { if (depot->disassemble_convoi(cnv, true)) { icnv--; + update_convoy(); } } else if(komp == &bt_next) { if(++icnv == (int)depot->convoi_count()) { icnv = -1; } + update_convoy(); } else if(komp == &bt_prev) { if(icnv-- == -1) { icnv = depot->convoi_count() - 1; } - // image lsit selction here ... - } else if(komp == &convoi) { - image_from_convoi_list( p.i ); - } else if(komp == &pas) { - image_from_storage_list(&pas_vec[p.i]); - } else if (komp == &electrics) { - image_from_storage_list(&electrics_vec[p.i]); - } else if(komp == &loks) { - image_from_storage_list(&loks_vec[p.i]); - } else if(komp == &waggons) { - image_from_storage_list(&waggons_vec[p.i]); - } else if(komp == &bt_obsolete) { - show_retired_vehicles = (show_retired_vehicles==0); - } else if(komp == &bt_show_all) { - show_all = (show_all==0); - } else if(komp == &bt_veh_action) { - if(veh_action== va_sell) { - veh_action = va_append; - } - else { - veh_action = veh_action+1; - } + update_convoy(); } else if(komp == &bt_new_line) { new_line(); return true; @@ -1052,6 +466,7 @@ bool depot_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) depot->copy_convoi(cnv); // automatically select newly created convoi icnv = depot->convoi_count()-1; + update_convoy(); } else if(komp == &bt_apply_line) { apply_line(); } else if(komp == &line_selector) { @@ -1072,7 +487,7 @@ bool depot_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) else { return false; } - build_vehicle_lists(); + convoy_assembler->build_vehicle_lists(); } update_data(); layout(NULL); @@ -1116,7 +531,7 @@ void depot_frame_t::infowin_event(const event_t *ev) koord gr = get_fenstergroesse(); set_fenstergroesse(gr); } else if(ev->ev_class == INFOWIN && ev->ev_code == WIN_OPEN) { - build_vehicle_lists(); + convoy_assembler->build_vehicle_lists(); update_data(); layout(NULL); } @@ -1141,39 +556,6 @@ depot_frame_t::zeichnen(koord pos, koord groesse) const convoihandle_t cnv = depot->get_convoi(icnv); if(cnv.is_bound()) { if(cnv->get_vehikel_anzahl() > 0) { - int length=0; - uint32 total_power=0; - uint32 total_max_weight=0; - uint32 total_min_weight=0; - uint16 max_speed=0; - uint16 min_speed=0; - for( unsigned i=0; i<cnv->get_vehikel_anzahl(); i++) { - const vehikel_besch_t *besch = cnv->get_vehikel(i)->get_besch(); - - length += besch->get_length(); - total_power += besch->get_leistung()*besch->get_gear()/64; - total_min_weight += besch->get_gewicht(); - total_max_weight += besch->get_gewicht(); - - uint32 max_weight =0; - uint32 min_weight =100000; - for(uint32 j=0; j<warenbauer_t::get_waren_anzahl(); j++) { - const ware_besch_t *ware = warenbauer_t::get_info(j); - - if(besch->get_ware()->get_catg_index()==ware->get_catg_index()) { - max_weight = max(max_weight, ware->get_weight_per_unit()); - min_weight = min(min_weight, ware->get_weight_per_unit()); - } - } - total_max_weight += max_weight*besch->get_zuladung()/1000; - total_min_weight += min_weight*besch->get_zuladung()/1000; - } - max_speed = min(speed_to_kmh(cnv->get_min_top_speed()), (uint32) sqrt((((double)total_power/total_min_weight)-1)*2500)); - min_speed = min(speed_to_kmh(cnv->get_min_top_speed()), (uint32) sqrt((((double)total_power/total_max_weight)-1)*2500)); - sprintf(txt_convoi_count, "%s %d (%s %i)", - translator::translate("Fahrzeuge:"), cnv->get_vehikel_anzahl(), - translator::translate("Station tiles:"), (length+TILE_STEPS-1)/TILE_STEPS ); - sprintf(txt_convoi_speed, "%s %d(%d)km/h", translator::translate("Max. speed:"), min_speed, max_speed ); sprintf(txt_convoi_value, "%s %d$", translator::translate("Restwert:"), cnv->calc_restwert()/100); // just recheck if schedules match if( cnv->get_line().is_bound() && cnv->get_line()->get_schedule()->ist_abgeschlossen() ) { @@ -1191,28 +573,21 @@ depot_frame_t::zeichnen(koord pos, koord groesse) } } else { - tstrncpy(txt_convoi_count, "keine Fahrzeuge", lengthof(txt_convoi_count)); *txt_convoi_value = '\0'; } } else { static char empty[2] = "\0"; inp_name.set_text( empty, 0); - *txt_convoi_count = '\0'; - *txt_convoi_speed = '\0'; *txt_convoi_value = '\0'; *txt_convoi_line = '\0'; } - bt_obsolete.pressed = show_retired_vehicles; // otherwise the button would not show depressed - bt_show_all.pressed = show_all; // otherwise the button would not show depressed - gui_frame_t::zeichnen(pos, groesse); if(!cnv.is_bound()) { display_proportional_clip(pos.x+inp_name.get_pos().x+2, pos.y+inp_name.get_pos().y+18, translator::translate("new convoi"), ALIGN_LEFT, COL_GREY1, true); } - draw_vehicle_info_text(pos); } @@ -1288,194 +663,3 @@ void depot_frame_t::fahrplaneingabe() create_win( new news_img("Please choose vehicles first\n"), w_time_delete, magic_none); } } - - -void depot_frame_t::draw_vehicle_info_text(koord pos) -{ - char buf[1024]; - const char *c; - - gui_image_list_t *lst; - if( tabs.get_aktives_tab()==&scrolly_pas ) { - lst = dynamic_cast<gui_image_list_t *>(&pas); - } - else if( tabs.get_aktives_tab()==&scrolly_electrics ) { - lst = dynamic_cast<gui_image_list_t *>(&electrics); - } - else if( tabs.get_aktives_tab()==&scrolly_loks ) { - lst = dynamic_cast<gui_image_list_t *>(&loks); - } - else { - lst = dynamic_cast<gui_image_list_t *>(&waggons); - } - int x = get_maus_x(); - int y = get_maus_y(); - int value = -1; - const vehikel_besch_t *veh_type = NULL; - koord relpos = koord( 0, ((gui_scrollpane_t *)tabs.get_aktives_tab())->get_scroll_y() ); - int sel_index = lst->index_at(pos + tabs.get_pos() - relpos, x, y - 16 - gui_tab_panel_t::HEADER_VSIZE); - - if ((sel_index != -1) && (tabs.getroffen(x-pos.x,y-pos.y))) { - const vector_tpl<gui_image_list_t::image_data_t>& vec = (lst == &electrics ? electrics_vec : (lst == &pas ? pas_vec : (lst == &loks ? loks_vec : waggons_vec))); - veh_type = vehikelbauer_t::get_info(vec[sel_index].text); - if (vec[sel_index].count > 0) { - value = calc_restwert(veh_type) / 100; - } - } - else { - sel_index = convoi.index_at(pos , x, y - 16); - if(sel_index != -1) { - convoihandle_t cnv = depot->get_convoi(icnv); - veh_type = cnv->get_vehikel(sel_index)->get_besch(); - value = cnv->get_vehikel(sel_index)->calc_restwert()/100; - } - } - - switch(depot->vehicle_count()) { - case 0: - c = translator::translate("Keine Einzelfahrzeuge im Depot"); - break; - case 1: - c = translator::translate("1 Einzelfahrzeug im Depot"); - break; - default: - sprintf(buf, translator::translate("%d Einzelfahrzeuge im Depot"), depot->vehicle_count()); - c = buf; - break; - } - display_proportional( pos.x + 4, pos.y + tabs.get_pos().y + tabs.get_groesse().y + 16 + 4, c, ALIGN_LEFT, COL_BLACK, true ); - - if(veh_type) { - int k = 0; - // lok oder waggon ? - if(veh_type->get_leistung() > 0) { //"Leistung" = performance (Google) - //lok - const int zuladung = veh_type->get_zuladung(); //"Zuladung" = payload (Google) - - char name[128]; - - sprintf(name, - "%s (%s)", - translator::translate(veh_type->get_name()), - translator::translate(engine_type_names[veh_type->get_engine_type()+1])); - - int n = sprintf(buf, - translator::translate("LOCO_INFO"), - name, - veh_type->get_preis()/100, - veh_type->get_betriebskosten(get_welt())/100.0, - veh_type->get_leistung(), - veh_type->get_geschw(), - veh_type->get_gewicht() - ); - - //"Payload" (Google) - if(zuladung>0) { - n += sprintf(buf + n, - translator::translate("LOCO_CAP"), - zuladung, - translator::translate(veh_type->get_ware()->get_mass()), - veh_type->get_ware()->get_catg() == 0 ? translator::translate(veh_type->get_ware()->get_name()) : translator::translate(veh_type->get_ware()->get_catg_name()) - ); - k = n; - } - - } - else { - // waggon - int n = sprintf(buf, - translator::translate("WAGGON_INFO"), - translator::translate(veh_type->get_name()), - veh_type->get_preis()/100, - veh_type->get_betriebskosten(get_welt())/100.0, - veh_type->get_zuladung(), - translator::translate(veh_type->get_ware()->get_mass()), - veh_type->get_ware()->get_catg() == 0 ? - translator::translate(veh_type->get_ware()->get_name()) : - translator::translate(veh_type->get_ware()->get_catg_name()), - veh_type->get_gewicht(), - veh_type->get_geschw() - ); - - k = n; - } - - if(veh_type->get_catering_level() > 0) - { - if(veh_type->get_ware()->get_catg_index() == 1) - { - //Catering vehicles that carry mail are treated as TPOs. - k += sprintf(buf + k, translator::translate("This is a travelling post office")); - } - else - { - k += sprintf(buf + k, translator::translate("Catering level: %i"), veh_type->get_catering_level()); - } - } - - // Permissive way constraints - // (If vehicle has, way must have) - // @author: jamespetts - for(uint8 i = 0; i < 8; i++) - { - if(veh_type->permissive_way_constraint_set(i)) - { - k += sprintf(buf + k, translator::translate("\nMUST USE: ")); - char tmpbuf[30]; - sprintf(tmpbuf, "Permissive %i", i); - k += sprintf(buf + k, translator::translate(tmpbuf)); - } - } - - display_multiline_text( pos.x + 4, pos.y + tabs.get_pos().y + tabs.get_groesse().y + 31 + LINESPACE*1 + 4, buf, COL_BLACK); - - // column 2 - - int j = sprintf(buf, "%s %s %04d\n", - translator::translate("Intro. date:"), - translator::get_month_name(veh_type->get_intro_year_month()%12), - veh_type->get_intro_year_month()/12 ); - - if(veh_type->get_retire_year_month() !=DEFAULT_RETIRE_DATE*12) { - j += sprintf(buf + j, "%s %s %04d\n", - translator::translate("Retire. date:"), - translator::get_month_name(veh_type->get_retire_year_month()%12), - veh_type->get_retire_year_month()/12 ); - } - - if(veh_type->get_leistung() > 0 && veh_type->get_gear()!=64) { - j+= sprintf(buf + j, "%s %0.2f : 1\n", translator::translate("Gear: "), veh_type->get_gear()/64.0); - } - - if(veh_type->get_copyright()!=NULL && veh_type->get_copyright()[0]!=0) - { - j += sprintf(buf + j, translator::translate("Constructed by %s\n"), veh_type->get_copyright()); - } - if(veh_type->get_tilting()) - { - j += sprintf(buf + j, translator::translate("This is a tilting vehicle\n")); - } - - if(value != -1) - { - sprintf(buf + strlen(buf), "%s %d Cr", translator::translate("Restwert: "), value); //"Restwert" = residual (Google) - } - - // Prohibitibve way constraints - // (If way has, vehicle must have) - // @author: jamespetts - j += sprintf(buf + j, "\n"); - for(uint8 i = 0; i < 8; i++) - { - if(veh_type->prohibitive_way_constraint_set(i)) - { - j += sprintf(buf + j, translator::translate("\nMAY USE: ")); - char tmpbuf[30]; - sprintf(tmpbuf, "Prohibitive %i", i); - j += sprintf(buf + j, translator::translate(tmpbuf)); - } - } - - display_multiline_text( pos.x + 200, pos.y + tabs.get_pos().y + tabs.get_groesse().y + 31 + LINESPACE*2 + 4, buf, COL_BLACK); - } -} diff --git a/gui/depot_frame.h b/gui/depot_frame.h index c261d90492c..ade8de38feb 100644 --- a/gui/depot_frame.h +++ b/gui/depot_frame.h @@ -20,7 +20,9 @@ #include "components/gui_button.h" #include "components/action_listener.h" #include "components/gui_scrollpane.h" +#include "components/gui_convoy_assembler.h" #include "../simtypes.h" +#include "../simdepot.h" class depot_t; class vehikel_besch_t; @@ -47,16 +49,6 @@ class depot_frame_t : public gui_frame_t, */ int icnv; - /* show retired vehicles (same for all depot) - * @author prissi - */ - static bool show_retired_vehicles; - - /* show retired vehicles (same for all depot) - * @author prissi - */ - static bool show_all; - /** * Gui elements * @author Volker Meyer @@ -67,8 +59,6 @@ class depot_frame_t : public gui_frame_t, gui_label_t lb_convois; button_t bt_next; - gui_label_t lb_convoi_count; - gui_label_t lb_convoi_speed; gui_label_t lb_convoi_value; gui_label_t lb_convoi_line; @@ -77,15 +67,6 @@ class depot_frame_t : public gui_frame_t, button_t bt_destroy; button_t bt_sell; - button_t bt_obsolete; - button_t bt_show_all; - - gui_tab_panel_t tabs; - gui_divider_t div_tabbottom; - - gui_label_t lb_veh_action; - button_t bt_veh_action; - /** * buttons for new route-management * @author hsiegeln @@ -95,30 +76,12 @@ class depot_frame_t : public gui_frame_t, button_t bt_copy_convoi; button_t bt_apply_line; - vector_tpl<gui_image_list_t::image_data_t> convoi_pics; - gui_image_list_t convoi; - - vector_tpl<gui_image_list_t::image_data_t> pas_vec; - vector_tpl<gui_image_list_t::image_data_t> electrics_vec; - vector_tpl<gui_image_list_t::image_data_t> loks_vec; - vector_tpl<gui_image_list_t::image_data_t> waggons_vec; - - gui_image_list_t pas; - gui_image_list_t electrics; - gui_image_list_t loks; - gui_image_list_t waggons; - gui_scrollpane_t scrolly_pas; - gui_scrollpane_t scrolly_electrics; - gui_scrollpane_t scrolly_loks; - gui_scrollpane_t scrolly_waggons; - gui_container_t cont_pas; - gui_container_t cont_electrics; - gui_container_t cont_loks; - gui_container_t cont_waggons; - static char no_line_text[128]; gui_combobox_t line_selector; + gui_convoy_assembler_t *convoy_assembler; + + linehandle_t selected_line; /** @@ -132,22 +95,9 @@ class depot_frame_t : public gui_frame_t, char txt_cnv_name[118]; - char txt_convoi_count[40]; char txt_convoi_value[40]; - char txt_convoi_speed[80]; char txt_convoi_line[128]; - enum { va_append, va_insert, va_sell }; - uint8 veh_action; - - /** - * A helper map to update loks_vec and waggons_Vec. All entries from - * loks_vec and waggons_vec are referenced here. - * @author Volker Meyer - * @date 09.06.2003 - */ - ptrhashtable_tpl<const vehikel_besch_t *, gui_image_list_t::image_data_t *> vehicle_map; - /** * Update texts, image lists and buttons according to the current state. * @author Volker Meyer @@ -155,22 +105,6 @@ class depot_frame_t : public gui_frame_t, */ void update_data(); - /** - * Draw the info text for the vehicle the mouse is over - if any. - * @author Volker Meyer, Hj. Malthaner - * @date 09.06.2003 - * @update 09-Jan-04 - */ - void draw_vehicle_info_text(koord pos); - - /** - * Calulate the values of the vehicles of the given type owned by the - * player. - * @author Volker Meyer - * @date 09.06.2003 - */ - sint32 calc_restwert(const vehikel_besch_t *veh_type); - /** * Do the dynamic dialog layout * @author Volker Meyer @@ -185,23 +119,11 @@ class depot_frame_t : public gui_frame_t, */ bool has_min_sizer() const {return true;} - // true if already stored here - bool is_contained(const vehikel_besch_t *info); - - // add a single vehicle (helper function) - void add_to_vehicle_list(const vehikel_besch_t *info); - - // for convoi image - void image_from_convoi_list(uint nr); - - vehikel_t* find_oldest_newest(const vehikel_besch_t* besch, bool old); - - void image_from_storage_list(gui_image_list_t::image_data_t *bild_data); - karte_t* get_welt() { return depot->get_welt(); } public: depot_frame_t(depot_t* depot); + virtual ~depot_frame_t(); /** * Setzt die Fenstergroesse @@ -210,13 +132,6 @@ class depot_frame_t : public gui_frame_t, */ void set_fenstergroesse(koord groesse); - /** - * Create and fill loks_vec and waggons_vec. - * @author Volker Meyer - * @date 09.06.2003 - */ - void build_vehicle_lists(); - /** * Manche Fenster haben einen Hilfetext assoziiert. * @return den Dateinamen für die Hilfe, oder NULL @@ -259,6 +174,9 @@ class depot_frame_t : public gui_frame_t, * V.Meyer */ bool action_triggered( gui_action_creator_t *komp, value_t extra); + inline depot_t *get_depot() const {return depot;} + inline convoihandle_t get_convoy() const {return depot->get_convoi(icnv);} + inline void update_convoy() {icnv<0?convoy_assembler->clear_convoy():convoy_assembler->set_vehicles(get_convoy());} }; #endif diff --git a/simconvoi.cc b/simconvoi.cc index 16723f4eef6..2d9890ccb5d 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -28,6 +28,8 @@ #include "boden/grund.h" #include "boden/wege/schiene.h" // for railblocks +#include "bauer/vehikelbauer.h" + #include "besch/vehikel_besch.h" #include "besch/roadsign_besch.h" @@ -104,30 +106,45 @@ static int calc_min_top_speed(const array_tpl<vehikel_t*>& fahr, uint8 anz_vehik } -void convoi_t::init(karte_t *wl, spieler_t *sp) +// Reset some values. Used in init and replacing. +void convoi_t::reset() { - welt = wl; - besitzer_p = sp; - is_electric = false; sum_gesamtgewicht = sum_gewicht = sum_gear_und_leistung = sum_leistung = power_from_steam = power_from_steam_with_gear = 0; previous_delta_v = 0; min_top_speed = 9999999; + withdraw = false; + has_obsolete = false; + no_load = false; + replace = false; + depot_when_empty = false; + + jahresgewinn = 0; + + max_record_speed = 0; + akt_speed_soll = 0; // Sollgeschwindigkeit + akt_speed = 0; // momentane Geschwindigkeit + sp_soll = 0; +} + +void convoi_t::init(karte_t *wl, spieler_t *sp) +{ + welt = wl; + besitzer_p = sp; + + reset(); + fpl = NULL; line = linehandle_t(); line_id = INVALID_LINE_ID; anz_vehikel = 0; steps_driven = -1; - withdraw = false; - has_obsolete = false; - no_load = false; + autostart = true; wait_lock = 0; go_on_ticks = WAIT_INFINITE; - jahresgewinn = 0; - alte_richtung = ribi_t::keine; next_wolke = 0; @@ -141,11 +158,6 @@ void convoi_t::init(karte_t *wl, spieler_t *sp) loading_level = 0; loading_limit = 0; - max_record_speed = 0; - akt_speed_soll = 0; // Sollgeschwindigkeit - akt_speed = 0; // momentane Geschwindigkeit - sp_soll = 0; - next_stop_index = 65535; line_update_pending = linehandle_t(); @@ -788,6 +800,46 @@ void convoi_t::step() switch(state) { + case INITIAL: + + // If there is a pending replacement, just do it + if (get_replace() && replacing_vehicles.get_count()>0) { + const grund_t *gr = welt->lookup(home_depot); + depot_t *dep; + if ( gr && (dep=gr->get_depot()) ) { + bool keep_name=(anz_vehikel>0 && strcmp(get_name(),fahr[0]->get_besch()->get_name())!=0); + // Sell the old convoy + besitzer_p->buche( calc_restwert(), dep->get_pos().get_2d(), COST_NEW_VEHICLE ); + besitzer_p->buche( -calc_restwert(), COST_ASSETS ); + for(int i=anz_vehikel-1; i>=0; i--) { + delete fahr[i]; + } + anz_vehikel = 0; + reset(); + // Buy the new one + for (unsigned int i=0; i<replacing_vehicles.get_count(); ++i) { + vehikel_t* veh = dep->find_oldest_newest(replacing_vehicles[i], true); + if (veh == NULL) { + // nothing there => we buy it + veh = dep->buy_vehicle(replacing_vehicles[i]); + } + dep->append_vehicle(self, veh, false); + } + if (!keep_name) { + set_name(fahr[0]->get_besch()->get_name()); + } + set_replace(false); + replacing_vehicles.clear(); + if (line.is_bound()) { + line->recalc_status(); + } + if (autostart) { + dep->start_convoi(self); + } + } + } + break; + case LOADING: laden(); break; @@ -994,6 +1046,7 @@ convoi_t::betrete_depot(depot_t *dep) // the sync list from inside sync_step() welt->sync_remove(this); state = INITIAL; + wait_lock = 0; } @@ -1061,7 +1114,7 @@ void convoi_t::ziel_erreicht() akt_speed = 0; sprintf(buf, translator::translate("!1_DEPOT_REACHED"), get_name()); welt->get_message()->add_message(buf, v->get_pos().get_2d(),message_t::convoi, PLAYER_FLAG|get_besitzer()->get_player_nr(), IMG_LEER); - + home_depot=v->get_pos(); betrete_depot(dp); } else { @@ -1078,6 +1131,11 @@ void convoi_t::ziel_erreicht() // Neither depot nor station: waypoint fpl->advance(); state = ROUTING_1; + if(depot_when_empty && loading_level==0) { + depot_when_empty=false; + no_load=false; + go_to_depot(false); + } } } wait_lock = 0; @@ -2620,6 +2678,102 @@ convoi_t::get_catering_level(uint8 type) const return max_catering_level; } +void convoi_t::set_replacing_vehicles(const vector_tpl<const vehikel_besch_t *> *rv) +{ + replacing_vehicles.clear(); + replacing_vehicles.resize(rv->get_count()); // To save some memory + for (unsigned int i=0; i<rv->get_count(); ++i) { + replacing_vehicles.push_back((*rv)[i]); + } +} + + + /** + * True if this convoy has the same vehicles as the other + * @author isidoro + */ +bool convoi_t::has_same_vehicles(convoihandle_t other) const +{ + if (other.is_bound()) { + if (get_vehikel_anzahl()!=other->get_vehikel_anzahl()) { + return false; + } + for (int i=0; i<get_vehikel_anzahl(); i++) { + if (get_vehikel(i)->get_besch()!=other->get_vehikel(i)->get_besch()) { + return false; + } + } + return true; + } + return false; +} + + +/** + * Convoy is sent to depot. Return value, success or not. + */ +bool convoi_t::go_to_depot(bool show_success) +{ + if (convoi_info_t::route_search_in_progress) { + return false; + } + // limit update to certain states that are considered to be save for fahrplan updates + int state = get_state(); + if(state==convoi_t::FAHRPLANEINGABE) { +DBG_MESSAGE("convoi_t::go_to_depot()","convoi state %i => cannot change schedule ... ", state ); + return false; + } + convoi_info_t::route_search_in_progress = true; + + // iterate over all depots and try to find shortest route + slist_iterator_tpl<depot_t *> depot_iter(depot_t::get_depot_list()); + route_t * shortest_route = new route_t(); + route_t * route = new route_t(); + koord3d home = koord3d(0,0,0); + while (depot_iter.next()) { + depot_t *depot = depot_iter.get_current(); + if(depot->get_wegtyp()!=get_vehikel(0)->get_besch()->get_waytype() || depot->get_besitzer()!=get_besitzer()) { + continue; + } + koord3d pos = depot->get_pos(); + if(!shortest_route->empty() && abs_distance(pos.get_2d(),get_pos().get_2d())>=shortest_route->get_max_n()) { + // the current route is already shorter, no need to search further + continue; + } + bool found = get_vehikel(0)->calc_route(get_pos(), pos, 50, route); // do not care about speed + if (found) { + if( route->get_max_n() < shortest_route->get_max_n() || shortest_route->empty() ) { + shortest_route->kopiere(route); + home = pos; + } + } + } + delete route; + DBG_MESSAGE("shortest route has ", "%i hops", shortest_route->get_max_n()); + + // if route to a depot has been found, update the convoi's schedule + bool b_depot_found = false; + if(!shortest_route->empty()) { + schedule_t *fpl = get_schedule(); + fpl->insert(get_welt()->lookup(home)); + fpl->set_aktuell( (fpl->get_aktuell()+fpl->get_count()-1)%fpl->get_count() ); + b_depot_found = set_schedule(fpl); + } + delete shortest_route; + convoi_info_t::route_search_in_progress = false; + + // show result + const char* txt; + if (b_depot_found) { + txt = "Convoi has been sent\nto the nearest depot\nof appropriate type.\n"; + } else { + txt = "Home depot not found!\nYou need to send the\nconvoi to the depot\nmanually."; + } + if (!b_depot_found || show_success) { + create_win( new news_img(txt), w_time_delete, magic_none); + } + return b_depot_found; +} /** diff --git a/simconvoi.h b/simconvoi.h index d853b428f88..79e6d373249 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -160,6 +160,24 @@ class convoi_t : public sync_steppable, public overtaker_t */ bool no_load; + /* + * the convoy is marked for automatic replacing + * @author isidoro + */ + bool replace; + + /** + * if marked for replacing, once in depot, auto restar the vehicle + * @author isidoro + */ + bool autostart; + + /** + * send to depot when empty + * @author isidoro + */ + bool depot_when_empty; + /** * the convoi caches its freight info; it is only recalculation after loading or resorting * @author prissi @@ -277,6 +295,9 @@ class convoi_t : public sync_steppable, public overtaker_t ribi_t::ribi alte_richtung; + // The replacing vehicles, if any + vector_tpl<const vehikel_besch_t *> replacing_vehicles; + /** * Initialize all variables with default values. * Each constructor must call this method first! @@ -355,6 +376,10 @@ class convoi_t : public sync_steppable, public overtaker_t */ koord3d home_depot; + // Helper function: used in init and replacing + void reset(); + + public: route_t* get_route() { return &route; } @@ -790,6 +815,27 @@ class convoi_t : public sync_steppable, public overtaker_t void set_no_load(bool new_no_load) { no_load = new_no_load; } + bool get_replace() const { return replace; } + + void set_replace(bool new_replace) { replace = new_replace; } + + bool get_depot_when_empty() const { return depot_when_empty; } + + void set_depot_when_empty(bool new_dwe) { depot_when_empty=new_dwe; } + + bool get_autostart() const { return autostart; } + + void set_autostart(bool new_autostart) { autostart=new_autostart; } + + const vector_tpl<const vehikel_besch_t *> *get_replacing_vehicles() const { return &replacing_vehicles; } + void set_replacing_vehicles(const vector_tpl<const vehikel_besch_t *> *rv); + + // True if the convoy has the same vehicles + bool has_same_vehicles(convoihandle_t other) const; + + // Go to depot, if possible + bool go_to_depot(bool show_success); + // Overtaking for convois virtual bool can_overtake(overtaker_t *other_overtaker, int other_speed, int steps_other, int diagonal_length); diff --git a/simdepot.cc b/simdepot.cc index 81f99fc3a94..deaee898b6b 100644 --- a/simdepot.cc +++ b/simdepot.cc @@ -109,6 +109,16 @@ depot_t *depot_t::find_depot( koord3d start, const ding_t::typ depot_type, const return found; } +unsigned depot_t::get_max_convoy_length(waytype_t wt) +{ + if (wt==road_wt || wt==water_wt) { + return 4; + } + if (wt==air_wt) { + return 1; + } + return convoi_t::max_rail_vehicle; +} /* this is called on two occasions: @@ -434,6 +444,25 @@ const char * depot_t::ist_entfernbar(const spieler_t *sp) return NULL; } +// returns the indest of the old/newest vehicle in a list +//@author: isidoro +vehikel_t* depot_t::find_oldest_newest(const vehikel_besch_t* besch, bool old) +{ + vehikel_t* found_veh = NULL; + slist_iterator_tpl<vehikel_t*> iter(get_vehicle_list()); + while (iter.next()) { + vehikel_t* veh = iter.get_current(); + if (veh->get_besch() == besch) { + // joy of XOR, finally a line where I could use it! + if (found_veh == NULL || + old ^ (found_veh->get_insta_zeit() > veh->get_insta_zeit())) { + found_veh = veh; + } + } + } + return found_veh; +} + slist_tpl<const vehikel_besch_t*>* depot_t::get_vehicle_type() { @@ -478,6 +507,21 @@ linehandle_t depot_t::get_selected_line() return selected_line; } + +sint32 depot_t::calc_restwert(const vehikel_besch_t *veh_type) +{ + sint32 wert = 0; + + slist_iterator_tpl<vehikel_t *> iter(get_vehicle_list()); + while(iter.next()) { + if(iter.get_current()->get_besch() == veh_type) { + wert += iter.get_current()->calc_restwert(); + } + } + return wert; +} + + bool bahndepot_t::can_convoi_start(convoihandle_t cnv) const { waytype_t wt=cnv->get_vehikel(0)->get_waytype(); @@ -526,3 +570,17 @@ bool bahndepot_t::can_convoi_start(convoihandle_t cnv) const } return success; } + +// true if already stored here +bool depot_t::is_contained(const vehikel_besch_t *info) +{ + if(vehicle_count()>0) { + slist_iterator_tpl<vehikel_t *> iter(get_vehicle_list()); + while(iter.next()) { + if(iter.get_current()->get_besch()==info) { + return true; + } + } + } + return false; +} diff --git a/simdepot.h b/simdepot.h index 5604d7a7257..be726d95a22 100644 --- a/simdepot.h +++ b/simdepot.h @@ -20,6 +20,7 @@ class vehikel_t; class schedule_t; class depot_frame_t; class vehikel_besch_t; +class gui_convoy_assembler; /** @@ -29,7 +30,7 @@ class vehikel_besch_t; class depot_t : public gebaeude_t { protected: - /** + /** * Reworked depot data! * * It can now contain any number of vehicles bough by the user (as before). @@ -57,6 +58,8 @@ class depot_t : public gebaeude_t static const slist_tpl<depot_t *>& get_depot_list() { return all_depots; } + static unsigned get_max_convoy_length(waytype_t wt); + depot_t(karte_t *welt,loadsave_t *file); depot_t(karte_t *welt, koord3d pos, spieler_t *sp, const haus_tile_besch_t *t); virtual ~depot_t(); @@ -67,12 +70,6 @@ class depot_t : public gebaeude_t virtual linehandle_t create_line(); - // text for the tabs is defaulted to the train names - virtual const char * get_electrics_name() { return "Electrics_tab"; }; - virtual const char * get_passenger_name() { return "Pas_tab"; } - virtual const char * get_zieher_name() { return "Lokomotive_tab"; } - virtual const char * get_haenger_name() { return "Waggon_tab"; } - /** * Access to convoi list. * @author Volker Meyer @@ -166,17 +163,6 @@ class depot_t : public gebaeude_t */ void convoi_arrived(convoihandle_t cnv, bool fpl_adjust); - /** - * Parameters to determine layout and behaviour of the depot_frame_t. - * @author Volker Meyer - * @date 09.06.2003 - */ - virtual int get_x_grid() const = 0; - virtual int get_y_grid() const = 0; - virtual int get_x_placement() const = 0; - virtual int get_y_placement() const = 0; - virtual unsigned get_max_convoi_length() const = 0; - /** * Öffnet ein neues Beobachtungsfenster für das Objekt. * @author Hj. Malthaner @@ -196,12 +182,31 @@ class depot_t : public gebaeude_t */ vehikel_t* get_oldest_vehicle(const vehikel_besch_t* besch); + /** + * Calulate the values of the vehicles of the given type owned by the + * player in this depot. + * @author Volker Meyer + * @date 09.06.2003 + */ + sint32 calc_restwert(const vehikel_besch_t *veh_type); + /* * sets/gets the line that was selected the last time in the depot-dialog */ void set_selected_line(const linehandle_t sel_line); linehandle_t get_selected_line(); + /* + * Find the oldest/newest vehicle in the depot + */ + vehikel_t* find_oldest_newest(const vehikel_besch_t* besch, bool old); + + // true if already stored here + bool is_contained(const vehikel_besch_t *info); + + // Helper function + inline unsigned get_max_convoi_length() const {return get_max_convoy_length(get_wegtyp());} + private: linehandle_t selected_line; }; @@ -226,17 +231,6 @@ class bahndepot_t : public depot_t void rdwr_vehicles(loadsave_t *file) { depot_t::rdwr_vehikel(vehicles,file); } - /** - * Parameters to determine layout and behaviour of the depot_frame_t. - * @author Volker Meyer - * @date 09.06.2003 - */ - int get_x_placement() const {return -25; } - int get_y_placement() const {return -28; } - int get_x_grid() const { return 24; } - int get_y_grid() const { return 24; } - unsigned get_max_convoi_length() const { return convoi_t::max_rail_vehicle; } - virtual waytype_t get_wegtyp() const {return track_wt;} virtual enum ding_t::typ get_typ() const {return bahndepot;} virtual const char *get_name() const {return "Bahndepot"; } @@ -303,29 +297,12 @@ class narrowgaugedepot_t : public bahndepot_t */ class strassendepot_t : public depot_t { -protected: - virtual const char * get_passenger_name() { return "Bus_tab"; } - virtual const char * get_electrics_name() { return "TrolleyBus_tab"; } - virtual const char * get_zieher_name() { return "LKW_tab"; } - virtual const char * get_haenger_name() { return "Anhaenger_tab"; } - public: strassendepot_t(karte_t *welt, loadsave_t *file) : depot_t(welt,file) {} strassendepot_t(karte_t *welt, koord3d pos,spieler_t *sp, const haus_tile_besch_t *t) : depot_t(welt,pos,sp,t) {} virtual simline_t::linetype get_line_type() const { return simline_t::truckline; } - /** - * Parameters to determine layout and behaviour of the depot_frame_t. - * @author Volker Meyer - * @date 09.06.2003 - */ - int get_x_placement() const { return -20; } - int get_y_placement() const { return -25; } - int get_x_grid() const { return 24; } - int get_y_grid() const { return 24; } - unsigned get_max_convoi_length() const { return 4; } - virtual waytype_t get_wegtyp() const {return road_wt; } enum ding_t::typ get_typ() const {return strassendepot;} const char *get_name() const {return "Strassendepot";} @@ -340,28 +317,12 @@ class strassendepot_t : public depot_t */ class schiffdepot_t : public depot_t { -protected: - virtual const char * get_passenger_name() { return "Ferry_tab"; } - virtual const char * get_zieher_name() { return "Schiff_tab"; } - virtual const char * get_haenger_name() { return "Schleppkahn_tab"; } - public: schiffdepot_t(karte_t *welt, loadsave_t *file) : depot_t(welt,file) {} schiffdepot_t(karte_t *welt, koord3d pos, spieler_t *sp, const haus_tile_besch_t *t) : depot_t(welt,pos,sp,t) {} virtual simline_t::linetype get_line_type() const { return simline_t::shipline; } - /** - * Parameters to determine layout and behaviour of the depot_frame_t. - * @author Volker Meyer - * @date 09.06.2003 - */ - int get_x_placement() const { return -1; } - int get_y_placement() const { return -11; } - int get_x_grid() const { return 60; } - int get_y_grid() const { return 46; } - - unsigned get_max_convoi_length() const { return 4; } virtual waytype_t get_wegtyp() const {return water_wt; } enum ding_t::typ get_typ() const {return schiffdepot;} const char *get_name() const {return "Schiffdepot";} @@ -369,27 +330,12 @@ class schiffdepot_t : public depot_t class airdepot_t : public depot_t { -protected: - virtual const char * get_zieher_name() { return "aircraft_tab"; } - virtual const char * get_passenger_name() { return "Flug_tab"; } - public: airdepot_t(karte_t *welt, loadsave_t *file) : depot_t(welt,file) {} airdepot_t(karte_t *welt, koord3d pos,spieler_t *sp, const haus_tile_besch_t *t) : depot_t(welt,pos,sp,t) {} virtual simline_t::linetype get_line_type() const { return simline_t::airline; } - /** - * Parameters to determine layout and behaviour of the depot_frame_t. - * @author Volker Meyer - * @date 09.06.2003 - */ - int get_x_placement() const {return -10; } - int get_y_placement() const {return -23; } - int get_x_grid() const { return 36; } - int get_y_grid() const { return 36; } - unsigned get_max_convoi_length() const { return 1; } - virtual waytype_t get_wegtyp() const { return air_wt; } enum ding_t::typ get_typ() const { return airdepot; } const char *get_name() const {return "Hangar";} diff --git a/simline.h b/simline.h index b0473d29f90..664485fe86d 100644 --- a/simline.h +++ b/simline.h @@ -88,8 +88,6 @@ class simline_t { void init_financial_history(); - void recalc_status(); - public: ~simline_t(); @@ -203,6 +201,8 @@ class simline_t { public: spieler_t *get_besitzer() const {return sp;} + void recalc_status(); + }; From 5c347051b5cdc98ece39dae67de8f47f8fd2ef61 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 15 Feb 2009 23:54:50 +0000 Subject: [PATCH 20/61] A number of issues with debug settings that caused problems including a crash on the release build fixed. --- Simutrans-Experimental.vcproj | 2 +- bauer/fabrikbauer.cc | 3 ++- bauer/tunnelbauer.cc | 3 ++- simdebug.h | 2 +- simsys_w16.cc | 2 +- simworld.cc | 4 +++- tpl/HOT_queue2_tpl.h | 3 ++- tpl/HOT_queue_tpl.h | 3 ++- 8 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Simutrans-Experimental.vcproj b/Simutrans-Experimental.vcproj index b0ad229e829..ce287e267e2 100644 --- a/Simutrans-Experimental.vcproj +++ b/Simutrans-Experimental.vcproj @@ -125,7 +125,7 @@ <Tool Name="VCCLCompilerTool" AdditionalIncludeDirectories=""G:\Projects\SDL-1.2.10\include";"G:\Program Files\PlatformSDK\Include";G:\Projects\zlib\include" - PreprocessorDefinitions="ZLIB_WINAPI;LITTLE_ENDIAN;STEPS16;USE_C;WIN32" + PreprocessorDefinitions="ZLIB_WINAPI;LITTLE_ENDIAN;STEPS16;USE_C;WIN32;NDEBUG" RuntimeLibrary="2" UsePrecompiledHeader="0" WarningLevel="3" diff --git a/bauer/fabrikbauer.cc b/bauer/fabrikbauer.cc index 2dd517f1336..557b8f48c6e 100644 --- a/bauer/fabrikbauer.cc +++ b/bauer/fabrikbauer.cc @@ -505,7 +505,8 @@ int fabrikbauer_t::baue_hierarchie(koord3d* parent, const fabrik_besch_t* info, pos->rotate90( welt->get_groesse_y()-info->get_haus()->get_h(rotate) ); welt->rotate90(); } - assert( !welt->cannot_save() ); + bool can_save = !welt->cannot_save(); + assert( can_save ); } // intown needs different place search diff --git a/bauer/tunnelbauer.cc b/bauer/tunnelbauer.cc index 30050fff42a..6efecbc1d3e 100644 --- a/bauer/tunnelbauer.cc +++ b/bauer/tunnelbauer.cc @@ -444,7 +444,8 @@ tunnelbauer_t::remove(karte_t *welt, spieler_t *sp, koord3d start, waytype_t weg } } while (!tmp_list.empty()); - assert(!end_list.empty()); + bool end_list_empty = !end_list.empty(); + assert(end_list_empty); // Jetzt geht es ans löschen der Tunnel while (!part_list.empty()) { diff --git a/simdebug.h b/simdebug.h index 46676c392a5..83f87bffb7b 100644 --- a/simdebug.h +++ b/simdebug.h @@ -13,7 +13,7 @@ // check assertions -#undef NDEBUG +//#undef NDEBUG //#define NDEBUG diff --git a/simsys_w16.cc b/simsys_w16.cc index 0cfd32dea0a..3e568fcaf92 100644 --- a/simsys_w16.cc +++ b/simsys_w16.cc @@ -683,7 +683,7 @@ void show_pointer(int yesno) state = yesno; } } - + void ex_ord_update_mx_my() diff --git a/simworld.cc b/simworld.cc index 1d559bdd5db..46e8d614c93 100644 --- a/simworld.cc +++ b/simworld.cc @@ -624,7 +624,9 @@ DBG_MESSAGE("karte_t::destroy()", "attraction list destroyed"); delete scenario; scenario = NULL; -assert( depot_t::get_depot_list().empty() ); + + bool empty_depot_list = depot_t::get_depot_list().empty(); + assert( empty_depot_list ); DBG_MESSAGE("karte_t::destroy()", "world destroyed"); printf("World destroyed.\n"); diff --git a/tpl/HOT_queue2_tpl.h b/tpl/HOT_queue2_tpl.h index 89721dddaa4..972087d5ebf 100644 --- a/tpl/HOT_queue2_tpl.h +++ b/tpl/HOT_queue2_tpl.h @@ -56,7 +56,8 @@ template <typename T, uint32 node_size = 8192> class HOT_queue_tpl private: void heapify(uint32 pocket) { - assert(!nodes[pocket].empty()); + bool nodes_not_empty = !nodes[pocket].empty(); + assert(nodes_not_empty); // needs resort: NULL pointer in the first pocket if (nodes[pocket].front() == NULL) { diff --git a/tpl/HOT_queue_tpl.h b/tpl/HOT_queue_tpl.h index 556724cc3bb..2cbadbe8515 100644 --- a/tpl/HOT_queue_tpl.h +++ b/tpl/HOT_queue_tpl.h @@ -82,7 +82,8 @@ template <typename T, uint32 node_size = 8192> class HOT_queue_tpl // ok, touching a possibly unsorted pocket if(need_resort) { // need heap'ifying ... - assert(heap.empty()); + bool heap_empty = heap.empty(); + assert(heap_empty); node_count -= nodes[node_top].count(); while (!nodes[node_top].empty()) { heap.insert( nodes[node_top].remove_first() ); From 98d34b71f0face37d0042affb0c4f95f7e2128fb Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 21 Feb 2009 12:57:25 +0000 Subject: [PATCH 21/61] Corrected bug which would cause instability and failures to unload cargo when loading a saved game. --- Simutrans-Experimental.vcproj | 8 ++++++ boden/wege/weg.cc | 5 ++++ dataobj/einstellungen.cc | 6 +++++ dataobj/einstellungen.h | 12 ++++++++- player/simplay.cc | 50 +++++++++++++++++++++++++++++------ player/simplay.h | 16 +++++++++-- simfab.cc | 2 +- simware.cc | 16 +++++++++-- simwerkz.cc | 7 ++--- vehicle/simvehikel.cc | 2 +- 10 files changed, 106 insertions(+), 18 deletions(-) diff --git a/Simutrans-Experimental.vcproj b/Simutrans-Experimental.vcproj index ce287e267e2..9afd7ccf057 100644 --- a/Simutrans-Experimental.vcproj +++ b/Simutrans-Experimental.vcproj @@ -1481,6 +1481,14 @@ RelativePath=".\gui\gui_convoiinfo.h" > </File> + <File + RelativePath=".\gui\components\gui_convoy_assembler.h" + > + </File> + <File + RelativePath=".\gui\components\gui_convoy_label.h" + > + </File> <File RelativePath=".\gui\components\gui_divider.h" > diff --git a/boden/wege/weg.cc b/boden/wege/weg.cc index ce8bfa319cf..a5d59249424 100644 --- a/boden/wege/weg.cc +++ b/boden/wege/weg.cc @@ -155,6 +155,8 @@ void weg_t::reset_way_constraints() /** * Setzt neue Beschreibung. Ersetzt alte Höchstgeschwindigkeit * mit wert aus Beschreibung. + * + * "Sets new description. Replaced old with maximum speed value of description." (Google) * @author Hj. Malthaner */ void weg_t::set_besch(const weg_besch_t *b) @@ -197,6 +199,7 @@ void weg_t::init() set_flag(ding_t::is_wayding); ribi = ribi_maske = ribi_t::keine; max_speed = 450; + max_weight = 999; besch = 0; init_statistics(); alle_wege.insert(this); @@ -239,6 +242,8 @@ void weg_t::rdwr(loadsave_t *file) file->rdwr_short(dummy16, "\n"); max_speed=dummy16; + //TODO: Implement load/save for weight limits + if(file->get_version()>=89000) { dummy8 = flags; file->rdwr_byte(dummy8,"f"); diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index b9e12f3ae11..6864e1f56ef 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -700,6 +700,12 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s //Factory settings factory_max_years_obsolete = contents.get_int("max_years_obsolete", 30); + //@author: jamespetts + // Insolvency and debt settings + interest_rate_percent = contents.get_int("interest_rate_percent", 10); + allow_bankruptsy = contents.get_int("allow_bankruptsy", 0); + allow_purhcases_when_insolvent = contents.get_int("allow_purhcases_when_insolvent", 0); + /* * Selection of savegame format through inifile */ diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index 50e251660d7..22c2ffc24cc 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -241,6 +241,12 @@ class einstellungen_t // Factory retirement settings uint16 factory_max_years_obsolete; + //@author: jamespetts + // Insolvency and debt settings + uint8 interest_rate_percent; + bool allow_bankruptsy; + bool allow_purhcases_when_insolvent; + // true if active bool automaten[MAX_PLAYER_COUNT]; // 0 = emtpy, otherwise some vaule from simplay @@ -417,11 +423,15 @@ class einstellungen_t uint8 get_max_direction_steps (waytype_t waytype) const { return max_direction_steps[waytype]; } uint8 get_curve_friction_factor (waytype_t waytype) const { return curve_friction_factor[waytype]; } - bool is_pay_for_total_distance() const { return pay_for_total_distance ; } + bool is_pay_for_total_distance() const { return pay_for_total_distance; } void set_pay_for_total_distance( bool b ) { pay_for_total_distance = b; } uint16 get_factory_max_years_obsolete() const { return factory_max_years_obsolete; } + uint8 get_interest_rate_percent() const { return interest_rate_percent; } + bool bankruptsy_allowed() const { return allow_bankruptsy; } + bool insolvent_purchases_allowed() const { return allow_purhcases_when_insolvent; } + sint16 get_river_number() const { return river_number; } void set_river_number( sint16 n ) { river_number=n; } sint16 get_min_river_length() const { return min_river_length; } diff --git a/player/simplay.cc b/player/simplay.cc index 79e6b1d6b94..7eba93626f0 100644 --- a/player/simplay.cc +++ b/player/simplay.cc @@ -307,26 +307,60 @@ void spieler_t::neuer_monat() return; } - // Bankrott ? - if(konto < 0) { + // Insolvency settings. + // Modified by jamespetts, February 2009 + if(konto < 0) + { konto_ueberzogen++; - if(!welt->get_einstellungen()->is_freeplay()) { + + //Add interest + + //Monthly rate + if(welt->get_einstellungen()->get_interest_rate_percent() > 0.0) + { + double interest_rate = ((welt->get_einstellungen()->get_interest_rate_percent() / 100.0) / 12.0); + sint32 monthly_interest = interest_rate * konto; + konto += monthly_interest; + } + + if(!welt->get_einstellungen()->is_freeplay()) + { if(this == welt->get_spieler(0)) { - if(finance_history_year[0][COST_NETWEALTH]<0) { + if(finance_history_year[0][COST_NETWEALTH]<0 && welt->get_einstellungen()->bankruptsy_allowed()) + { destroy_all_win(); create_win(280, 40, new news_img("Bankrott:\n\nDu bist bankrott.\n"), w_info, magic_none); welt->beenden(false); } - else { + else + { + int n = 0; // tell the player - sprintf(buf, translator::translate("On loan since %i month(s)"), konto_ueberzogen ); + if(konto_ueberzogen > 1) + { + // Plural detection for the months. + // Different languages pluralise in different ways, so whole string must + // be re-translated. + n += sprintf(buf, translator::translate("You have been overdrawn for %i months"), konto_ueberzogen ); + } + else + { + n += sprintf(buf, translator::translate("You have been overdrawn for one month"), konto_ueberzogen ); + } + if(welt->get_einstellungen()->get_interest_rate_percent() > 0) + { + n += sprintf(buf + n, translator::translate("\n\nInterest on your debt is\naccumulating at %i %%"), welt->get_einstellungen()->get_interest_rate_percent() ); + } // sprintf(buf,translator::translate("Verschuldet:\n\nDu hast %d Monate Zeit,\ndie Schulden zurueckzuzahlen.\n"), MAX_KONTO_VERZUG-konto_ueberzogen+1 ); welt->get_message()->add_message(buf,koord::invalid,message_t::problems,player_nr,IMG_LEER); } } - else if(automat && this!=welt->get_spieler(1)) { + else if(automat && this!=welt->get_spieler(1)) + { // for AI, we only declare bankrupt, if total assest are below zero - if(finance_history_year[0][COST_NETWEALTH]<0) { + // Also, AI players play by the same rules as human players: will only go bankrupt if humans can. + if(finance_history_year[0][COST_NETWEALTH]<0 && welt->get_einstellungen()->bankruptsy_allowed()) + { ai_bankrupt(); } } diff --git a/player/simplay.h b/player/simplay.h index c211498f83f..b102a6defa1 100644 --- a/player/simplay.h +++ b/player/simplay.h @@ -99,17 +99,19 @@ class spieler_t /** * Der Kontostand. + * "The account balance." (Google) * * @author Hj. Malthaner */ - sint64 konto; + sint64 konto; //"account" (Google) /** * Zählt wie viele Monate das Konto schon ueberzogen ist + * "Count how many months the account is already overdrawn" (Google) * * @author Hj. Malthaner */ - sint32 konto_ueberzogen; + sint32 konto_ueberzogen; //"overdrawn account" (Google) //slist_tpl<halthandle_t> halt_list; ///< Liste der Haltestellen vector_tpl<halthandle_t> halt_list; ///< "List of the stops" (Babelfish) @@ -342,6 +344,16 @@ class spieler_t */ virtual void bescheid_vehikel_problem(convoihandle_t cnv,const koord3d ziel); + // The maximum amount overdrawn that a player can be + // before no more purchases can be made. + uint32 credit_limit; + + //Checks the affordability of any possible purchase. + inline bool can_afford(sint64 price) + { + return (price < (konto + credit_limit) || welt->get_einstellungen()->insolvent_purchases_allowed() || welt->get_einstellungen()->is_freeplay()); + } + private: /* undo informations * * @author prissi diff --git a/simfab.cc b/simfab.cc index ca4265e19e1..5ee84cc43fc 100644 --- a/simfab.cc +++ b/simfab.cc @@ -1404,7 +1404,7 @@ void fabrik_t::info(cbuffer_t& buf) const { buf.clear(); - buf.printf("%s %li %s\n", translator::translate("Durchsatz"), get_current_production(), translator::translate("units/day")); + buf.printf("%s %i %s\n", translator::translate("Durchsatz"), get_current_production(), translator::translate("units/day")); if (!lieferziele.empty()) { buf.append("\n"); diff --git a/simware.cc b/simware.cc index a0bc19804c6..34db06f4183 100644 --- a/simware.cc +++ b/simware.cc @@ -39,8 +39,6 @@ ware_t::ware_t(const ware_besch_t *wtyp) : ziel(), zwischenziel(), zielpos(-1, - menge = 0; index = wtyp->get_index(); total_journey_start_time = journey_leg_start_time = 0; - halthandle_t x; - origin = previous_transfer = x; } // Constructor for new revenue system: packet of cargo keeps track of its origin. @@ -53,6 +51,7 @@ ware_t::ware_t(const ware_besch_t *wtyp, halthandle_t o, uint32 t) : ziel(), zwi total_journey_start_time = journey_leg_start_time = t; } + ware_t::ware_t(karte_t *welt,loadsave_t *file) { rdwr(welt,file); @@ -114,6 +113,11 @@ ware_t::rdwr(karte_t *welt,loadsave_t *file) ziel = welt->get_halt_koord_index(ziel_koord); ziel_koord.rdwr(file); zwischenziel = welt->get_halt_koord_index(ziel_koord); + + //TODO: Make the following the default option only if cannot load origin, etc., from file: + origin = previous_transfer = zwischenziel; + total_journey_start_time = journey_leg_start_time = welt->get_zeit_ms(); + } zielpos.rdwr(file); } @@ -131,4 +135,12 @@ ware_t::laden_abschliessen(karte_t *welt) //"Invite finish" (Google); "load lock if(zwischenziel.is_bound()) { zwischenziel = welt->lookup(zwischenziel->get_init_pos())->get_halt(); } + + if(origin.is_bound()) { + origin = welt->lookup(origin->get_init_pos())->get_halt(); + } + + if(previous_transfer.is_bound()) { + previous_transfer = welt->lookup(previous_transfer->get_init_pos())->get_halt(); + } } diff --git a/simwerkz.cc b/simwerkz.cc index 75bea202157..b3743921481 100644 --- a/simwerkz.cc +++ b/simwerkz.cc @@ -202,7 +202,7 @@ static halthandle_t suche_nahe_haltestelle(spieler_t *sp, karte_t *welt, koord3d } } - // now just search alll neighbours + // now just search all neighbours for( sint16 y=-1; y<=h; y++ ) { const planquadrat_t *plan = welt->lookup( pos.get_2d()+koord(-1,y) ); if(plan) { @@ -311,7 +311,8 @@ static grund_t *wkz_intern_koord_to_weg_grund(spieler_t *sp, karte_t *welt, koor /****************************************** now the actual tools **************************************/ // werkzeuge -const char *wkz_abfrage_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) +// "tools" (Babelfish) +const char *wkz_abfrage_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) //"queries" (Babelfish) { const planquadrat_t *plan = welt->lookup(pos.get_2d()); if(plan) { @@ -1555,8 +1556,8 @@ const char *wkz_brueckenbau_t::get_tooltip(spieler_t *sp) if(besch->get_waytype()!=powerline_wt) { n += sprintf(toolstr+n, ", %dkm/h", besch->get_topspeed()); + n += sprintf(toolstr+n, ", %dt", besch->get_max_weight()); } - n += sprintf(toolstr+n, ", %dt", besch->get_max_weight()); if(besch->get_max_length()>0) { n += sprintf(toolstr+n, ", %dkm", besch->get_max_length()); } diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 3c74d0a8bc6..2c4119e9361 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -1955,7 +1955,7 @@ DBG_MESSAGE("vehicle_t::rdwr_from_convoi()","bought at %i/%i.",(insta_zeit%12)+1 if(besch) { calc_bild(); // full weight after loading - sum_weight = (get_fracht_gewicht()+499)/1000 + besch->get_gewicht(); + sum_weight = (get_fracht_gewicht()+499)/1000 + besch->get_gewicht(); } // recalc total freight total_freight = 0; From 32f24a41453897aec29c875acec41f1893b56178 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 22 Feb 2009 19:04:00 +0000 Subject: [PATCH 22/61] Added new ways of dealing with debt and insolvency: players now have a credit limit, and, if the appropriate option is set, cannot spend on capital items (apart from the remove tool) beyond that limit. There is also a customisable interest rate for all debt. Bankruptcy can also be switched off, so that the only penalty is not being able to make any new capital expenditure. --- bauer/brueckenbauer.cc | 26 ++++++--- bauer/hausbauer.cc | 1 + bauer/tunnelbauer.cc | 8 +++ dings/baum.cc | 2 +- gui/convoi_info_t.cc | 7 ++- gui/depot_frame.cc | 13 +++-- gui/money_frame.cc | 24 ++++++-- gui/money_frame.h | 5 ++ player/simplay.cc | 43 ++++++++++++++- player/simplay.h | 28 ++++++---- simconvoi.cc | 38 +++++++++++-- simconvoi.h | 4 ++ simdepot.cc | 5 +- simhalt.cc | 7 ++- simhalt.h | 2 +- simline.cc | 10 +++- simline.h | 2 + simwerkz.cc | 122 ++++++++++++++++++++++++++++++++++++++--- 18 files changed, 295 insertions(+), 52 deletions(-) diff --git a/bauer/brueckenbauer.cc b/bauer/brueckenbauer.cc index 581f059508c..3a414eb4e3f 100644 --- a/bauer/brueckenbauer.cc +++ b/bauer/brueckenbauer.cc @@ -364,6 +364,7 @@ const char *brueckenbauer_t::baue( karte_t *welt, spieler_t *sp, koord pos, cons zv = koord(ribi_t::rueckwaerts(ribi)); // Brückenende suchen + // "Bridge End Search" (Google) const char *msg; koord3d end = finde_ende(welt, gr->get_pos(), zv, besch, msg ); @@ -377,10 +378,21 @@ DBG_MESSAGE("brueckenbauer_t::baue()", "end not ok"); if(gr_end->kann_alle_obj_entfernen(sp)) { return "Tile not empty."; } + + if(!sp->can_afford(besch->get_preis())) + { + return "That would exceed\nyour credit limit."; + } + // Anfang und ende sind geprueft, wir konnen endlich bauen - if(powerbridge) { + // "Beginning and end are approved, we can finally build" (Google) + if(powerbridge) + { baue_bruecke(welt, sp, gr->get_pos(), end, zv, besch, wegbauer_t::leitung_besch ); - } else { + } + + else + { baue_bruecke(welt, sp, gr->get_pos(), end, zv, besch, weg->get_besch() ); } return NULL; @@ -440,7 +452,7 @@ void brueckenbauer_t::baue_bruecke(karte_t *welt, spieler_t *sp, koord3d pos, ko // must determine end tile: on a slope => likely need auffahrt bool need_auffahrt = (pos.z==end.z); - if(need_auffahrt) { + if(need_auffahrt) { //"Need ramp" (Google) grund_t *gr = welt->lookup(end); weg_t *w = gr->get_weg( (waytype_t)weg_besch->get_wtyp()); if(w) { @@ -473,7 +485,7 @@ void brueckenbauer_t::baue_bruecke(karte_t *welt, spieler_t *sp, koord3d pos, ko spieler_t::accounting(sp, -wegbauer_t::leitung_besch->get_preis(), gr->get_pos().get_2d(), COST_CONSTRUCTION); gr->obj_add(lt); } - lt->calc_neighbourhood(); + lt->calc_neighbourhood(); } } } @@ -491,8 +503,7 @@ void brueckenbauer_t::baue_auffahrt(karte_t* welt, spieler_t* sp, koord3d end, k if(grund_hang == hang_t::flach) { weg_hang = hang_typ(zv); // nordhang - suedrampe } - - bruecke = new brueckenboden_t(welt, end, grund_hang, weg_hang); + bruecke = new brueckenboden_t(welt, end, grund_hang, weg_hang); // add the ramp if(bruecke->get_grund_hang() == hang_t::flach) { img = besch->get_rampe(ribi_neu); @@ -520,7 +531,7 @@ void brueckenbauer_t::baue_auffahrt(karte_t* welt, spieler_t* sp, koord3d end, k } else { leitung_t *lt = bruecke->get_leitung(); if(!lt) { - lt = new leitung_t(welt, bruecke->get_pos(), sp); + lt = new leitung_t(welt, bruecke->get_pos(), sp); //"leading" (Google) bruecke->obj_add( lt ); } else { // remove maintainance @@ -528,6 +539,7 @@ void brueckenbauer_t::baue_auffahrt(karte_t* welt, spieler_t* sp, koord3d end, k } lt->laden_abschliessen(); } + bruecke_t *br = new bruecke_t(welt, end, sp, besch, img); bruecke->obj_add( br ); br->laden_abschliessen(); diff --git a/bauer/hausbauer.cc b/bauer/hausbauer.cc index a15968f3190..fc8d54d5d95 100644 --- a/bauer/hausbauer.cc +++ b/bauer/hausbauer.cc @@ -720,6 +720,7 @@ const haus_besch_t* hausbauer_t::get_wohnhaus(int level, uint16 time, climate cl // get a random object const haus_besch_t *hausbauer_t::waehle_aus_liste(slist_tpl<const haus_besch_t *> &liste, uint16 time, bool ignore_retire, climate cl) { + //"select from list" (Google) if (!liste.empty()) { // previously just returned a random object; however, now we do als look at the chance entry weighted_vector_tpl<const haus_besch_t *> auswahl(16); diff --git a/bauer/tunnelbauer.cc b/bauer/tunnelbauer.cc index 6efecbc1d3e..92427539f27 100644 --- a/bauer/tunnelbauer.cc +++ b/bauer/tunnelbauer.cc @@ -261,15 +261,23 @@ const char *tunnelbauer_t::baue( karte_t *welt, spieler_t *sp, koord pos, const } } + if(!sp->can_afford(besch->get_preis())) + { + return "That would exceed\nyour credit limit."; + } + // pruefe ob Tunnel auf strasse/schiene endet + // "examine whether the tunnel on road / rail ends" (Google) if(!welt->ist_in_kartengrenzen(end.get_2d())) { return "Tunnel must end on single way!"; } // Anfang und ende sind geprueft, wir konnen endlich bauen + // "examine whether the tunnel on road / rail ends" (Google) if(!baue_tunnel(welt, sp, gr->get_pos(), end, zv, besch)) { return "Ways not connected"; } + return NULL; } diff --git a/dings/baum.cc b/dings/baum.cc index f1f4db0a5ab..de017ebc3f4 100644 --- a/dings/baum.cc +++ b/dings/baum.cc @@ -599,7 +599,7 @@ void baum_t::info(cbuffer_t & buf) const void -baum_t::entferne(spieler_t *sp) +baum_t::entferne(spieler_t *sp) //"remove" (Babelfish) { spieler_t::accounting(sp, welt->get_einstellungen()->cst_remove_tree, get_pos().get_2d(), COST_CONSTRUCTION); mark_image_dirty( get_bild(), 0 ); diff --git a/gui/convoi_info_t.cc b/gui/convoi_info_t.cc index 8a25fa56f6e..bd49e84d0d3 100644 --- a/gui/convoi_info_t.cc +++ b/gui/convoi_info_t.cc @@ -137,7 +137,10 @@ convoi_info_t::convoi_info_t(convoihandle_t cnv) set_fenstergroesse(koord(TOTAL_WIDTH, 278)); // chart - chart.set_pos(koord(44,76+BUTTON_HEIGHT+8)); + chart.set_pos(koord(44,76+BUTTON_HEIGHT+18)); + chart.set_groesse(koord(TOTAL_WIDTH-44-4, 100)); + chart.set_dimension(12, 10000); + chart.set_visible(false); chart.set_groesse(koord(TOTAL_WIDTH-44-4, 100)); chart.set_dimension(12, 10000); chart.set_visible(false); @@ -395,7 +398,7 @@ bool convoi_info_t::action_triggered( gui_action_creator_t *komp,value_t /* */) if (komp == &toggler) { toggler.pressed = !toggler.pressed; - const koord offset = toggler.pressed ? koord(0, 170) : koord(0, -170); + const koord offset = toggler.pressed ? koord(0, 170) : koord(0, -180); set_min_windowsize( koord(TOTAL_WIDTH, toggler.pressed ? 364: 194)); scrolly.set_pos( scrolly.get_pos()+koord(0,offset.y) ); // toggle visibility of components diff --git a/gui/depot_frame.cc b/gui/depot_frame.cc index d6d7f2250cc..825ef78d61e 100644 --- a/gui/depot_frame.cc +++ b/gui/depot_frame.cc @@ -408,12 +408,6 @@ bool depot_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) } break; default: // append/insert_in_front - if(!cnv.is_bound()) { - // create a new convoi - cnv = depot->add_convoi(); - icnv = depot->convoi_count() - 1; - cnv->set_name((*convoy_assembler->get_vehicles())[0]->get_name()); - } const vehikel_besch_t* vb; if (k.x==gui_convoy_assembler_t::insert_vehicle_in_front_action) { vb=(*convoy_assembler->get_vehicles())[0]; @@ -425,6 +419,13 @@ bool depot_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) // nothing there => we buy it veh = depot->buy_vehicle(vb); } + if(!cnv.is_bound()) + { + // create a new convoi + cnv = depot->add_convoi(); + icnv = depot->convoi_count() - 1; + cnv->set_name((*convoy_assembler->get_vehicles())[0]->get_name()); + } depot->append_vehicle(cnv, veh, k.x == gui_convoy_assembler_t::insert_vehicle_in_front_action); break; } diff --git a/gui/money_frame.cc b/gui/money_frame.cc index a2426617826..eb38c041deb 100644 --- a/gui/money_frame.cc +++ b/gui/money_frame.cc @@ -106,6 +106,8 @@ money_frame_t::money_frame_t(spieler_t *sp) old_tmoney(NULL, COL_WHITE, gui_label_t::money), old_mmoney(NULL, COL_WHITE, gui_label_t::money), old_omoney(NULL, COL_WHITE, gui_label_t::money), + credit_limit("Credit limit:", COL_WHITE, gui_label_t::right), + clamount(NULL, COL_BLACK, gui_label_t::money), tylabel2("This Year", COL_WHITE, gui_label_t::right), gtmoney(NULL, COL_WHITE, gui_label_t::money), vtmoney(NULL, COL_WHITE, gui_label_t::money), @@ -191,11 +193,14 @@ money_frame_t::money_frame_t(spieler_t *sp) maintenance_label.set_pos(koord(left+340+80, top+1*BUTTONSPACE-2)); maintenance_money.set_pos(koord(left+340+55, top+2*BUTTONSPACE)); - tylabel2.set_pos(koord(left+140+80+335,top+4*BUTTONSPACE-2)); - gtmoney.set_pos(koord(left+140+335+55, top+5*BUTTONSPACE)); - vtmoney.set_pos(koord(left+140+335+55, top+6*BUTTONSPACE)); - margin.set_pos(koord(left+140+335+55, top+7*BUTTONSPACE)); - money.set_pos(koord(left+140+335+55, top+8*BUTTONSPACE)); + credit_limit.set_pos(koord(left+140+80+335,top+3*BUTTONSPACE-8)); + clamount.set_pos(koord(left+140+335+55,top+4*BUTTONSPACE-8)); + + tylabel2.set_pos(koord(left+140+80+335,top+5*BUTTONSPACE-8)); + gtmoney.set_pos(koord(left+140+335+55, top+6*BUTTONSPACE-8)); + vtmoney.set_pos(koord(left+140+335+55, top+7*BUTTONSPACE-8)); + margin.set_pos(koord(left+140+335+55, top+8*BUTTONSPACE-8)); + money.set_pos(koord(left+140+335+55, top+9*BUTTONSPACE-8)); // return money or else stuff ... warn.set_pos(koord(left+335, top+10*BUTTONSPACE)); @@ -228,6 +233,9 @@ money_frame_t::money_frame_t(spieler_t *sp) add_komponente(&lylabel); add_komponente(&tylabel); + add_komponente(&credit_limit); + add_komponente(&clamount); + add_komponente(&tylabel2); add_komponente(>money); add_komponente(&vtmoney); @@ -308,7 +316,7 @@ money_frame_t::money_frame_t(spieler_t *sp) void money_frame_t::zeichnen(koord pos, koord gr) { // Hajo: each label needs its own buffer - static char str_buf[24][256]; + static char str_buf[25][256]; sp->calc_finance_history(); @@ -347,6 +355,10 @@ void money_frame_t::zeichnen(koord pos, koord gr) old_powerline.set_text(display_money(COST_POWERLINES, str_buf[23], 1)); old_powerline.set_color(get_money_colour(COST_POWERLINES, 1)); + //clamount.set_text(display_money(sp->get_credit_limit(), str_buf[24], 1)); + money_to_string(str_buf[24], sp->get_credit_limit() / 100.0); + clamount.set_text(str_buf[24]); + conmoney.set_color(get_money_colour(COST_CONSTRUCTION, 0)); nvmoney.set_color(get_money_colour(COST_NEW_VEHICLE, 0)); vrmoney.set_color(get_money_colour(COST_VEHICLE_RUN, 0)); diff --git a/gui/money_frame.h b/gui/money_frame.h index cee13abe9ca..59a306417a7 100644 --- a/gui/money_frame.h +++ b/gui/money_frame.h @@ -51,6 +51,11 @@ class money_frame_t : public gui_frame_t, private action_listener_t gui_label_t old_mmoney; gui_label_t old_omoney; + //Credit limit, right column + //@author: jamespetts + gui_label_t credit_limit; + gui_label_t clamount; + gui_label_t tylabel2; // this year, right column gui_label_t gtmoney; // balance (current) diff --git a/player/simplay.cc b/player/simplay.cc index 7eba93626f0..e70ac87fc99 100644 --- a/player/simplay.cc +++ b/player/simplay.cc @@ -120,6 +120,9 @@ spieler_t::spieler_t(karte_t *wl, uint8 nr) : // we have different AI, try to find out our type: sprintf(spieler_name_buf,"player %i",player_nr-1); + + base_credit_limit = 1000000; + credit_limit = calc_credit_limit(); } @@ -269,8 +272,10 @@ void spieler_t::neuer_monat() // since the messages must remain on the screen longer ... static char buf[256]; + credit_limit = calc_credit_limit(); // Wartungskosten abziehen + // "Deduct maintenance costs" (Google) calc_finance_history(); roll_finance_history_month(); @@ -447,12 +452,29 @@ void spieler_t::calc_finance_history() finance_history_month[0][COST_SCENARIO_COMPLETED] = finance_history_year[0][COST_SCENARIO_COMPLETED] = welt->get_scenario()->completed(player_nr); } +sint32 spieler_t::calc_credit_limit() +{ + sint32 profit = 0; + sint32 assets = 0; + for(uint8 i = 0; i <= 12; i++) + { + profit += finance_history_month[i][COST_OPERATING_PROFIT]; + assets += finance_history_month[i][COST_NETWEALTH]; + } + // Credit limit is 40% of net profit for the past year, + // plus 40% of the net assets for the past year, + // or 0, whichever is lower. + profit = (profit / 12.0) * 0.4; + assets = (assets/ 12.0) * 0.4; + + return ((profit + assets) > base_credit_limit) ? profit + assets : base_credit_limit; +} // add and amount, including the display of the message and some other things ... void spieler_t::buche(const sint64 betrag, const koord pos, enum player_cost type) { - buche(betrag, type); + buche(betrag, type); //"Buche" = "books"; "betrag" = "amount" (Babelfish). if(betrag != 0) { if( abs_distance(welt->get_world_position(),pos)<2*(display_get_width()/get_tile_raster_width())+3 ) { @@ -500,11 +522,25 @@ void spieler_t::buche(const sint64 betrag, enum player_cost type) void spieler_t::accounting( spieler_t *sp, const sint64 amount, koord k, enum player_cost pc ) { if(sp!=NULL && sp!=welt->get_spieler(1)) { - sp->buche( amount, k, pc ); + sp->buche( amount, k, pc ); //"Books" (Babelfish) } } +// Will only process the transaction if it can be afforded. +// @author: jamespetts +bool spieler_t::accounting_with_check( spieler_t *sp, const sint64 amount, koord k, enum player_cost pc ) +{ + if(sp->can_afford(amount)) + { + accounting(sp, amount, k, pc); + return true; + } + else + { + return false; + } +} bool spieler_t::check_owner( const spieler_t *owner, const spieler_t *test ) @@ -853,6 +889,9 @@ DBG_DEBUG("spieler_t::rdwr()","player %i: loading %i halts.",welt->sp2num( this if(file->get_version()>=88003) { simlinemgmt.rdwr(welt,file,this); } + + base_credit_limit = 1000000; + credit_limit = calc_credit_limit(); } diff --git a/player/simplay.h b/player/simplay.h index b102a6defa1..0fa290e4d50 100644 --- a/player/simplay.h +++ b/player/simplay.h @@ -229,6 +229,8 @@ class spieler_t // this is also save to be called with sp==NULL, which may happen for unowned objects like bridges, ways, trees, ... static void accounting( spieler_t *sp, const sint64 betrag, koord k, enum player_cost pc ); + + static bool accounting_with_check( spieler_t *sp, const sint64 betrag, koord k, enum player_cost pc ); /** * @return Kontostand als double (Gleitkomma) Wert @@ -344,16 +346,6 @@ class spieler_t */ virtual void bescheid_vehikel_problem(convoihandle_t cnv,const koord3d ziel); - // The maximum amount overdrawn that a player can be - // before no more purchases can be made. - uint32 credit_limit; - - //Checks the affordability of any possible purchase. - inline bool can_afford(sint64 price) - { - return (price < (konto + credit_limit) || welt->get_einstellungen()->insolvent_purchases_allowed() || welt->get_einstellungen()->is_freeplay()); - } - private: /* undo informations * * @author prissi @@ -361,11 +353,27 @@ class spieler_t vector_tpl<koord3d> last_built; waytype_t undo_type; + // The maximum amount overdrawn that a player can be + // before no more purchases can be made. + sint32 credit_limit; + sint32 base_credit_limit; + +protected: + sint32 calc_credit_limit(); + public: void init_undo(waytype_t t, unsigned short max ); void add_undo(koord3d k); bool undo(); + //Checks the affordability of any possible purchase. + inline bool can_afford(sint64 price) const + { + return (price < (konto + credit_limit) || welt->get_einstellungen()->insolvent_purchases_allowed() || welt->get_einstellungen()->is_freeplay()); + } + + uint32 get_credit_limit() const { return credit_limit; } + // headquarter stuff private: sint32 headquarter_level; diff --git a/simconvoi.cc b/simconvoi.cc index 2d9890ccb5d..05cb0d9ef7d 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -832,6 +832,12 @@ void convoi_t::step() replacing_vehicles.clear(); if (line.is_bound()) { line->recalc_status(); + if (line->get_replacing_convoys_count()==0) { + char buf[128]; + sprintf(buf, translator::translate("Replacing\nvehicles of\n%-20s\ncompleted"), line->get_name()); + welt->get_message()->add_message(buf, home_depot.get_2d(),message_t::convoi, PLAYER_FLAG|get_besitzer()->get_player_nr(), IMG_LEER); + } + } if (autostart) { dep->start_convoi(self); @@ -1112,8 +1118,11 @@ void convoi_t::ziel_erreicht() calc_gewinn(); akt_speed = 0; - sprintf(buf, translator::translate("!1_DEPOT_REACHED"), get_name()); - welt->get_message()->add_message(buf, v->get_pos().get_2d(),message_t::convoi, PLAYER_FLAG|get_besitzer()->get_player_nr(), IMG_LEER); + if (!replace || !autostart) { + sprintf(buf, translator::translate("!1_DEPOT_REACHED"), get_name()); + welt->get_message()->add_message(buf, v->get_pos().get_2d(),message_t::convoi, PLAYER_FLAG|get_besitzer()->get_player_nr(), IMG_LEER); + } + home_depot=v->get_pos(); betrete_depot(dp); } @@ -1131,7 +1140,7 @@ void convoi_t::ziel_erreicht() // Neither depot nor station: waypoint fpl->advance(); state = ROUTING_1; - if(depot_when_empty && loading_level==0) { + if(replace && depot_when_empty && has_no_cargo()) { depot_when_empty=false; no_load=false; go_to_depot(false); @@ -2256,7 +2265,7 @@ void convoi_t::laden() //"load" (Babelfish) // Nun wurde ein/ausgeladen werden if(loading_level>=loading_limit || no_load || welt->get_zeit_ms()>go_on_ticks) { - if(withdraw && loading_level==0) { + if(withdraw && has_no_cargo()) { // destroy when empty besitzer_p->buche( calc_restwert(), COST_NEW_VEHICLE ); besitzer_p->buche( -calc_restwert(), COST_ASSETS ); @@ -2775,6 +2784,27 @@ DBG_MESSAGE("convoi_t::go_to_depot()","convoi state %i => cannot change schedule return b_depot_found; } +bool convoi_t::has_no_cargo() const +{ + if (loading_level==0) + { + return true; + } + if (loading_level!=100) + { + return false; + } + /* a convoy with max capacity of zero, has always loading_level==100 */ + for(unsigned i=0; i<anz_vehikel; i++) + { + if (fahr[i]->get_fracht_max()>0) + { + return false; + } + } + return true; +} + /** * conditions for a city car to overtake another overtaker. diff --git a/simconvoi.h b/simconvoi.h index 79e6d373249..eab128021ee 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -836,6 +836,10 @@ class convoi_t : public sync_steppable, public overtaker_t // Go to depot, if possible bool go_to_depot(bool show_success); + // True if convoy has no cargo + //@author: isidoro + bool has_no_cargo() const; + // Overtaking for convois virtual bool can_overtake(overtaker_t *other_overtaker, int other_speed, int steps_other, int diagonal_length); diff --git a/simdepot.cc b/simdepot.cc index deaee898b6b..3fc37e75e51 100644 --- a/simdepot.cc +++ b/simdepot.cc @@ -178,8 +178,9 @@ bool depot_t::can_convoi_start(convoihandle_t /*cnv*/) const vehikel_t* depot_t::buy_vehicle(const vehikel_besch_t* info) { // Offen: prüfen ob noch platz im depot ist??? + // "Hours: check whether there is space in the depot?" (Google) DBG_DEBUG("depot_t::buy_vehicle()", info->get_name()); - vehikel_t* veh = vehikelbauer_t::baue(get_pos(), get_besitzer(), NULL, info ); + vehikel_t* veh = vehikelbauer_t::baue(get_pos(), get_besitzer(), NULL, info ); //"besitzer" = "owner" (Google) DBG_DEBUG("depot_t::buy_vehicle()", "vehiclebauer %p", veh); vehicles.append(veh); @@ -452,7 +453,7 @@ vehikel_t* depot_t::find_oldest_newest(const vehikel_besch_t* besch, bool old) slist_iterator_tpl<vehikel_t*> iter(get_vehicle_list()); while (iter.next()) { vehikel_t* veh = iter.get_current(); - if (veh->get_besch() == besch) { + if (veh != NULL && veh->get_besch() == besch) { // joy of XOR, finally a line where I could use it! if (found_veh == NULL || old ^ (found_veh->get_insta_zeit() > veh->get_insta_zeit())) { diff --git a/simhalt.cc b/simhalt.cc index 5b871fbddef..77588c6aa31 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -1711,7 +1711,7 @@ sint64 haltestelle_t::calc_maintenance() // changes this to a publix transfer exchange stop -void haltestelle_t::make_public_and_join( spieler_t *sp ) +bool haltestelle_t::make_public_and_join( spieler_t *sp ) { spieler_t *public_owner=welt->get_spieler(1); sint64 total_costs = 0; @@ -1727,6 +1727,10 @@ void haltestelle_t::make_public_and_join( spieler_t *sp ) spieler_t *gb_sp=gb->get_besitzer(); sint64 costs = welt->get_einstellungen()->maint_building*gb->get_tile()->get_besch()->get_level(); total_costs += costs; + if(!sp->can_afford((total_costs*60)<<(welt->ticks_bits_per_tag-18))) + { + return false; + } spieler_t::add_maintenance( gb_sp, -costs ); gb->set_besitzer(public_owner); spieler_t::add_maintenance(public_owner, costs ); @@ -1782,6 +1786,7 @@ void haltestelle_t::make_public_and_join( spieler_t *sp ) } recalc_station_type(); + return true; } diff --git a/simhalt.h b/simhalt.h index 9f79745f8e3..223d7dc4b87 100644 --- a/simhalt.h +++ b/simhalt.h @@ -322,7 +322,7 @@ class haltestelle_t // just for info so far sint64 calc_maintenance(); - void make_public_and_join( spieler_t *sp ); + bool make_public_and_join( spieler_t *sp ); const vector_tpl<halthandle_t> *get_warenziele_passenger() const {return warenziele;} const vector_tpl<halthandle_t> *get_warenziele_mail() const {return warenziele+1;} diff --git a/simline.cc b/simline.cc index 1878a0a8d5f..4e614835a1c 100644 --- a/simline.cc +++ b/simline.cc @@ -187,7 +187,15 @@ DBG_DEBUG("simline_t::register_stops()", "halt null"); } } - +int simline_t::get_replacing_convoys_count() const { + int count=0; + for (int i=0; i<line_managed_convoys.get_count(); ++i) { + if (line_managed_convoys[i]->get_replace()) { + count++; + } + } + return count; +} void simline_t::unregister_stops() { diff --git a/simline.h b/simline.h index 664485fe86d..9b7668d714d 100644 --- a/simline.h +++ b/simline.h @@ -198,6 +198,8 @@ class simline_t { // recalculates the good transported by this line and (in case of changes) will start schedule recalculation void recalc_catg_index(); + int get_replacing_convoys_count() const; + public: spieler_t *get_besitzer() const {return sp;} diff --git a/simwerkz.cc b/simwerkz.cc index b3743921481..c286a154b53 100644 --- a/simwerkz.cc +++ b/simwerkz.cc @@ -978,7 +978,12 @@ const char *wkz_marker_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) const ding_t* thing = gr->obj_bei(0); const label_t* l = gr->find<label_t>(); - if(thing == NULL || thing->get_besitzer() == sp || (spieler_t::check_owner(thing->get_besitzer(), sp) && (thing->get_typ() != ding_t::gebaeude))) { + if(thing == NULL || thing->get_besitzer() == sp || (spieler_t::check_owner(thing->get_besitzer(), sp) && (thing->get_typ() != ding_t::gebaeude))) + { + if(!sp->can_afford(welt->get_einstellungen()->cst_buy_land)) + { + return "That would exceed\nyour credit limit."; + } gr->obj_add(new label_t(welt, gr->get_pos(), sp, "\0")); gr->find<label_t>()->zeige_info(); return ""; @@ -1060,6 +1065,12 @@ const char *wkz_transformer_t::get_tooltip( spieler_t *sp ) const char *wkz_transformer_t::work( karte_t *welt, spieler_t *sp, koord3d k ) { DBG_MESSAGE("wkz_senke()","called on %d,%d", k.x, k.y); + + if(!sp->can_afford(welt->get_einstellungen()->cst_transformer)) + { + return "That would exceed\nyour credit limit."; + } + grund_t *gr=welt->lookup_kartenboden(k.get_2d()); if(gr && gr->get_grund_hang()==0 && !gr->ist_wasser() && !gr->hat_wege() && gr->kann_alle_obj_entfernen(sp)==NULL) { @@ -1096,6 +1107,12 @@ DBG_MESSAGE("wkz_senke()","called on %d,%d", k.x, k.y); */ const char *wkz_add_city_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) { + + if(!sp->can_afford(0 - welt->get_einstellungen()->cst_found_city)) + { + return "That would exceed\nyour credit limit."; + } + grund_t *gr = welt->lookup_kartenboden(pos.get_2d()); if(gr) { @@ -1164,20 +1181,28 @@ const char *wkz_change_city_size_t::work( karte_t *welt, spieler_t *, koord3d po const char *wkz_plant_tree_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) { - if(welt->ist_in_kartengrenzen(pos.get_2d())) { + if(!sp->can_afford(welt->get_einstellungen()->cst_remove_tree)) + { + return "That would exceed\nyour credit limit."; + } + + if(welt->ist_in_kartengrenzen(pos.get_2d())) + { const baum_besch_t *besch = NULL; bool check_climates = true; bool random_age = false; if(default_param==NULL) { besch = baum_t::random_tree_for_climate( welt->get_climate(pos.z) ); } - else { + else + { // parse default_param: bbbesch_nr b=1 ignore climate b=1 randome age check_climates = default_param[0]=='0'; random_age = default_param[1]=='1'; besch = baum_t::find_tree(default_param+3); } - if(besch && baum_t::plant_tree_on_coordinate( welt, pos.get_2d(), besch, check_climates, random_age ) ) { + if(besch && baum_t::plant_tree_on_coordinate( welt, pos.get_2d(), besch, check_climates, random_age ) ) + { spieler_t::accounting( sp, welt->get_einstellungen()->cst_remove_tree, pos.get_2d(), COST_CONSTRUCTION ); return NULL; } @@ -1453,6 +1478,11 @@ const char *wkz_wegebau_t::work(karte_t *welt, spieler_t *sp, koord3d pos ) return false; } + if(!sp->can_afford(besch->get_preis())) + { + return "That would exceed\nyour credit limit."; + } + grund_t *gr=NULL; if(grund_t::underground_mode) { // search all grounds for match @@ -1910,6 +1940,12 @@ const char *wkz_wayobj_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) if(besch==NULL) { besch = default_electric; } + + if(!sp->can_afford(besch->get_preis())) + { + return "That would exceed\nyour credit limit."; + } + waytype_t wt=besch->get_wtyp(); koord3d end; @@ -1975,6 +2011,12 @@ const char *wkz_wayobj_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) /* build all kind of station extension buildings */ const char *wkz_station_t::wkz_station_building_aux(karte_t *welt, spieler_t *sp, koord3d k, const haus_besch_t *besch, sint8 rotation ) { + + if(!sp->can_afford(welt->get_einstellungen()->cst_multiply_post*besch->get_level()*besch->get_b()*besch->get_h())) + { + return "That would exceed\nyour credit limit."; + } + koord pos = k.get_2d(); DBG_MESSAGE("wkz_station_building_aux()", "building mail office/station building on square %d,%d", pos.x, pos.y); @@ -2576,9 +2618,16 @@ const char *wkz_station_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) sint8 rotation; const haus_besch_t *besch=get_besch(rotation); + + + const char *msg = NULL; switch (besch->get_utyp()) { case haus_besch_t::hafen: + if(!sp->can_afford(welt->get_einstellungen()->cst_multiply_dock * besch->get_level())) + { + return "That would exceed\nyour credit limit."; + } msg = wkz_station_t::wkz_station_dock_aux(welt, sp, pos, besch ); break; case haus_besch_t::hafen_geb: @@ -2588,6 +2637,10 @@ const char *wkz_station_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) case haus_besch_t::generic_stop: switch(besch->get_extra()) { case road_wt: + if(!sp->can_afford(welt->get_einstellungen()->cst_multiply_roadstop * besch->get_level())) + { + return "That would exceed\nyour credit limit."; + } msg = wkz_station_t::wkz_station_aux(welt, sp, pos, besch, road_wt, welt->get_einstellungen()->cst_multiply_roadstop, "H"); break; case track_wt: @@ -2595,12 +2648,24 @@ const char *wkz_station_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) case maglev_wt: case narrowgauge_wt: case tram_wt: + if(!sp->can_afford(welt->get_einstellungen()->cst_multiply_station * besch->get_level())) + { + return "That would exceed\nyour credit limit."; + } msg = wkz_station_t::wkz_station_aux(welt, sp, pos, besch, (waytype_t)besch->get_extra(), welt->get_einstellungen()->cst_multiply_station, "BF"); break; case water_wt: + if(!sp->can_afford(welt->get_einstellungen()->cst_multiply_dock * besch->get_level())) + { + return "That would exceed\nyour credit limit."; + } msg = wkz_station_t::wkz_station_aux(welt, sp, pos, besch, water_wt, welt->get_einstellungen()->cst_multiply_dock, "Dock"); break; case air_wt: + if(!sp->can_afford(welt->get_einstellungen()->cst_multiply_airterminal * besch->get_level())) + { + return "That would exceed\nyour credit limit."; + } msg = wkz_station_t::wkz_station_aux(welt, sp, pos, besch, air_wt, welt->get_einstellungen()->cst_multiply_airterminal, "Airport"); break; } @@ -2632,6 +2697,10 @@ const char *wkz_roadsign_t::work( karte_t *welt, spieler_t *sp, koord3d k ) { DBG_MESSAGE("wkz_roadsign()","called on %d,%d", k.x, k.y); const roadsign_besch_t * besch = roadsign_t::find_besch(default_param); + if(!sp->can_afford(besch->get_preis())) + { + return "That would exceed\nyour credit limit."; + } if(besch==NULL) { dbg->fatal("wkz_roadsign_t::work()","No roadsign \"%s\"", default_param ); } @@ -2734,6 +2803,34 @@ const char *wkz_roadsign_t::work( karte_t *welt, spieler_t *sp, koord3d k ) // built all types of depots const char *wkz_depot_t::wkz_depot_aux(karte_t *welt, spieler_t *sp, koord pos, const haus_besch_t *besch, waytype_t wegtype, sint64 cost) { + switch(wegtype) + { + case monorail_wt: + case maglev_wt: + case narrowgauge_wt: + case tram_wt: + case track_wt: + if(!sp->can_afford(welt->get_einstellungen()->cst_depot_rail)) + { + return "That would exceed\nyour credit limit."; + } + case water_wt: + if(!sp->can_afford(welt->get_einstellungen()->cst_depot_ship)) + { + return "That would exceed\nyour credit limit."; + } + case air_wt: + if(!sp->can_afford(welt->get_einstellungen()->cst_depot_air)) + { + return "That would exceed\nyour credit limit."; + } + case road_wt: + if(!sp->can_afford(welt->get_einstellungen()->cst_depot_road)) + { + return "That would exceed\nyour credit limit."; + } + }; + if(welt->ist_in_kartengrenzen(pos)) { grund_t *bd=NULL; // special for the seven seas ... @@ -3730,16 +3827,23 @@ const char *wkz_make_stop_public_t::move( karte_t *welt, spieler_t *sp, uint16, const char *wkz_make_stop_public_t::work( karte_t *welt, spieler_t *sp, koord3d p ) { const planquadrat_t *pl = welt->lookup(p.get_2d()); - if(!pl || !pl->get_halt().is_bound()) { + if(!pl || !pl->get_halt().is_bound()) + { return "No stop here!"; } - else { + else + { halthandle_t halt = pl->get_halt(); - if( !(spieler_t::check_owner(halt->get_besitzer(),sp) || halt->get_besitzer()==welt->get_spieler(1)) ) { + if( !(spieler_t::check_owner(halt->get_besitzer(),sp) || halt->get_besitzer()==welt->get_spieler(1)) ) + { return "Das Feld gehoert\neinem anderen Spieler\n"; } - else { - halt->make_public_and_join(sp); + else + { + if(!halt->make_public_and_join(sp)) + { + return "That would exceed\nyour credit limit."; + } } } return NULL; From 21438a95e8af13a725bb3b955545ba1d928f5185 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Wed, 25 Feb 2009 22:41:37 +0000 Subject: [PATCH 23/61] Credit limit only shown in finances window when freeplay is not being used, and when insolvent purchases are not allowed. --- gui/money_frame.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gui/money_frame.cc b/gui/money_frame.cc index eb38c041deb..988dc740126 100644 --- a/gui/money_frame.cc +++ b/gui/money_frame.cc @@ -233,8 +233,11 @@ money_frame_t::money_frame_t(spieler_t *sp) add_komponente(&lylabel); add_komponente(&tylabel); - add_komponente(&credit_limit); - add_komponente(&clamount); + if(!sp->get_welt()->get_einstellungen()->insolvent_purchases_allowed() || sp->get_welt()->get_einstellungen()->is_freeplay()) + { + add_komponente(&credit_limit); + add_komponente(&clamount); + } add_komponente(&tylabel2); add_komponente(>money); From f2ff343e773ce23bdbf61680b1a66bf9d4dce3ba Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Thu, 26 Feb 2009 22:19:23 +0000 Subject: [PATCH 24/61] Fixed a bug that could cause a crash in some cases, relating to the code for hill climbing. --- vehicle/simvehikel.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 3d05d55eb06..15b0deb9637 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -1397,7 +1397,8 @@ vehikel_t::calc_akt_speed(const grund_t *gr) //,const int h_alt, const int h_neu { hill.add_to_head(ribi_typ(hang)==fahrtrichtung); uint8 hill_number; - for(hill_number = 0; hill_number < 5; hill_number ++) + uint8 hill_count = hill.get_count(); + for(hill_number = 0; hill_number < hill_count; hill_number ++) { if(!hill[hill_number]) { From 195b8b5c375d12282615105594d1c977a1621e1c Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Thu, 26 Feb 2009 23:26:59 +0000 Subject: [PATCH 25/61] Ticks now only shown on debug builds. Also, missing file for the vehicle replacing included. --- gui/replace_frame.h | 133 ++++++++++++++++++++++++++++++++++++++++++++ simwin.cc | 12 +++- 2 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 gui/replace_frame.h diff --git a/gui/replace_frame.h b/gui/replace_frame.h new file mode 100644 index 00000000000..6118a51f854 --- /dev/null +++ b/gui/replace_frame.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1997 - 2001 Hansjörg Malthaner + * + * This file is part of the Simutrans project under the artistic licence. + * (see licence.txt) + */ + +#ifndef replace_frame_t_h +#define replace_frame_t_h + +#include "gui_frame.h" + +#include "components/action_listener.h" +#include "components/gui_button.h" +#include "components/gui_convoy_assembler.h" +#include "components/gui_convoy_label.h" +#include "components/gui_label.h" +#include "components/gui_numberinput.h" +#include "messagebox.h" + + +/** + * Replace frame, makes convoys be marked for replacing. + * + * @author isidoro + * @date Jan-09 + */ +class replace_frame_t : public gui_frame_t, + public action_listener_t +{ +private: + /** + * The convoy to be replaced + */ + convoihandle_t cnv; + sint32 new_convoy_cost; + + bool replace_line; // True if all convoys like this in its line are to be replaced + bool replace_all; // True if all convoys like this are to be replaced + bool depot; // True if convoy is to be sent to depot only + bool autostart; // True if convoy is to be sent to depot and restarted automatically + enum {state_replace=0, state_sell, state_skip, n_states}; + int state; + int replaced_so_far; + sint32 money; + + /** + * Gui elements + */ + gui_convoy_label_t lb_convoy; + gui_label_t lb_to_be_replaced; + gui_convoy_assembler_t *convoy_assembler; + gui_label_t lb_money; + button_t bt_replace_line; + button_t bt_replace_all; + button_t bt_autostart; + button_t bt_depot; + button_t bt_mark; + gui_label_t lb_replace_cycle; + gui_label_t lb_replace; + gui_label_t lb_sell; + gui_label_t lb_skip; + gui_label_t lb_n_replace; + gui_label_t lb_n_sell; + gui_label_t lb_n_skip; + gui_numberinput_t numinp[n_states]; + char txt_money[16]; + char txt_n_replace[8]; + char txt_n_sell[8]; + char txt_n_skip[8]; + + /** + * Update texts, image lists and buttons according to the current state. + * @author Volker Meyer + * @date 09.06.2003 + */ + void update_data(); + + /** + * Do the dynamic dialog layout + */ + void layout(koord *); + + int total_width, min_total_width, total_height, min_total_height; + + // Some helper functions + void update_total_height(int height); + void update_total_width(int width); + void replace_convoy(convoihandle_t cnv); + inline void start_replacing() {state=state_replace; replaced_so_far=0;} + int get_present_state(); + + karte_t* get_welt() { return cnv->get_welt(); } + +public: + replace_frame_t(convoihandle_t cnv, const char *name); + virtual ~replace_frame_t(); + + /** + * Setzt die Fenstergroesse + * @author (Mathew Hounsell) + * @date 11-Mar-2003 + */ + void set_fenstergroesse(koord groesse); + + /** + * Manche Fenster haben einen Hilfetext assoziiert. + * @return den Dateinamen für die Hilfe, oder NULL + * @author Hj. Malthaner + */ + const char * get_hilfe_datei() const {return "replace.txt";} + + void infowin_event(const event_t *ev); + + /** + * Zeichnet das Frame + * @author Hansjörg Malthaner + */ + void zeichnen(koord pos, koord gr); + + /** + * This method is called if an action is triggered + * @author Hj. Malthaner + * + * Returns true, if action is done and no more + * components should be triggered. + * V.Meyer + */ + bool action_triggered( gui_action_creator_t *komp, value_t extra); + +}; + +#endif \ No newline at end of file diff --git a/simwin.cc b/simwin.cc index 05daf27bc70..403a91a9694 100644 --- a/simwin.cc +++ b/simwin.cc @@ -1085,14 +1085,22 @@ void win_display_flush(double konto) // @author prissi - also show date if desired switch(umgebung_t::show_month) { // german style - case 4: sprintf(time, "%s, %d %s %d %d:%02dh TICKS: %d", +#ifdef DEBUG + case 4: sprintf(time, "%s, %d %s %d %d:%02dh TICKS: %d", +#else + case 4: sprintf(time, "%s, %d %s %d %d:%02dh", +#endif translator::translate(seasons[wl->get_jahreszeit()]), //Season tage, //Day translator::get_month_name(month%12), //Month year, stunden, //"Hours" (Google) +#ifdef DEBUG minuten, //Minutes - ticks //HACK: Testing purposes only. + ticks +#else + minuten //Minutes +#endif ); break; // us style From d07632579c965937331ac1c9d177c1aa0ba7488e Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 28 Feb 2009 13:36:33 +0000 Subject: [PATCH 26/61] Hill climbing algorithm made more efficient. --- vehicle/simvehikel.cc | 87 ++++++++++++++++++++++++++++--------------- vehicle/simvehikel.h | 3 +- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 15b0deb9637..ac2d1fd2dcb 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -1395,47 +1395,72 @@ vehikel_t::calc_akt_speed(const grund_t *gr) //,const int h_alt, const int h_neu const hang_t::typ hang = gr->get_weg_hang(); if(hang!=hang_t::flach) { - hill.add_to_head(ribi_typ(hang)==fahrtrichtung); - uint8 hill_number; - uint8 hill_count = hill.get_count(); - for(hill_number = 0; hill_number < hill_count; hill_number ++) + if(ribi_typ(hang) == fahrtrichtung) { - if(!hill[hill_number]) + //Uphill + hill_up ++; + hill_down = 0; + + switch(hill_up) { + case 0: break; - } - } - switch(hill_number) - { - case 0: - //Must be downhill - current_friction -= 13; - break; + case 1: + current_friction += 18; + break; - case 1: - current_friction += 18; - break; + case 2: + current_friction += 25; + break; - case 2: - current_friction += 25; - break; + case 3: + current_friction += 32; + break; - case 3: - current_friction += 32; - break; + case 4: + current_friction += 38; + break; - case 4: - current_friction += 38; - break; + case 5: + default: + current_friction += 45; + break; - case 5: - current_friction += 45; - break; + }; + } - default: - break; - }; + else + { + //Downhill + hill_down ++; + hill_up = 0; + + switch(hill_down) + { + case 0: + break; + + case 1: + current_friction -= 10; + break; + + case 2: + current_friction -= 13; + break; + + case 3: + default: + current_friction -= 15; + }; + } + } + + else + { + //No hill at all - reset hill count. + hill_up = 0; + hill_down = 0; } if(ist_erstes) { //"Is the first" (Google) diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index 4073f4a9817..fe394f59717 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -209,7 +209,8 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t sint16 direction_steps; - fixed_list_tpl<bool, 5> hill; + uint8 hill_up; + uint8 hill_down; bool is_overweight; //#define debug_corners From 4fe9004816cc2f6e9f07fe47c93d776fd4c9f8c1 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 28 Feb 2009 13:48:56 +0000 Subject: [PATCH 27/61] Cornering algorithm made more efficient. --- vehicle/simvehikel.cc | 7 ++----- vehicle/simvehikel.h | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index ac2d1fd2dcb..28710d3c1b1 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -927,7 +927,6 @@ void vehikel_t::neue_fahrt(uint16 start_route_index, bool recalc) if(alte_fahrtrichtung != fahrtrichtung) { pre_corner_direction.clear(); - curve_history.clear(); } } @@ -1140,7 +1139,6 @@ vehikel_t::hop() } is_overweight = (sum_weight > weight_limit); - curve_history.add_to_tail(alte_fahrtrichtung != fahrtrichtung); if(alte_fahrtrichtung != fahrtrichtung) { pre_corner_direction.add_to_tail(get_direction_degrees(ribi_t::get_dir(alte_fahrtrichtung))); @@ -1167,8 +1165,7 @@ vehikel_t::hop() calc_akt_speed(gr); - sint8 trim_size = curve_history.get_count() - direction_steps; - curve_history.trim_from_head((trim_size >= 0) ? trim_size : 0); + sint8 trim_size = pre_corner_direction.get_count() - direction_steps; pre_corner_direction.trim_from_head((trim_size >= 0) ? trim_size : 0); } @@ -1264,7 +1261,7 @@ vehikel_t::calc_modified_speed_limit(const koord3d *position, ribi_t::ribi curre uint16 tmp; - for(int i = (curve_history.get_count() >= direction_steps) ? direction_steps - 1 : curve_history.get_count() - 1; i > 0; i --) + for(int i = (pre_corner_direction.get_count() >= direction_steps) ? direction_steps - 1 : pre_corner_direction.get_count() - 1; i > 0; i --) { tmp = vehikel_t::compare_directions(direction, pre_corner_direction.get_element(i)); if(tmp > direction_difference) diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index fe394f59717..4f3e1fe1dc2 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -204,7 +204,6 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t //@author: jamespetts // Cornering settings. - fixed_list_tpl<bool, 16> curve_history; fixed_list_tpl<sint16, 16> pre_corner_direction; sint16 direction_steps; From 54266ff994f8c9ed4d95028ae437e0b0328fe7bb Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 1 Mar 2009 17:03:03 +0000 Subject: [PATCH 28/61] Reversing code: vehicles now reverse without turning around if the rear vehicle has the new "can_lead_from_rear" attribute specified. Furthermore, the lead vehicle (usually a locomotive) will change ends but not flip if the parameter "bidirectional" is set in its .dat file. This does not yet have any effect on the simulation. --- besch/reader/vehicle_reader.cc | 16 ++- besch/vehikel_besch.h | 5 + besch/writer/vehicle_writer.cc | 18 +++- dataobj/ribi.h | 2 +- makeobj/makeobj.cc | 2 +- simconvoi.cc | 181 +++++++++++++++++++++++++++++---- simconvoi.h | 16 ++- simwerkz.cc | 5 +- tpl/array_tpl.h | 1 - tpl/fixed_list_tpl.h | 4 +- tpl/ordered_vector_tpl.h | 4 +- tpl/vector_tpl.h | 4 +- utils/log.cc | 1 + vehicle/simvehikel.cc | 78 ++++++++++++-- vehicle/simvehikel.h | 21 +++- 15 files changed, 302 insertions(+), 56 deletions(-) diff --git a/besch/reader/vehicle_reader.cc b/besch/reader/vehicle_reader.cc index ae0cc7d1f49..e147296ea9f 100644 --- a/besch/reader/vehicle_reader.cc +++ b/besch/reader/vehicle_reader.cc @@ -166,14 +166,16 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->vorgaenger = decode_uint8(p); //"Predecessors" (Google) besch->nachfolger = decode_uint8(p); //"Successor" (Google) besch->freight_image_type = decode_uint8(p); - if(node.size == 35) + if(node.size == 37) { - // Node size == 35 - extra features to be read. Version 8a. + // Node size == 37 - extra features to be read. Version 8a. // Backwards compatible with version 8 with this code. besch->is_tilting = decode_uint8(p); besch->way_constraints_permissive = decode_uint8(p); besch->way_constraints_prohibitive = decode_uint8(p); besch->catering_level = decode_uint8(p); + besch->bidirectional = decode_uint8(p); + besch->can_lead_from_rear = decode_uint8(p); } else { @@ -182,6 +184,8 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->way_constraints_permissive = 0; besch->way_constraints_prohibitive = 0; besch->catering_level = 0; + besch->bidirectional = false; + besch->can_lead_from_rear = false; } } else { @@ -247,6 +251,8 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->way_constraints_permissive = 0; besch->way_constraints_prohibitive = 0; besch->catering_level = 0; + besch->bidirectional = false; + besch->can_lead_from_rear = false; } @@ -271,7 +277,7 @@ DBG_MESSAGE("vehicle_reader_t::register_obj()","old sound %i to %i",old_id,besch "way=%d zuladung=%d preis=%d geschw=%d gewicht=%d leistung=%d " "betrieb=%d sound=%d vor=%d nach=%d " "date=%d/%d gear=%d engine_type=%d len=%d is_tilting=%d catering_level=%d " - "way_constraints_permissive=%d way_constraints_prohibitive%d", + "way_constraints_permissive=%d way_constraints_prohibitive%d bidirectional%d can_lead_from_rear%d", version, besch->typ, besch->zuladung, @@ -291,7 +297,9 @@ DBG_MESSAGE("vehicle_reader_t::register_obj()","old sound %i to %i",old_id,besch besch->is_tilting, besch->catering_level, besch->way_constraints_permissive, - besch->way_constraints_prohibitive); + besch->way_constraints_prohibitive, + besch->bidirectional, + besch->can_lead_from_rear); return besch; } diff --git a/besch/vehikel_besch.h b/besch/vehikel_besch.h index fcc29c5cc35..e5b34a3c39d 100644 --- a/besch/vehikel_besch.h +++ b/besch/vehikel_besch.h @@ -93,6 +93,9 @@ class vehikel_besch_t : public obj_besch_std_name_t { uint8 catering_level; //The level of catering. 0 for no catering. Higher numbers for better catering. + bool bidirectional; //Whether must always travel in one direction + bool can_lead_from_rear; + public: // since we have a second constructor @@ -235,6 +238,8 @@ class vehikel_besch_t : public obj_besch_std_name_t { uint16 get_betriebskosten() const { return betriebskosten; } uint16 get_betriebskosten(karte_t *welt) const; //Overloaded method - includes increase for obsolescence. sint8 get_sound() const { return sound; } + bool is_bidirectional() const { return bidirectional; } + bool get_can_lead_from_rear() const { return can_lead_from_rear; } /** diff --git a/besch/writer/vehicle_writer.cc b/besch/writer/vehicle_writer.cc index 51650c4dcd3..6e44449b623 100644 --- a/besch/writer/vehicle_writer.cc +++ b/besch/writer/vehicle_writer.cc @@ -76,7 +76,7 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj int i; uint8 uv8; - int total_len = 35; + int total_len = 37; // prissi: must be done here, since it may affect the length of the header! cstring_t sound_str = ltrim( obj.get("sound") ); @@ -398,10 +398,22 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj uint8 catering_level = (obj.get_int("catering_level", 0)); node.write_uint8(fp, catering_level, 34); + //Reverseing settings. + //@author: jamespetts + + // Bidirectional: vehicle can travel backwards without turning around. + // Function is disabled for road and air vehicles. + uint8 bidirectional = (obj.get_int("bidirectional", 0)); + node.write_uint8(fp, bidirectional, 35); + + // Can lead from rear: train can run backwards without turning around. + uint8 can_lead_from_rear = (obj.get_int("can_lead_from_rear", 0)); + node.write_uint8(fp, can_lead_from_rear, 36); + sint8 sound_str_len = sound_str.len(); if (sound_str_len > 0) { - node.write_sint8 (fp, sound_str_len, 35); - node.write_data_at(fp, sound_str, 36, sound_str_len); + node.write_sint8 (fp, sound_str_len, 37); + node.write_data_at(fp, sound_str, 38, sound_str_len); } node.write(fp); diff --git a/dataobj/ribi.h b/dataobj/ribi.h index 6a96983391d..eadfaa3706d 100644 --- a/dataobj/ribi.h +++ b/dataobj/ribi.h @@ -108,7 +108,7 @@ class ribi_t { * direction bits (ribi) can 16 Komb. represent. */ enum _ribi { - keine=0, //None + keine = 0, //None nord = 1, //North ost = 2, //East nordost = 3, //North-East diff --git a/makeobj/makeobj.cc b/makeobj/makeobj.cc index e1b46e740a6..a6bb2adfb62 100644 --- a/makeobj/makeobj.cc +++ b/makeobj/makeobj.cc @@ -33,7 +33,7 @@ int main(int argc, char* argv[]) argv++, argc--; } else { puts( - "\nMakeobj-Experimental, based on Makeobj version " MAKEOBJ_VERSION " for Simutrans-Experimental " VERSION_NUMBER " and higher\n" + "\nMakeobj-Experimental x, based on Makeobj version " MAKEOBJ_VERSION " for Simutrans-Experimental " VERSION_NUMBER " and higher\n" "Experimental version by James E. Petts, derived from Makeobj, \n (c) 2002-2006 V. Meyer , Hj. Malthaner and \n" "M. Pristovsek (markus@pristovsek.de). Files compiled with Makeobj-Experimental work with\n" "Simutrans-Experimental and standard Simutrans.\n" diff --git a/simconvoi.cc b/simconvoi.cc index a19908a6aa0..ad544b681ba 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -126,6 +126,8 @@ void convoi_t::reset() akt_speed_soll = 0; // Sollgeschwindigkeit akt_speed = 0; // momentane Geschwindigkeit sp_soll = 0; + + heaviest_vehicle = 0; } void convoi_t::init(karte_t *wl, spieler_t *sp) @@ -164,6 +166,9 @@ void convoi_t::init(karte_t *wl, spieler_t *sp) home_depot = koord3d::invalid; last_stop_pos = koord3d::invalid; + + reversable = false; + reversed = false; } @@ -174,7 +179,6 @@ convoi_t::convoi_t(karte_t* wl, loadsave_t* file) : fahr(max_vehicle, NULL) rdwr(file); } - convoi_t::convoi_t(spieler_t* sp) : fahr(max_vehicle, NULL) { self = convoihandle_t(this); @@ -351,7 +355,7 @@ DBG_MESSAGE("convoi_t::laden_abschliessen()","next_stop_index=%d", next_stop_ind for(unsigned i=0; i<anz_vehikel; i++) { vehikel_t* v = fahr[i]; - v->darf_rauchen(false); + v->darf_rauchen(false); //"Allowed to smoke" (Google) fahr[i]->fahre_basis( ((TILE_STEPS)*train_length)<<12 ); train_length -= v->get_besch()->get_length(); v->darf_rauchen(true); @@ -618,6 +622,9 @@ bool convoi_t::sync_step(long delta_t) case INITIAL: // jemand muß start aufrufen, damit der convoi von INITIAL // nach ROUTING_1 geht, das kann nicht automatisch gehen + + //someone must call start, so that convoi from INITIAL + //to ROUTING_1 goes, which cannot go automatically (Google) break; case FAHRPLANEINGABE: @@ -707,7 +714,7 @@ bool convoi_t::sync_step(long delta_t) } // now move the rest (so all vehikel are moving synchroniously) for(unsigned i=1; i<anz_vehikel; i++) { - fahr[i]->fahre_basis(sp_hat); + fahr[i]->fahre_basis(sp_hat); //"cycle basis" (Google) } // maybe we have been stopped be something => avoid wide jumps sp_soll = (sp_soll-sp_hat) & 0x0FFF; @@ -788,6 +795,7 @@ void convoi_t::suche_neue_route() */ void convoi_t::step() { + // moved check to here, as this will apply the same update // logic/constraints convois have for manual schedule manipulation if (line_update_pending.is_bound()) { @@ -1113,6 +1121,12 @@ void convoi_t::ziel_erreicht() if(dp) { // ok, we are entering a depot char buf[128]; + if(reversed) + { + //Always enter a depot facing forward + reversable = fahr[anz_vehikel - 1]->get_besch()->get_can_lead_from_rear(); + reverse_order(reversable); + } // we still book the money for the trip; however, the frieght will be lost calc_gewinn(); @@ -1154,6 +1168,7 @@ void convoi_t::ziel_erreicht() /** * Wartet bis Fahrzeug 0 freie Fahrt meldet + * Wait until the vehicle returns 0 free ride (Google) * @author Hj. Malthaner */ void convoi_t::warten_bis_weg_frei(int restart_speed) @@ -1164,6 +1179,7 @@ void convoi_t::warten_bis_weg_frei(int restart_speed) } if(restart_speed>=0) { // langsam anfahren + // "slow start" (Google) akt_speed = restart_speed; } } @@ -1177,7 +1193,8 @@ DBG_MESSAGE("convoi_t::add_vehikel()","at pos %i of %i totals.",anz_vehikel,max_ // extend array if requested (only needed for trains) if(anz_vehikel == max_vehicle) { DBG_MESSAGE("convoi_t::add_vehikel()","extend array_tpl to %i totals.",max_rail_vehicle); - fahr.resize(max_rail_vehicle, NULL); + //fahr.resize(max_rail_vehicle, NULL); + fahr.resize(max_rail_vehicle); } // now append if (anz_vehikel < fahr.get_size()) { @@ -1221,6 +1238,8 @@ DBG_MESSAGE("convoi_t::add_vehikel()","extend array_tpl to %i totals.",max_rail_ // der convoi hat jetzt ein neues ende set_erstes_letztes(); + heaviest_vehicle = calc_heaviest_vehicle(); + DBG_MESSAGE("convoi_t::add_vehikel()","now %i of %i total vehikels.",anz_vehikel,max_vehicle); return true; } @@ -1283,11 +1302,14 @@ convoi_t::remove_vehikel_bei(uint16 i) } } } + + heaviest_vehicle = calc_heaviest_vehicle(); + return v; } void -convoi_t::set_erstes_letztes() +convoi_t::set_erstes_letztes() //"set only last" (Google) { // anz_vehikel muss korrekt init sein // "anz vehicle must be correctly INIT" (Babelfish) @@ -1539,7 +1561,26 @@ convoi_t::vorfahren() //"move forward" (Babelfish) } else { // still leaving depot (steps_driven!=0) or going in other direction or misalignment? - if( steps_driven>0 || !can_go_alte_richtung() ) { + if( steps_driven>0 || !can_go_alte_richtung() ) + { + + //Convoy needs to reverse + //@author: jamespetts + if(!can_go_alte_richtung()) + { + switch(fahr[0]->get_waytype()) + { + case road_wt: + case air_wt: + //Only track based vehicles reverse. + break; + + default: + reversable = fahr[anz_vehikel - 1]->get_besch()->get_can_lead_from_rear(); + //reversable = true; + reverse_order(reversable); + } + } // since start may have been changed k0 = route.position_bei(0); @@ -1551,7 +1592,7 @@ convoi_t::vorfahren() //"move forward" (Babelfish) grund_t* gr = welt->lookup(v->get_pos()); if(gr) { v->mark_image_dirty( v->get_bild(), v->get_hoff() ); - v->verlasse_feld(); + v->verlasse_feld(); //"leave field" (Google) // eventually unreserve this schiene_t * sch0 = dynamic_cast<schiene_t *>( gr->get_weg(fahr[i]->get_waytype()) ); if(sch0) { @@ -1567,34 +1608,53 @@ convoi_t::vorfahren() //"move forward" (Babelfish) gr=welt->lookup(v->get_pos()); if(gr) { v->set_pos(k0); - v->betrete_feld(); + v->betrete_feld(); //"enter field" (Google) } } // move one train length to the start position ... int train_length = 0; - for(unsigned i=0; i<anz_vehikel-1u; i++) { + for(unsigned i=0; i<anz_vehikel-1u; i++) + { train_length += fahr[i]->get_besch()->get_length(); // this give the length in 1/TILE_STEPS of a full tile } // in north/west direction, we leave the vehicle away to start as much back as possible - ribi_t::ribi neue_richtung = fahr[0]->get_fahrtrichtung(); - if(neue_richtung==ribi_t::sued || neue_richtung==ribi_t::ost) { + ribi_t::ribi neue_richtung = fahr[0]->get_direction_of_travel(); + if(neue_richtung==ribi_t::sued || neue_richtung==ribi_t::ost) + { train_length += fahr[anz_vehikel-1]->get_besch()->get_length(); } - else { + else + { train_length += 1; } train_length = max(1,train_length); // now advance all convoi until it is completely on the track fahr[0]->set_erstes(false); // switches off signal checks ... - for(unsigned i=0; i<anz_vehikel; i++) { - vehikel_t* v = fahr[i]; + if(reversed && (reversable || fahr[0]->is_reversed())) + { + for(sint8 i = anz_vehikel - 1; i >= 0; i--) + { + vehikel_t* v = fahr[i]; + v->darf_rauchen(false); + fahr[i]->fahre_basis( ((TILE_STEPS)*train_length)<<12 ); //"fahre" = "go" (Google) + train_length += (v->get_besch()->get_length()); // this give the length in 1/TILE_STEPS of a full tile => all cars closely coupled! + v->darf_rauchen(true); + } + } - v->darf_rauchen(false); - fahr[i]->fahre_basis( ((TILE_STEPS)*train_length)<<12 ); - train_length -= v->get_besch()->get_length(); // this give the length in 1/TILE_STEPS of a full tile => all cars closely coupled! - v->darf_rauchen(true); + else + { + for(sint8 i = 0; i < anz_vehikel; i++) + { + vehikel_t* v = fahr[i]; + v->darf_rauchen(false); + fahr[i]->fahre_basis( ((TILE_STEPS)*train_length)<<12 ); //"fahre" = "go" (Google) + train_length -= (v->get_besch()->get_length()); // this give the length in 1/TILE_STEPS of a full tile => all cars closely coupled! + v->darf_rauchen(true); + } + } fahr[0]->set_erstes(true); } @@ -1630,6 +1690,63 @@ convoi_t::vorfahren() //"move forward" (Babelfish) INT_CHECK("simconvoi 711"); } +void +convoi_t::reverse_order(bool rev) +{ + // Code snippet obtained and adapted from: + // http://www.cprogramming.com/snippets/show.php?tip=15&count=30&page=0 + // by John Shao (public domain work) + + uint8 a = 0; + vehikel_t* reverse; + uint8 b = anz_vehikel; + if(rev) + { + fahr[0]->set_erstes(false); + } + else + { + b--; + a++; + } + + fahr[anz_vehikel - 1]->set_letztes(false); + + for(a; a<--b; a++) //increment a and decrement b until they meet each other + { + reverse = fahr[a]; //put what's in a into swap space + fahr[a] = fahr[b]; //put what's in b into a + fahr[b] = reverse; //put what's in the swap (a) into b + } + + if(!rev) + { + fahr[0]->set_erstes(true); + } + + fahr[anz_vehikel - 1]->set_letztes(true); + + if(reversed) + { + reversed = false; + for(uint8 i = 0; i < anz_vehikel; i ++) + { + fahr[i]->set_reversed(false); + } + } + else + { + reversed = true; + for(uint8 i = 0; i < anz_vehikel; i ++) + { + fahr[i]->set_reversed(true); + } + } +} + + + + void convoi_t::rdwr(loadsave_t *file) @@ -1959,9 +2076,11 @@ convoi_t::rdwr(loadsave_t *file) // TODO: Add load/save parameters for: // (1) origin; // (2) last transfer; - // (3) origin departure time; and - // (4) last transfer departure time. + // (3) origin departure time; + // (4) last transfer departure time; and + // (5) whether the convoy is in reverse formation. // Then, reversion the save game file format. + // no_load, withdraw if(file->get_version()<102001) { no_load = false; @@ -1971,6 +2090,11 @@ convoi_t::rdwr(loadsave_t *file) file->rdwr_bool( no_load, "" ); file->rdwr_bool( withdraw, "" ); } + + heaviest_vehicle = calc_heaviest_vehicle(); + + //HACK: Should be loaded from file. + reversed = false; } @@ -2023,7 +2147,7 @@ void convoi_t::set_sortby(uint8 sort_order) -//chaches the last info; resorts only when needed +//caches the last info; resorts only when needed void convoi_t::get_freight_info(cbuffer_t & buf) { if(freight_info_resort) { @@ -2966,3 +3090,18 @@ bool convoi_t::can_overtake(overtaker_t *other_overtaker, int other_speed, int s other_overtaker->set_tiles_overtaking( -1-(n_tiles/2) ); return true; } + +uint32 +convoi_t::calc_heaviest_vehicle() +{ + uint32 heaviest = 0; + for(uint8 i = 0; i < anz_vehikel; i ++) + { + uint32 tmp = fahr[i]->get_sum_weight(); + if(tmp > heaviest) + { + heaviest = tmp; + } + } + return heaviest; +} \ No newline at end of file diff --git a/simconvoi.h b/simconvoi.h index eab128021ee..b6446e2bab3 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -293,7 +293,7 @@ class convoi_t : public sync_steppable, public overtaker_t enum states state; - ribi_t::ribi alte_richtung; + ribi_t::ribi alte_richtung; //"Old direction" (Google) // The replacing vehicles, if any vector_tpl<const vehikel_besch_t *> replacing_vehicles; @@ -379,6 +379,14 @@ class convoi_t : public sync_steppable, public overtaker_t // Helper function: used in init and replacing void reset(); + // Reverses the order of the convoy. + // @author: jamespetts + void reverse_order(bool rev); + bool reversable; + bool reversed; + + uint32 heaviest_vehicle; + public: route_t* get_route() { return &route; } @@ -846,6 +854,12 @@ class convoi_t : public sync_steppable, public overtaker_t //Returns the maximum catering level of the category type given in the convoy. //@author: jamespetts uint8 get_catering_level(uint8 type) const; + + bool get_reversable() const { return reversable; } + bool is_reversed() const { return reversed; } + + uint32 calc_heaviest_vehicle(); + uint32 get_heaviest_vehicle() const { return heaviest_vehicle; } }; #endif diff --git a/simwerkz.cc b/simwerkz.cc index 8c194f23bba..dbbfa57d101 100644 --- a/simwerkz.cc +++ b/simwerkz.cc @@ -1320,11 +1320,12 @@ const weg_besch_t * wkz_wegebau_t::get_besch(bool remember) const char *wkz_wegebau_t::get_tooltip(spieler_t *sp) { const weg_besch_t *besch = get_besch(false); - sprintf(toolstr, "%s, %ld$ (%ld$), %dkm/h", + sprintf(toolstr, "%s, %ld$ (%ld$), %dkm/h, %dt", translator::translate(besch->get_name()), besch->get_preis()/100l, (besch->get_wartung()<<(sp->get_welt()->ticks_bits_per_tag-18))/100l, - besch->get_topspeed()); + besch->get_topspeed(), + besch->get_max_weight()); return toolstr; } diff --git a/tpl/array_tpl.h b/tpl/array_tpl.h index b463ec76fb0..6d1f94b338c 100644 --- a/tpl/array_tpl.h +++ b/tpl/array_tpl.h @@ -4,7 +4,6 @@ #include <typeinfo> #include "../simdebug.h" #include "../simtypes.h" - /** * A template class for bounds checked 1-dimesnional arrays. * This is kept as simple as possible. Does not use exceptions diff --git a/tpl/fixed_list_tpl.h b/tpl/fixed_list_tpl.h index 441563c39f8..847b6d47ed5 100644 --- a/tpl/fixed_list_tpl.h +++ b/tpl/fixed_list_tpl.h @@ -16,11 +16,11 @@ #define TPL_FIXED_LIST_H #ifndef ITERATE -#define ITERATE(collection,i) for(uint16 i = 0; i < collection.get_count(); i++) +#define ITERATE(collection,i) for(uint16 i = 0; i < (collection).get_count(); i++) #endif #ifndef ITERATE_PTR -#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < collection->get_count(); i++) +#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < (collection)->get_count(); i++) #endif #include <typeinfo> diff --git a/tpl/ordered_vector_tpl.h b/tpl/ordered_vector_tpl.h index 7e47aeeb0e8..71c255ddc6c 100644 --- a/tpl/ordered_vector_tpl.h +++ b/tpl/ordered_vector_tpl.h @@ -2,11 +2,11 @@ #define TPL_ORDERED_VECTOR_TPL_H #ifndef ITERATE -#define ITERATE(collection,i) for(uint16 i = 0; i < collection.get_count(); i++) +#define ITERATE(collection,i) for(uint16 i = 0; i < (collection).get_count(); i++) #endif #ifndef ITERATE_PTR -#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < collection->get_count(); i++) +#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < (collection)->get_count(); i++) #endif #include "../simtypes.h" diff --git a/tpl/vector_tpl.h b/tpl/vector_tpl.h index e3978dc795e..f733eba672f 100644 --- a/tpl/vector_tpl.h +++ b/tpl/vector_tpl.h @@ -2,11 +2,11 @@ #define TPL_VECTOR_H #ifndef ITERATE -#define ITERATE(collection,i) for(uint16 i = 0; i < collection.get_count(); i++) +#define ITERATE(collection,i) for(uint16 i = 0; i < (collection).get_count(); i++) #endif #ifndef ITERATE_PTR -#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < collection->get_count(); i++) +#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < (collection)->get_count(); i++) #endif #include <stdlib.h> diff --git a/utils/log.cc b/utils/log.cc index cbd88812d8c..35697cc2b7e 100644 --- a/utils/log.cc +++ b/utils/log.cc @@ -194,6 +194,7 @@ void log_t::fatal(const char *who, const char *format, ...) va_end(argptr); +#define MAKEOBJ #ifdef MAKEOBJ // no display available puts( buffer ); diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 28710d3c1b1..a538c946f52 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -196,7 +196,7 @@ void vehikel_basis_t::rotate90() void -vehikel_basis_t::verlasse_feld() +vehikel_basis_t::verlasse_feld() //"leave field" (Google) { // first: release crossing grund_t *gr = welt->lookup(get_pos()); @@ -967,6 +967,7 @@ vehikel_t::vehikel_t(koord3d pos, const vehikel_besch_t* besch, spieler_t* sp) : direction_steps = 4; local_bonus_supplement = 0; is_overweight = false; + reversed = false; } @@ -995,6 +996,7 @@ vehikel_t::vehikel_t(karte_t *welt) : direction_steps = 4; local_bonus_supplement = 0; is_overweight = false; + reversed = false; } @@ -1078,7 +1080,7 @@ void vehikel_t::betrete_feld() { if(ist_erstes && reliefkarte_t::is_visible) { - reliefkarte_t::get_karte()->set_relief_farbe(get_pos().get_2d(), VEHIKEL_KENN); + reliefkarte_t::get_karte()->set_relief_farbe(get_pos().get_2d(), VEHIKEL_KENN); //"Set relief colour" (Babelfish) } vehikel_basis_t::betrete_feld(); @@ -1120,7 +1122,7 @@ vehikel_t::hop() fahrtrichtung = calc_set_richtung( pos_prev.get_2d(), pos_next.get_2d() ); } } - calc_bild(); + calc_bild(); //Calculate image betrete_feld(); //"Enter field" (Google) grund_t *gr; @@ -1137,7 +1139,7 @@ vehikel_t::hop() { weight_limit = 1; } - is_overweight = (sum_weight > weight_limit); + is_overweight = (cnv->get_heaviest_vehicle() > weight_limit); if(alte_fahrtrichtung != fahrtrichtung) { @@ -1198,17 +1200,18 @@ vehikel_t::calc_modified_speed_limit(const koord3d *position, ribi_t::ribi curre uint32 overweight_speed_limit = base_limit; uint32 corner_speed_limit = base_limit; uint32 new_limit = base_limit; + uint32 heaviest_vehicle = cnv->get_heaviest_vehicle(); //Reduce speed for overweight vehicles - if(sum_weight > weight_limit) + if(heaviest_vehicle > weight_limit) { - if(sum_weight / weight_limit <= 1.1) + if(heaviest_vehicle / weight_limit <= 1.1) { //Overweight by up to 10% - reduce speed limit to a third. overweight_speed_limit = base_limit / 3; } - else if(sum_weight / weight_limit > 1.1) + else if(heaviest_vehicle / weight_limit > 1.1) { //Overweight by more than 10% - reduce speed limit by a factor of 10. overweight_speed_limit = base_limit / 10; @@ -1774,18 +1777,71 @@ void vehikel_t::calc_bild() //"Bild" = "picture" (Google) { image_id old_bild=get_bild(); - if (fracht.empty()) { - set_bild(besch->get_bild_nr(ribi_t::get_dir(get_fahrtrichtung()),NULL)); + if (fracht.empty()) + { + set_bild(besch->get_bild_nr(ribi_t::get_dir(get_direction_of_travel()),NULL)); } - else { - set_bild(besch->get_bild_nr(ribi_t::get_dir(get_fahrtrichtung()), fracht.front().get_besch())); + else + { + set_bild(besch->get_bild_nr(ribi_t::get_dir(get_direction_of_travel()), fracht.front().get_besch())); } if(old_bild!=get_bild()) { set_flag(ding_t::dirty); } } +ribi_t::ribi +vehikel_t::get_direction_of_travel() +{ + ribi_t::ribi dir = get_fahrtrichtung(); + if(reversed) + { + switch(dir) + { + case ribi_t::nord: + dir = ribi_t::sued; + break; + + case ribi_t::ost: + dir = ribi_t::west; + break; + + case ribi_t::nordost: + dir = ribi_t::suedwest; + break; + + case ribi_t::sued: + dir = ribi_t::nord; + break; + + case ribi_t::suedost: + dir = ribi_t::nordwest; + break; + + case ribi_t::west: + dir = ribi_t::ost; + break; + + case ribi_t::nordwest: + dir = ribi_t::suedost; + break; + case ribi_t::suedwest: + dir = ribi_t::nordost; + break; + }; + } + return dir; +} + +void +vehikel_t::set_reversed(bool value) +{ + if(besch->is_bidirectional() || (cnv != NULL && cnv->get_reversable())) + { + reversed = value; + } +} void vehikel_t::rdwr(loadsave_t *file) { diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index 4f3e1fe1dc2..17a4914aaf4 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -142,6 +142,7 @@ class vehikel_basis_t : public ding_t vehikel_basis_t(karte_t *welt); vehikel_basis_t(karte_t *welt, koord3d pos); + }; @@ -212,6 +213,10 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t uint8 hill_down; bool is_overweight; + // Whether this individual vehicle is reversed. + //@author: jamespetts + bool reversed; + //#define debug_corners #ifdef debug_corners @@ -227,8 +232,6 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t ribi_t::ribi alte_fahrtrichtung; - //sint16 pre_corner_direction[16]; - //uint16 target_speed[16]; //const koord3d *lookahead[16]; @@ -260,8 +263,8 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t */ koord3d pos_prev; - bool ist_erstes:1; // falls vehikel im convoi fährt, geben diese - bool ist_letztes:1; // flags auskunft über die position + bool ist_erstes:1; // falls vehikel im convoi fährt, geben diese ("appropriate vehicle in Convoi runs, these" - Google) + bool ist_letztes:1; // flags auskunft über die position ("flags provide information on the position" - Google) bool rauchen:1; bool check_for_finish:1; // true, if on the last tile @@ -453,7 +456,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t bool beladen(koord k, halthandle_t halt); // sets or querey begin and end of convois - void set_erstes(bool janein) {ist_erstes = janein;} + void set_erstes(bool janein) {ist_erstes = janein;} //janein = "yesno" (Google) bool is_first() {return ist_erstes;} void set_letztes(bool janein) {ist_letztes = janein;} @@ -487,6 +490,14 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t // this draws a tooltips for things stucked on depot order or lost virtual void display_after(int xpos, int ypos, bool dirty) const; + bool is_reversed() const { return reversed; } + void set_reversed(bool value); + + // Gets modified direction, used for drawing + // vehicles in reverse formation. + ribi_t::ribi get_direction_of_travel(); + + uint16 get_sum_weight() const { return sum_weight; } }; From 1f854553ab80175170a56d0e5c27628749e50908 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Wed, 4 Mar 2009 21:04:05 +0000 Subject: [PATCH 29/61] Completed system for reversing of railway trains (incl. trams, etc.). Now, whether the locomotive has to change ends and whether the locomotive needs to use a turntable affect the time that a train takes to change direction. This is customisable in simuconf.tab. --- besch/vehikel_besch.h | 10 ++++ besch/writer/way_writer.cc | 2 +- dataobj/einstellungen.cc | 5 ++ dataobj/einstellungen.h | 10 ++++ gui/components/gui_convoy_assembler.h | 3 +- gui/depot_frame.cc | 2 +- gui/goods_frame_t.cc | 6 ++- gui/goods_frame_t.h | 2 +- simconvoi.cc | 77 +++++++++++++++++++++++---- simintr.h | 5 +- 10 files changed, 106 insertions(+), 16 deletions(-) diff --git a/besch/vehikel_besch.h b/besch/vehikel_besch.h index e5b34a3c39d..9e0c757e34c 100644 --- a/besch/vehikel_besch.h +++ b/besch/vehikel_besch.h @@ -189,6 +189,11 @@ class vehikel_besch_t : public obj_besch_std_name_t { // liefert get_vorgaenger(0) == NULL, so bedeutet das entweder alle // Vorgänger sind erlaubt oder keine. Um das zu unterscheiden, sollte man // vorher hat_vorgaenger() befragen + + // Returns allowed predecessor. + // provides get_vorgaenger (0) == NULL, it means that either all + // predecessors are allowed or not. To distinguish, one should + // predict hat_vorgaenger () question (Google) const vehikel_besch_t *get_vorgaenger(int i) const { if(i < 0 || i >= vorgaenger) { @@ -219,6 +224,11 @@ class vehikel_besch_t : public obj_besch_std_name_t { // liefert get_nachfolger(0) == NULL, so bedeutet das entweder alle // Nachfolger sind erlaubt oder keine. Um das zu unterscheiden, sollte // man vorher hat_nachfolger() befragen + + //Returns the lawful successor. + //provides get_nachfolger (0) == NULL, it means that either all + // succeed or none are allowed. To distinguish, one should + // predict hat_nachfolger () question (Google) const vehikel_besch_t *get_nachfolger(int i) const { if(i < 0 || i >= nachfolger) { diff --git a/besch/writer/way_writer.cc b/besch/writer/way_writer.cc index 6f498d71d2c..7111bca1e0b 100644 --- a/besch/writer/way_writer.cc +++ b/besch/writer/way_writer.cc @@ -23,7 +23,7 @@ void way_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& obj) int ribi, hang; // Hajo: node size is 27 bytes - obj_node_t node(this, 27, &parent); + obj_node_t node(this, 28, &parent); // Hajo: Version needs high bit set as trigger -> this is required diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index 6864e1f56ef..7010d057321 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -706,6 +706,11 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s allow_bankruptsy = contents.get_int("allow_bankruptsy", 0); allow_purhcases_when_insolvent = contents.get_int("allow_purhcases_when_insolvent", 0); + //Reversing settings + unit_reverse_time = contents.get_int("unit_reverse_time", 1500); + hauled_reverse_time = contents.get_int("hauled_reverse_time", 2500); + turntable_reverse_time = contents.get_int("turntable_reverse_time", 4000); + /* * Selection of savegame format through inifile */ diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index 22c2ffc24cc..de6edcb723d 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -247,6 +247,12 @@ class einstellungen_t bool allow_bankruptsy; bool allow_purhcases_when_insolvent; + // Reversing settings + //@author: jamespetts + uint16 unit_reverse_time; + uint16 hauled_reverse_time; + uint16 turntable_reverse_time; + // true if active bool automaten[MAX_PLAYER_COUNT]; // 0 = emtpy, otherwise some vaule from simplay @@ -432,6 +438,10 @@ class einstellungen_t bool bankruptsy_allowed() const { return allow_bankruptsy; } bool insolvent_purchases_allowed() const { return allow_purhcases_when_insolvent; } + uint16 get_unit_reverse_time() const { return unit_reverse_time; } + uint16 get_hauled_reverse_time() const { return hauled_reverse_time; } + uint16 get_turntable_reverse_time() const { return turntable_reverse_time; } + sint16 get_river_number() const { return river_number; } void set_river_number( sint16 n ) { river_number=n; } sint16 get_min_river_length() const { return min_river_length; } diff --git a/gui/components/gui_convoy_assembler.h b/gui/components/gui_convoy_assembler.h index 4250e84ac67..75871d95dd3 100644 --- a/gui/components/gui_convoy_assembler.h +++ b/gui/components/gui_convoy_assembler.h @@ -214,7 +214,8 @@ class gui_convoy_assembler_t : inline void set_convoy_tabs_skip(int skip) {convoy_tabs_skip=skip;} inline int get_convoy_clist_width() const {return vehicles.get_count() * (grid.x - grid_dx) + 2 * gui_image_list_t::BORDER;} - + //inline int get_convoy_clist_width() const {return depot_frame->get_depot()->get_max_convoi_length() * (grid.x - grid_dx) + 2 * gui_image_list_t::BORDER;} + inline int get_convoy_image_width() const {return get_convoy_clist_width() + placement_dx;} inline int get_convoy_image_height() const {return grid.y + 2 * gui_image_list_t::BORDER;} diff --git a/gui/depot_frame.cc b/gui/depot_frame.cc index 825ef78d61e..e2d67a2f245 100644 --- a/gui/depot_frame.cc +++ b/gui/depot_frame.cc @@ -196,7 +196,7 @@ void depot_frame_t::layout(koord *gr) * [Start][Schedule][Destroy][Sell] * [new Route][change Route][delete Route] */ - int ABUTTON_WIDTH = 96; + int ABUTTON_WIDTH = 128; int ABUTTON_HEIGHT = 14; int ACTIONS_WIDTH = 4 * ABUTTON_WIDTH; int ACTIONS_HEIGHT = ABUTTON_HEIGHT + ABUTTON_HEIGHT; // @author hsiegeln: added "+ ABUTTON_HEIGHT" diff --git a/gui/goods_frame_t.cc b/gui/goods_frame_t.cc index d5ba322671d..9e7c95515f5 100644 --- a/gui/goods_frame_t.cc +++ b/gui/goods_frame_t.cc @@ -42,7 +42,8 @@ const char *goods_frame_t::sort_text[SORT_MODES] = { "gl_btn_unsort", "gl_btn_sort_name", "gl_btn_sort_revenue", - "gl_btn_sort_bonus" + "gl_btn_sort_bonus", + "gl_btn_sort_catg" }; @@ -134,6 +135,9 @@ int goods_frame_t::compare_goods(const void *p1, const void *p2) case 3: // sort by speed bonus order = w2->get_speed_bonus()-w1->get_speed_bonus(); break; + case 4: // sort by catg_index + order = w1->get_catg()-w2->get_catg(); + break; default: // sort by name order = strcmp(translator::translate(w1->get_name()), translator::translate(w2->get_name())); break; diff --git a/gui/goods_frame_t.h b/gui/goods_frame_t.h index a6a104c88de..677db286056 100644 --- a/gui/goods_frame_t.h +++ b/gui/goods_frame_t.h @@ -24,7 +24,7 @@ class karte_t; class goods_frame_t : public gui_frame_t, private action_listener_t { private: - enum sort_mode_t { unsortiert=0, nach_name=1, nach_gewinn=2, nach_bonus=3, SORT_MODES=4 }; + enum sort_mode_t { unsortiert=0, nach_name=1, nach_gewinn=2, nach_bonus=3, nach_catg=4, SORT_MODES=5 }; static const char *sort_text[SORT_MODES]; // static, so we remember the last settings diff --git a/simconvoi.cc b/simconvoi.cc index ad544b681ba..b6e3a1cfefc 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -680,9 +680,16 @@ bool convoi_t::sync_step(long delta_t) } // until all are moving or something went wrong (sp_hat==0) if(sp_hat==0 || v_nr==anz_vehikel) { - steps_driven = -1; - state = DRIVING; - return true; + // Attempted fix of depot squashing problem: + // but causes problems with signals. + //if (v_nr==anz_vehikel) { + steps_driven = -1; + //} + //else { + //} + + state = DRIVING; + return true; } // now only the right numbers for(int i=1; i<=v_nr; i++) { @@ -875,8 +882,8 @@ void convoi_t::step() } // Hajo: now calculate a new route drive_to(v->get_pos(), fpl->get_current_eintrag().pos); - if(!route.empty()) { - vorfahren(); //"Front" (Google) + if(!route.empty()) { + vorfahren(); //"Drive" } else { state = NO_ROUTE; @@ -1518,6 +1525,8 @@ convoi_t::vorfahren() //"move forward" (Babelfish) sp_soll = 0; set_tiles_overtaking( 0 ); + uint16 reverse_delay = 0; + set_akt_speed_soll( vehikel_t::SPEED_UNLIMITED ); koord3d k0 = route.position_bei(0); @@ -1572,12 +1581,36 @@ convoi_t::vorfahren() //"move forward" (Babelfish) { case road_wt: case air_wt: - //Only track based vehicles reverse. + //Road vehicles and aircraft do not need to change direction + //Canal barges *may* change direction, so water is omitted. break; default: - reversable = fahr[anz_vehikel - 1]->get_besch()->get_can_lead_from_rear(); - //reversable = true; + if(reversed) + { + reversable = fahr[0]->get_besch()->get_can_lead_from_rear(); + } + else + { + reversable = fahr[anz_vehikel - 1]->get_besch()->get_can_lead_from_rear(); + } + + if(reversable) + { + //Multiple unit or similar: quick reverse + reverse_delay = welt->get_einstellungen()->get_unit_reverse_time(); + } + else if(fahr[0]->get_besch()->is_bidirectional()) + { + //Loco hauled, no turntable. + reverse_delay = welt->get_einstellungen()->get_hauled_reverse_time(); + } + else + { + //Locomotive needs turntable: slow reverse + reverse_delay = welt->get_einstellungen()->get_turntable_reverse_time(); + } + reverse_order(reversable); } } @@ -1634,6 +1667,8 @@ convoi_t::vorfahren() //"move forward" (Babelfish) fahr[0]->set_erstes(false); // switches off signal checks ... if(reversed && (reversable || fahr[0]->is_reversed())) { + //train_length -= fahr[0]->get_besch()->get_length(); + train_length = 0; for(sint8 i = anz_vehikel - 1; i >= 0; i--) { vehikel_t* v = fahr[i]; @@ -1646,6 +1681,13 @@ convoi_t::vorfahren() //"move forward" (Babelfish) else { + //if(!reversable && fahr[0]->get_besch()->is_bidirectional()) + //{ + // //This can sometimes relieve excess setting back on reversing. + // //Unfortunately, it seems to produce bizarre results on occasion. + // train_length -= (fahr[0]->get_besch()->get_length()) / 2; + // train_length = train_length > 0 ? train_length : 0; + //} for(sint8 i = 0; i < anz_vehikel; i++) { vehikel_t* v = fahr[i]; @@ -1667,7 +1709,8 @@ convoi_t::vorfahren() //"move forward" (Babelfish) if(haltestelle_t::get_halt(welt,k0).is_bound()) { fahr[0]->play_sound(); } - wait_lock = 0; + //wait_lock = 0; + wait_lock = reverse_delay; state = DRIVING; } } @@ -1700,14 +1743,28 @@ convoi_t::reverse_order(bool rev) uint8 a = 0; vehikel_t* reverse; uint8 b = anz_vehikel; + if(rev) { fahr[0]->set_erstes(false); } else { - b--; + if(!fahr[anz_vehikel - 1]->get_besch()->is_bidirectional()) + { + //Do not change the order at all if the last vehicle is not bidirectional + return; + } + a++; + a += fahr[0]->get_besch()->get_nachfolger_count(); + for(uint8 i = 1; i < anz_vehikel; i++) + { + if(fahr[i]->get_besch()->get_leistung() > 0) + { + a++; + } + } } fahr[anz_vehikel - 1]->set_letztes(false); diff --git a/simintr.h b/simintr.h index cf4cb97b0c0..950cd70b1e8 100644 --- a/simintr.h +++ b/simintr.h @@ -43,9 +43,12 @@ void interrupt_check(); void interrupt_check(const char* caller_info); // standard version +#ifdef NDEBUG #define INT_CHECK(info) interrupt_check(); +#else // debug version -// #define INT_CHECK(info) interrupt_check(info); + #define INT_CHECK(info) interrupt_check(info); +#endif #endif From a355b84f47b1ac95ca146a00fe0d2d53638b3690 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Fri, 6 Mar 2009 00:00:20 +0000 Subject: [PATCH 30/61] New versioning system for .pak files that use Simutrans-Experimental features (now not backwards compatible with Simutrans-Standard). Also, some optimisation of MSVC++ vcproj files, including: makeobj now compiles as a release build. --- Simutrans-Experimental.vcproj | 7 +++- besch/objversion.h | 5 ++- besch/reader/bridge_reader.cc | 52 ++++++++++++++++-------- besch/reader/tunnel_reader.cc | 50 ++++++++++++++++------- besch/reader/vehicle_reader.cc | 63 ++++++++++++++++++----------- besch/reader/vehicle_reader.h | 1 + besch/reader/way_obj_reader.cc | 47 +++++++++++++++------ besch/reader/way_reader.cc | 49 ++++++++++++++-------- besch/vehikel_besch.h | 2 +- besch/writer/bridge_writer.cc | 10 +++++ besch/writer/tunnel_writer.cc | 10 +++++ besch/writer/vehicle_writer.cc | 10 +++++ besch/writer/way_obj_writer.cc | 10 +++++ besch/writer/way_writer.cc | 10 +++++ dataobj/einstellungen.cc | 2 +- makeobj/Makeobj-experimental.vcproj | 12 +++--- makeobj/makeobj.cc | 5 +-- 17 files changed, 248 insertions(+), 97 deletions(-) diff --git a/Simutrans-Experimental.vcproj b/Simutrans-Experimental.vcproj index 9afd7ccf057..9576d9f78bf 100644 --- a/Simutrans-Experimental.vcproj +++ b/Simutrans-Experimental.vcproj @@ -73,6 +73,7 @@ IgnoreDefaultLibraryNames="libcmt.lib" GenerateDebugInformation="true" SubSystem="2" + OptimizeForWindows98="0" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" @@ -124,6 +125,7 @@ /> <Tool Name="VCCLCompilerTool" + InlineFunctionExpansion="2" AdditionalIncludeDirectories=""G:\Projects\SDL-1.2.10\include";"G:\Program Files\PlatformSDK\Include";G:\Projects\zlib\include" PreprocessorDefinitions="ZLIB_WINAPI;LITTLE_ENDIAN;STEPS16;USE_C;WIN32;NDEBUG" RuntimeLibrary="2" @@ -146,12 +148,13 @@ Name="VCLinkerTool" AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winmm.lib zlibstat.lib advapi32.lib $(NOINHERIT)" LinkIncremental="1" - AdditionalLibraryDirectories=""G:\Program Files\PlatformSDK\Lib";G:\Projects\zlib\lib" + AdditionalLibraryDirectories=""c:\Program Files\PlatformSDK\Lib";c:\Projects\zlib\lib" IgnoreDefaultLibraryNames="libcmt.lib" - GenerateDebugInformation="true" + GenerateDebugInformation="false" SubSystem="2" OptimizeReferences="2" EnableCOMDATFolding="2" + OptimizeForWindows98="0" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" diff --git a/besch/objversion.h b/besch/objversion.h index 454e0b276dd..783761d9c9f 100644 --- a/besch/objversion.h +++ b/besch/objversion.h @@ -5,6 +5,9 @@ #define COMPILER_VERSION "0.1.2exp" #define COMPILER_VERSION_CODE (0 * 1000000 + 1 * 1000 + 1) +//The experimental subversion +#define EXP_VER 0x4000 + /* * obj_type value are stored inside the pak-files. Values are choosen to make * them somewhat readable (up to 4 uppercase letters describing the type). @@ -31,7 +34,7 @@ enum obj_type obj_fsupplier = C4ID('F','S','U','P'), obj_good = C4ID('G','O','O','D'), obj_ground = C4ID('G','R','N','D'), - obj_groundobj = C4ID('G','O','B','J'), + obj_groundobj = C4ID('G','O','B','J'), obj_image = C4ID('I','M','G', 0 ), obj_imagelist = C4ID('I','M','G','1'), obj_imagelist2d = C4ID('I','M','G','2'), diff --git a/besch/reader/bridge_reader.cc b/besch/reader/bridge_reader.cc index c4c34717045..53e248dc054 100644 --- a/besch/reader/bridge_reader.cc +++ b/besch/reader/bridge_reader.cc @@ -40,7 +40,24 @@ obj_besch_t * bridge_reader_t::read_node(FILE *fp, obj_node_info_t &node) // But we know, the higher most bit was always cleared. const uint16 v = decode_uint16(p); - const int version = v & 0x8000 ? v & 0x7FFF : 0; + int version = v & 0x8000 ? v & 0x7FFF : 0; + + // Whether the read file is from Simutrans-Experimental + //@author: jamespetts + + const bool experimental = version > 0 ? v & EXP_VER : false; + uint16 experimental_version = 0; + if(experimental) + { + // Experimental version to start at 0 and increment. + version = version & EXP_VER ? version & 0x3FFF : 0; + while(version > 0x100) + { + version -= 0x100; + experimental_version ++; + } + experimental_version -=1; + } // some defaults besch->maintenance = 800; @@ -140,24 +157,20 @@ obj_besch_t * bridge_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->pillars_asymmetric = (decode_uint8(p)!=0); besch->max_height = decode_uint8(p); besch->number_seasons = decode_uint8(p); - if(node.size == 28) - { - // 28 byte node = version 8a. New features, - // (weight limits and way constraints), but - // backwards compatible with version 8. - - besch->max_weight = decode_uint32(p); - besch->way_constraints_permissive = decode_uint8(p); - besch->way_constraints_prohibitive = decode_uint8(p); - } - else + if(experimental) { - besch->max_weight = 999; - besch->way_constraints_permissive = 0; - besch->way_constraints_prohibitive = 0; + if(experimental_version == 0) + { + besch->max_weight = decode_uint32(p); + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + } + else + { + dbg->fatal( "bridge_reader_t::read_node()","Incompatible pak file version for Simutrans-E, number %i", experimental_version ); + } } - } else { // old node, version 0 @@ -170,6 +183,13 @@ obj_besch_t * bridge_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->way_constraints_prohibitive = 0; } + if(!experimental) + { + besch->max_weight = 999; + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + } + // pillars cannot be heigher than this to avoid drawing errors if(besch->pillars_every>0 && besch->max_height==0) { besch->max_height = 7; diff --git a/besch/reader/tunnel_reader.cc b/besch/reader/tunnel_reader.cc index aabcc3c289d..ecc1db90ae4 100644 --- a/besch/reader/tunnel_reader.cc +++ b/besch/reader/tunnel_reader.cc @@ -27,7 +27,6 @@ tunnel_reader_t::successfully_loaded() const } - obj_besch_t * tunnel_reader_t::read_node(FILE *fp, obj_node_info_t &node) { tunnel_besch_t *besch = new tunnel_besch_t(); @@ -43,7 +42,24 @@ obj_besch_t * tunnel_reader_t::read_node(FILE *fp, obj_node_info_t &node) char * p = besch_buf; const uint16 v = decode_uint16(p); - const int version = v & 0x8000 ? v & 0x7FFF : 0; + int version = v & 0x8000 ? v & 0x7FFF : 0; + + // Whether the read file is from Simutrans-Experimental + //@author: jamespetts + + const bool experimental = version > 0 ? v & EXP_VER : false; + uint16 experimental_version = 0; + if(experimental) + { + // Experimental version to start at 0 and increment. + version = version & EXP_VER ? version & 0x3FFF : 0; + while(version > 0x100) + { + version -= 0x100; + experimental_version ++; + } + experimental_version -=1; + } if(version == 2) { // versioned node, version 2 - snow image support @@ -54,19 +70,18 @@ obj_besch_t * tunnel_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->intro_date = decode_uint16(p); besch->obsolete_date = decode_uint16(p); besch->number_seasons = decode_uint8(p); - if(node.size == 26) - { - // Node size == 26 - extra features to be read. Version 2a. - // Backwards compatible with version 2 with this code. - besch->max_weight = decode_uint32(p); - besch->way_constraints_permissive = decode_uint8(p); - besch->way_constraints_prohibitive = decode_uint8(p); - } - else + if(experimental) { - besch->max_weight = 999; - besch->way_constraints_permissive = 0; - besch->way_constraints_prohibitive = 0; + if(experimental_version == 0) + { + besch->max_weight = decode_uint32(p); + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + } + else + { + dbg->fatal( "tunnel_reader_t::read_node()","Incompatible pak file version for Simutrans-E, number %i", experimental_version ); + } } } else if(version == 1) { @@ -88,6 +103,13 @@ obj_besch_t * tunnel_reader_t::read_node(FILE *fp, obj_node_info_t &node) dbg->fatal("tunnel_reader_t::read_node()","illegal version %d",version); } + if(!experimental) + { + besch->max_weight = 999; + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + } + DBG_DEBUG("bridge_reader_t::read_node()", "version=%d waytype=%d price=%d topspeed=%d, intro_year=%d, max_weight%d", version, besch->wegtyp, besch->preis, besch->topspeed, besch->intro_date/12, besch->max_weight); diff --git a/besch/reader/vehicle_reader.cc b/besch/reader/vehicle_reader.cc index e147296ea9f..0bfa1cb0f4c 100644 --- a/besch/reader/vehicle_reader.cc +++ b/besch/reader/vehicle_reader.cc @@ -10,8 +10,6 @@ #include "vehicle_reader.h" #include "../obj_node_info.h" - - void vehicle_reader_t::register_obj(obj_besch_t *&data) { @@ -21,7 +19,6 @@ vehicle_reader_t::register_obj(obj_besch_t *&data) } - bool vehicle_reader_t::successfully_loaded() const { @@ -45,7 +42,24 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) // But we know, the higher most bit was always cleared. const uint16 v = decode_uint16(p); - const int version = v & 0x8000 ? v & 0x7FFF : 0; + int version = v & 0x8000 ? v & 0x7FFF : 0; + + // Whether the read file is from Simutrans-Experimental + //@author: jamespetts + + const bool experimental = version > 0 ? v & EXP_VER : false; + uint16 experimental_version = 0; + if(experimental) + { + // Experimental version to start at 0 and increment. + version = version & EXP_VER ? version & 0x3FFF : 0; + while(version > 0x100) + { + version -= 0x100; + experimental_version ++; + } + experimental_version -=1; + } if(version == 1) { // Versioned node, version 1 @@ -166,26 +180,21 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->vorgaenger = decode_uint8(p); //"Predecessors" (Google) besch->nachfolger = decode_uint8(p); //"Successor" (Google) besch->freight_image_type = decode_uint8(p); - if(node.size == 37) - { - // Node size == 37 - extra features to be read. Version 8a. - // Backwards compatible with version 8 with this code. - besch->is_tilting = decode_uint8(p); - besch->way_constraints_permissive = decode_uint8(p); - besch->way_constraints_prohibitive = decode_uint8(p); - besch->catering_level = decode_uint8(p); - besch->bidirectional = decode_uint8(p); - besch->can_lead_from_rear = decode_uint8(p); - } - else + if(experimental) { - //Standard version 8: default values for new items. - besch->is_tilting = 0; - besch->way_constraints_permissive = 0; - besch->way_constraints_prohibitive = 0; - besch->catering_level = 0; - besch->bidirectional = false; - besch->can_lead_from_rear = false; + if(experimental_version == 0) + { + besch->is_tilting = decode_uint8(p); + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + besch->catering_level = decode_uint8(p); + besch->bidirectional = decode_uint8(p); + besch->can_lead_from_rear = decode_uint8(p); + } + else + { + dbg->fatal( "vehicle_reader_t::read_node()","Incompatible pak file version for Simutrans-E, number %i", experimental_version ); + } } } else { @@ -245,8 +254,14 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->len *= TILE_STEPS/16; // before version 8 vehicles could only have one freight image in each direction - if(version<8) { + if(version<8) + { besch->freight_image_type = 0; + } + + if(!experimental) + { + // Default values for items not in the standard vehicle format. besch->is_tilting = 0; besch->way_constraints_permissive = 0; besch->way_constraints_prohibitive = 0; diff --git a/besch/reader/vehicle_reader.h b/besch/reader/vehicle_reader.h index 0eda7c49bc0..44aa76f02d5 100644 --- a/besch/reader/vehicle_reader.h +++ b/besch/reader/vehicle_reader.h @@ -8,6 +8,7 @@ class vehicle_reader_t : public obj_reader_t { static vehicle_reader_t the_instance; vehicle_reader_t() { register_reader(); } + protected: virtual void register_obj(obj_besch_t *&data); virtual bool successfully_loaded() const; diff --git a/besch/reader/way_obj_reader.cc b/besch/reader/way_obj_reader.cc index 8da737b74c3..29a891b4ed1 100644 --- a/besch/reader/way_obj_reader.cc +++ b/besch/reader/way_obj_reader.cc @@ -37,7 +37,24 @@ obj_besch_t * way_obj_reader_t::read_node(FILE *fp, obj_node_info_t &node) // Hajo: old versions of PAK files have no version stamp. // But we know, the higher most bit was always cleared. const uint16 v = decode_uint16(p); - const uint16 version = v & 0x7FFF; + uint16 version = v & 0x7FFF; + + // Whether the read file is from Simutrans-Experimental + //@author: jamespetts + + const bool experimental = version > 0 ? v & EXP_VER : false; + uint16 experimental_version = 0; + if(experimental) + { + // Experimental version to start at 0 and increment. + version = version & EXP_VER ? version & 0x3FFF : 0; + while(version > 0x100) + { + version -= 0x100; + experimental_version ++; + } + experimental_version -=1; + } if(version==1) { // Versioned node, version 3 @@ -48,23 +65,29 @@ obj_besch_t * way_obj_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->obsolete_date = decode_uint16(p); besch->wtyp = decode_uint8(p); besch->own_wtyp = decode_uint8(p); - if(node.size == 22) + if(experimental) { - // 22 byte node = version 1a. New features, - // (weight limits and way constraints), but - // backwards compatible with version 1. - besch->way_constraints_permissive = decode_uint8(p); - besch->way_constraints_prohibitive = decode_uint8(p); - } - else - { - besch->way_constraints_permissive = 0; - besch->way_constraints_prohibitive = 0; + if(experimental_version == 0) + { + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + } + else + { + dbg->fatal( "way_obj_reader_t::read_node()","Incompatible pak file version for Simutrans-E, number %i", experimental_version ); + } } } else { dbg->fatal("way_obj_reader_t::read_node()","Invalid version %d", version); } + + if(!experimental) + { + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + } + DBG_DEBUG("way_obj_reader_t::read_node()", "version=%d price=%d maintenance=%d topspeed=%d max_weight=%d " "wtype=%d styp=%d intro_year=%i", diff --git a/besch/reader/way_reader.cc b/besch/reader/way_reader.cc index 9b1ce8824f8..cc3023eb89e 100644 --- a/besch/reader/way_reader.cc +++ b/besch/reader/way_reader.cc @@ -59,6 +59,28 @@ obj_besch_t * way_reader_t::read_node(FILE *fp, obj_node_info_t &node) const uint16 v = decode_uint16(p); version = v & 0x7FFF; + // Whether the read file is from Simutrans-Experimental + //@author: jamespetts + + const bool experimental = version > 0 ? v & EXP_VER : false; + uint16 experimental_version = 0; + if(experimental) + { + // Experimental version to start at 0 and increment. + version = version & EXP_VER ? version & 0x3FFF : 0; + while(version > 0x100) + { + version -= 0x100; + experimental_version ++; + } + experimental_version -=1; + } + else + { + besch->way_constraints_permissive = 0; + besch->way_constraints_prohibitive = 0; + } + if(version==4) { // Versioned node, version 4 besch->price = decode_uint32(p); @@ -71,18 +93,17 @@ obj_besch_t * way_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->styp = decode_uint8(p); besch->draw_as_ding = decode_uint8(p); besch->number_seasons = decode_sint8(p); - if(node.size == 27) + if(experimental) { - //If node.size is 27, we have version 4a. - //Backwards compatible with version 4, but - //has extra functions (way constraints). - besch->way_constraints_permissive = decode_uint8(p); - besch->way_constraints_prohibitive = decode_uint8(p); - } - else - { - besch->way_constraints_permissive = 0; - besch->way_constraints_prohibitive = 0; + if(experimental_version == 0) + { + besch->way_constraints_permissive = decode_uint8(p); + besch->way_constraints_prohibitive = decode_uint8(p); + } + else + { + dbg->fatal( "way_reader_t::read_node()","Incompatible pak file version for Simutrans-E, number %i", experimental_version ); + } } } @@ -144,12 +165,6 @@ obj_besch_t * way_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->wtyp = powerline_wt; } - if(version < 4) - { - besch->way_constraints_permissive = 0; - besch->way_constraints_prohibitive = 0; - } - if(version<=2 && besch->wtyp==air_wt && besch->topspeed>=250) { // runway! besch->styp = 1; diff --git a/besch/vehikel_besch.h b/besch/vehikel_besch.h index 9e0c757e34c..46818e1c18c 100644 --- a/besch/vehikel_besch.h +++ b/besch/vehikel_besch.h @@ -197,7 +197,7 @@ class vehikel_besch_t : public obj_besch_std_name_t { const vehikel_besch_t *get_vorgaenger(int i) const { if(i < 0 || i >= vorgaenger) { - return 0; + return NULL; } return static_cast<const vehikel_besch_t *>(get_child(6 + i)); } diff --git a/besch/writer/bridge_writer.cc b/besch/writer/bridge_writer.cc index 98d9bf36dea..d7aec5bd507 100644 --- a/besch/writer/bridge_writer.cc +++ b/besch/writer/bridge_writer.cc @@ -72,6 +72,16 @@ void bridge_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& o // Hajo: Version needs high bit set as trigger -> this is required // as marker because formerly nodes were unversionend uint16 version = 0x8008; + + // This is the overlay flag for Simutrans-Experimental + // This sets the *second* highest bit to 1. + version |= EXP_VER; + + // Finally, this is the experimental version number. This is *added* + // to the standard version number, to be subtracted again when read. + // Start at 0x100 and increment in hundreds (hex). + version += 0x100; + node.write_uint16(outfp, version, 0); node.write_uint16(outfp, topspeed, 2); node.write_uint32(outfp, preis, 4); diff --git a/besch/writer/tunnel_writer.cc b/besch/writer/tunnel_writer.cc index da352e781f8..85376cb4e8b 100644 --- a/besch/writer/tunnel_writer.cc +++ b/besch/writer/tunnel_writer.cc @@ -66,6 +66,16 @@ void tunnel_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj) // Version uses always high bit set as trigger // version 2: snow images uint16 version = 0x8002; + + // This is the overlay flag for Simutrans-Experimental + // This sets the *second* highest bit to 1. + version |= EXP_VER; + + // Finally, this is the experimental version number. This is *added* + // to the standard version number, to be subtracted again when read. + // Start at 0x100 and increment in hundreds (hex). + version += 0x100; + node.write_uint16(fp, version, 0); node.write_uint32(fp, topspeed, 2); node.write_uint32(fp, preis, 6); diff --git a/besch/writer/vehicle_writer.cc b/besch/writer/vehicle_writer.cc index 6e44449b623..969538e36d6 100644 --- a/besch/writer/vehicle_writer.cc +++ b/besch/writer/vehicle_writer.cc @@ -106,6 +106,16 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj // Hajo: Version needs high bit set as trigger -> this is required // as marker because formerly nodes were unversionend uint16 version = 0x8008; + + // This is the overlay flag for Simutrans-Experimental + // This sets the *second* highest bit to 1. + version |= EXP_VER; + + // Finally, this is the experimental version number. This is *added* + // to the standard version number, to be subtracted again when read. + // Start at 0x100 and increment in hundreds (hex). + version += 0x100; + node.write_uint16(fp, version, 0); diff --git a/besch/writer/way_obj_writer.cc b/besch/writer/way_obj_writer.cc index 5218f230f35..6bd5c1149e5 100644 --- a/besch/writer/way_obj_writer.cc +++ b/besch/writer/way_obj_writer.cc @@ -28,6 +28,16 @@ void way_obj_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& // Hajo: Version needs high bit set as trigger -> this is required // as marker because formerly nodes were unversionend uint16 version = 0x8001; + + // This is the overlay flag for Simutrans-Experimental + // This sets the *second* highest bit to 1. + version |= EXP_VER; + + // Finally, this is the experimental version number. This is *added* + // to the standard version number, to be subtracted again when read. + // Start at 0x100 and increment in hundreds (hex). + version += 0x100; + uint32 price = obj.get_int("cost", 100); uint32 maintenance = obj.get_int("maintenance", 100); uint32 topspeed = obj.get_int("topspeed", 999); diff --git a/besch/writer/way_writer.cc b/besch/writer/way_writer.cc index 7111bca1e0b..a01348f5409 100644 --- a/besch/writer/way_writer.cc +++ b/besch/writer/way_writer.cc @@ -29,6 +29,16 @@ void way_writer_t::write_obj(FILE* outfp, obj_node_t& parent, tabfileobj_t& obj) // Hajo: Version needs high bit set as trigger -> this is required // as marker because formerly nodes were unversionend uint16 version = 0x8004; + + // This is the overlay flag for Simutrans-Experimental + // This sets the *second* highest bit to 1. + version |= EXP_VER; + + // Finally, this is the experimental version number. This is *added* + // to the standard version number, to be subtracted again when read. + // Start at 0x100 and increment in hundreds (hex). + version += 0x100; + uint32 price = obj.get_int("cost", 100); uint32 maintenance = obj.get_int("maintenance", 100); uint32 topspeed = obj.get_int("topspeed", 999); diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index 82ca589b4f6..215962fa126 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -197,7 +197,7 @@ einstellungen_t::einstellungen_t() : // this will pay for distance to next change station - pay_for_total_distance = TO_PREVIOUS; + pay_for_total_distance = 0; avoid_overcrowding = true; } diff --git a/makeobj/Makeobj-experimental.vcproj b/makeobj/Makeobj-experimental.vcproj index 2b6ebd7d9b6..16d90496e70 100644 --- a/makeobj/Makeobj-experimental.vcproj +++ b/makeobj/Makeobj-experimental.vcproj @@ -18,8 +18,8 @@ <Configurations> <Configuration Name="Debug|Win32" - OutputDirectory="..\..\simutrans-experimental-binaries\debug" - IntermediateDirectory="..\..\simutrans-experimental-binaries\debug\intermediates" + OutputDirectory="..\..\simutrans-experimental-binaries\makeobj\debug" + IntermediateDirectory="..\..\simutrans-experimental-binaries\makeobj\debug\intermediates" ConfigurationType="1" CharacterSet="1" > @@ -44,7 +44,6 @@ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;MAKEOBJ" MinimalRebuild="true" BasicRuntimeChecks="3" - RuntimeLibrary="3" UsePrecompiledHeader="0" WarningLevel="3" DebugInformationFormat="4" @@ -90,8 +89,8 @@ </Configuration> <Configuration Name="Release|Win32" - OutputDirectory="..\..\simutrans-experimental-binaries\release" - IntermediateDirectory="..\..\simutrans-experimental-binaries\release\intermediates" + OutputDirectory="..\..\simutrans-experimental-binaries\makeobj\release" + IntermediateDirectory="..\..\simutrans-experimental-binaries\makeobj\release\intermediates" ConfigurationType="1" CharacterSet="1" WholeProgramOptimization="1" @@ -115,7 +114,7 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;MAKEOBJ" RuntimeLibrary="2" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" @@ -133,6 +132,7 @@ /> <Tool Name="VCLinkerTool" + AdditionalDependencies="libpng.lib zlibstat.lib" LinkIncremental="1" GenerateDebugInformation="true" SubSystem="1" diff --git a/makeobj/makeobj.cc b/makeobj/makeobj.cc index a6bb2adfb62..e7c79e3666e 100644 --- a/makeobj/makeobj.cc +++ b/makeobj/makeobj.cc @@ -33,10 +33,9 @@ int main(int argc, char* argv[]) argv++, argc--; } else { puts( - "\nMakeobj-Experimental x, based on Makeobj version " MAKEOBJ_VERSION " for Simutrans-Experimental " VERSION_NUMBER " and higher\n" + "\nMakeobj-Experimental, based on Makeobj version " MAKEOBJ_VERSION " for Simutrans-Experimental " VERSION_NUMBER " and higher\n" "Experimental version by James E. Petts, derived from Makeobj, \n (c) 2002-2006 V. Meyer , Hj. Malthaner and \n" - "M. Pristovsek (markus@pristovsek.de). Files compiled with Makeobj-Experimental work with\n" - "Simutrans-Experimental and standard Simutrans.\n" + "M. Pristovsek (markus@pristovsek.de). This is open source software, released under the Artistic Licence.\n" ); } From fc55cc82749af77b9785b9c84a55908e094d6c64 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 7 Mar 2009 13:39:13 +0000 Subject: [PATCH 31/61] Added extra parameters for vehicle data files to prepare for new features. --- besch/reader/vehicle_reader.cc | 14 +++++- besch/vehikel_besch.h | 81 +++++++++++++++++++++++----------- besch/writer/vehicle_writer.cc | 56 +++++++++++++++++++++-- vehicle/simvehikel.cc | 8 ++-- 4 files changed, 125 insertions(+), 34 deletions(-) diff --git a/besch/reader/vehicle_reader.cc b/besch/reader/vehicle_reader.cc index 0bfa1cb0f4c..eb8a09591ea 100644 --- a/besch/reader/vehicle_reader.cc +++ b/besch/reader/vehicle_reader.cc @@ -190,6 +190,12 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->catering_level = decode_uint8(p); besch->bidirectional = decode_uint8(p); besch->can_lead_from_rear = decode_uint8(p); + besch->comfort = decode_uint8(p); + besch->overcrowded_capacity = decode_uint16(p); + besch->loading_time = decode_uint16(p); + besch->upgrades = decode_uint8(p); + besch->upgrade_price = decode_uint32(p); + besch->available_only_as_upgrade = decode_uint8(p); } else { @@ -262,12 +268,18 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) if(!experimental) { // Default values for items not in the standard vehicle format. - besch->is_tilting = 0; + besch->is_tilting = false; besch->way_constraints_permissive = 0; besch->way_constraints_prohibitive = 0; besch->catering_level = 0; besch->bidirectional = false; besch->can_lead_from_rear = false; + besch->comfort = 1; + besch->overcrowded_capacity = 0; + besch->loading_time = 2000; + besch->upgrades = 0; + besch->upgrade_price = besch->preis; + besch->available_only_as_upgrade = false; } diff --git a/besch/vehikel_besch.h b/besch/vehikel_besch.h index 46818e1c18c..da5f029d43b 100644 --- a/besch/vehikel_besch.h +++ b/besch/vehikel_besch.h @@ -64,29 +64,32 @@ class vehikel_besch_t : public obj_besch_std_name_t { private: - uint32 preis; //Price - uint16 zuladung; //Payload - uint16 geschw; //Speed - uint16 gewicht; //Weight - uint32 leistung; //Power - uint16 betriebskosten; //Running costs - - uint16 intro_date; // introduction date - uint16 obsolete_date; //phase out at - uint16 gear; // engine gear (power multiplier), 64=100 - - sint8 typ; // see weg_t for allowed types + uint32 preis; //Price + uint32 upgrade_price; //Price if this vehicle is bought as an upgrade, not a new vehicle. + uint16 zuladung; //Payload + uint16 overcrowded_capacity; // The capacity of a vehicle if overcrowded (usually expressed as the standing capacity). + uint16 geschw; //Speed + uint16 gewicht; //Weight + uint32 leistung; //Power + uint16 betriebskosten; //Running costs + + uint16 intro_date; // introduction date + uint16 obsolete_date; //phase out at + uint16 gear; // engine gear (power multiplier), 64=100 + + sint8 typ; // see weg_t for allowed types uint8 len; // length (=8 is half a tile, the old default) sint8 sound; - uint8 vorgaenger; // all defined leading vehicles - uint8 nachfolger; // all defined trailer + uint8 vorgaenger; // all defined leading vehicles + uint8 nachfolger; // all defined trailer + uint8 upgrades; // The vehicles types to which this type may be upgraded. - uint8 engine_type; // diesel, steam, electric (requires electrified ways), fuel_cell, etc. + uint8 engine_type; // diesel, steam, electric (requires electrified ways), fuel_cell, etc. sint8 freight_image_type; // number of freight images (displayed for different goods) - uint8 is_tilting; //Whether it is a tilting train (can take corners at higher speeds). 0 for no, 1 for yes. Anything other than 1 is assumed to be no. + bool is_tilting; //Whether it is a tilting train (can take corners at higher speeds). 0 for no, 1 for yes. Anything other than 1 is assumed to be no. uint8 way_constraints_permissive; //Way constraints. Actually, 8 boolean values. Bitwise operations necessary uint8 way_constraints_prohibitive; //to uncompress this (but if value is 0, are no constraints). @@ -94,7 +97,17 @@ class vehikel_besch_t : public obj_besch_std_name_t { uint8 catering_level; //The level of catering. 0 for no catering. Higher numbers for better catering. bool bidirectional; //Whether must always travel in one direction - bool can_lead_from_rear; + bool can_lead_from_rear; //Whether vehicle can lead a convoy when it is at the rear. + + uint8 comfort; // How comfortable that a vehicle is for passengers. + + uint16 loading_time; //Time in MS (at speed 1.0) to load/unload. + + bool available_only_as_upgrade; //If yes, can not be bought as new: only upgraded. + + + + public: @@ -104,17 +117,17 @@ class vehikel_besch_t : public obj_besch_std_name_t { // default vehicle (used for way seach and similar tasks) // since it has no images and not even a name knot any calls to this will case a crash vehikel_besch_t(uint8 wtyp, uint16 speed, engine_t engine) { - freight_image_type = preis = zuladung = betriebskosten = intro_date = vorgaenger = nachfolger = 0; - leistung = gewicht = 1; + freight_image_type = preis = upgrade_price = zuladung = overcrowded_capacity = betriebskosten = intro_date = vorgaenger = nachfolger = catering_level = upgrades = 0; + leistung = gewicht = comfort = 1; gear = 64; len = 8; sound = -1; typ = wtyp; engine_type = (uint8)engine; geschw = speed; - is_tilting = 0; + is_tilting = bidirectional = can_lead_from_rear = available_only_as_upgrade = false; way_constraints_prohibitive = way_constraints_permissive = 0; - catering_level = 0; + loading_time = 2000; } const ware_besch_t *get_ware() const { return static_cast<const ware_besch_t *>(get_child(2)); } @@ -225,20 +238,33 @@ class vehikel_besch_t : public obj_besch_std_name_t { // Nachfolger sind erlaubt oder keine. Um das zu unterscheiden, sollte // man vorher hat_nachfolger() befragen - //Returns the lawful successor. - //provides get_nachfolger (0) == NULL, it means that either all + // Returns the lawful successor. + // provides get_nachfolger (0) == NULL, it means that either all // succeed or none are allowed. To distinguish, one should // predict hat_nachfolger () question (Google) const vehikel_besch_t *get_nachfolger(int i) const { if(i < 0 || i >= nachfolger) { - return 0; + return NULL; } return static_cast<const vehikel_besch_t *>(get_child(6 + vorgaenger + i)); } int get_nachfolger_count() const { return nachfolger; } + // Returns the vehicle types to which this vehicle type is an upgrade. + + const vehikel_besch_t * get_upgrades(int i) const + { + if(i < 0 || i >= upgrades) + { + return NULL; + } + return static_cast<const vehikel_besch_t *>(get_child(6 + nachfolger + i)); + } + + int get_upgrades_count() const { return upgrades; } + waytype_t get_waytype() const { return static_cast<waytype_t>(typ); } uint16 get_zuladung() const { return zuladung; } uint32 get_preis() const { return preis; } @@ -250,6 +276,11 @@ class vehikel_besch_t : public obj_besch_std_name_t { sint8 get_sound() const { return sound; } bool is_bidirectional() const { return bidirectional; } bool get_can_lead_from_rear() const { return can_lead_from_rear; } + uint8 get_comfort() const { return comfort; } + uint16 get_overcrowded_capacity() const { return overcrowded_capacity; } + uint16 get_loading_time() const { return loading_time; } + uint32 get_upgrade_price() const { return upgrade_price; } + bool is_available_only_as_upgrade() { return available_only_as_upgrade; } /** @@ -297,7 +328,7 @@ class vehikel_besch_t : public obj_besch_std_name_t { /*Whether this is a tilting train (and can take coerners faster *@author: jamespetts*/ - bool get_tilting() const { return (is_tilting == 1); } + bool get_tilting() const { return (is_tilting); } /*Bitwise encoded way constraints (permissive) *@author: jamespetts*/ diff --git a/besch/writer/vehicle_writer.cc b/besch/writer/vehicle_writer.cc index 969538e36d6..81e38bc9fe6 100644 --- a/besch/writer/vehicle_writer.cc +++ b/besch/writer/vehicle_writer.cc @@ -76,7 +76,7 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj int i; uint8 uv8; - int total_len = 37; + int total_len = 48; // prissi: must be done here, since it may affect the length of the header! cstring_t sound_str = ltrim( obj.get("sound") ); @@ -314,6 +314,23 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj } } while (str.len() > 0); + // Upgrades: these are the vehicle types to which this vehicle type + // is an upgrade. "None" means that it is not an upgrade. + uint8 upgrades = 0; + do { + char buf[40]; + sprintf(buf, "upgrade[%d]", upgrades); + str = obj.get(buf); + if (str.len() > 0) { + if (upgrades == 0 && !STRICMP(str, "none")) + { + str = ""; + } + xref_writer_t::instance()->write_obj(fp, node, obj_vehicle, str, false); + upgrades++; + } + } while (str.len() > 0); + // multiple freight image types - define what good uses each index // good without index will be an error for (i = 0; i <= freight_max; i++) { @@ -420,10 +437,43 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj uint8 can_lead_from_rear = (obj.get_int("can_lead_from_rear", 0)); node.write_uint8(fp, can_lead_from_rear, 36); + // Passenger comfort rating - affects revenue on longer journies. + //@author: jamespetts + uint8 comfort = (obj.get_int("ccomfort", 1)); + node.write_uint8(fp, comfort, 37); + + // Overcrowded capacity - can take this much *in addition to* normal capacity, + // but revenue will be lower and dwell times higher. Mainly for passengers. + //@author: jamespetts + uint16 overcrowded_capacity = (obj.get_int("overcrowded_capacity", 0)); + node.write_uint8(fp, overcrowded_capacity, 38); + + // The time that it takes the vehicle to load and unload at stations (i.e., the + // dwell time). The default is 2,000 because that is the value used in Simutrans- + // Standard. + //@author: jamespetts + uint16 loading_time = (obj.get_int("loading_time", 2000)); + node.write_uint16(fp, loading_time, 40); + + // Upgrading settings + //@author: jamespetts + + node.write_sint8(fp, upgrades, 42); + + // This is the cost of upgrading to this vehicle, rather than buying it new. + // By default, the cost is the same as a new purchase. + uint32 upgrade_price = (obj.get_int("upgrade_price", cost)); + node.write_uint32(fp, upgrade_price, 43); + + // If this is set to true (is read as a bool), this will only be able to be purchased + // as an upgrade to another vehicle, not as a new vehicle. + uint8 available_only_as_upgrade = (obj.get_int("available_only_as_upgrade", 0)); + node.write_uint8(fp, available_only_as_upgrade, 47); + sint8 sound_str_len = sound_str.len(); if (sound_str_len > 0) { - node.write_sint8 (fp, sound_str_len, 37); - node.write_data_at(fp, sound_str, 38, sound_str_len); + node.write_sint8 (fp, sound_str_len, 48); + node.write_data_at(fp, sound_str, 49, sound_str_len); } node.write(fp); diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index fc66d9a9f66..bb13a6ade86 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -90,8 +90,6 @@ uint8 vehikel_basis_t::old_diagonal_length = 127; uint8 vehikel_basis_t::diagonal_length = 180; uint16 vehikel_basis_t::diagonal_multiplier = 724; -uint16 local_bonus_supplement; - // set only once, before loading! void vehikel_basis_t::set_diagonal_multiplier( uint32 multiplier, uint32 old_diagonal_multiplier ) { @@ -969,7 +967,7 @@ vehikel_t::vehikel_t(koord3d pos, const vehikel_besch_t* besch, spieler_t* sp) : current_corner = 0; #endif direction_steps = 4; - local_bonus_supplement = 0; + //local_bonus_supplement = 0; is_overweight = false; reversed = false; } @@ -998,7 +996,7 @@ vehikel_t::vehikel_t(karte_t *welt) : current_corner = 0; #endif direction_steps = 4; - local_bonus_supplement = 0; + //local_bonus_supplement = 0; is_overweight = false; reversed = false; } @@ -1612,7 +1610,7 @@ sint64 vehikel_t::calc_gewinn(koord start, koord end, convoi_t *cnv) const const uint16 base_bonus = goods->get_speed_bonus(); uint16 adjusted_bonus = 0; - local_bonus_supplement = (welt->get_einstellungen()->get_local_bonus_multiplier() / 100) * base_bonus; + uint16 local_bonus_supplement = (welt->get_einstellungen()->get_local_bonus_multiplier() / 100) * base_bonus; if(dist <= welt->get_einstellungen()->get_min_bonus_max_distance()) { From 3d76cbfd696a5cfe6ca4b4b9ae746199b7cfe641 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 7 Mar 2009 13:49:06 +0000 Subject: [PATCH 32/61] Fixed some inconsistencies after merging the new version from the trunk. --- bauer/wegbauer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bauer/wegbauer.cc b/bauer/wegbauer.cc index e9afa610880..1e4cf921c20 100644 --- a/bauer/wegbauer.cc +++ b/bauer/wegbauer.cc @@ -1850,7 +1850,6 @@ wegbauer_t::baue_tunnelboden() weg->add_way_constraints(besch->get_way_constraints_permissive(), besch->get_way_constraints_prohibitive()); tunnel->calc_bild(); cost -= tunnel_besch->get_preis(); - spieler_t::add_maintenance( sp, -weg->get_besch()->get_wartung()); spieler_t::add_maintenance( sp, tunnel_besch->get_wartung() ); } else if(gr->get_typ()==grund_t::tunnelboden) { @@ -1862,6 +1861,7 @@ wegbauer_t::baue_tunnelboden() spieler_t::add_maintenance(sp, -weg->get_besch()->get_wartung()); weg->set_besch(besch); weg->set_max_speed(tunnel_besch->get_topspeed()); + weg->set_max_weight(tunnel_besch->get_max_weight()); gr->calc_bild(); cost -= besch->get_preis(); spieler_t::add_maintenance( sp, tunnel_besch->get_wartung() ); From 9df9bd88f9b29a3b45e730301696b8fb22559690 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 9 Mar 2009 00:06:43 +0000 Subject: [PATCH 33/61] Vehicles can now be upgraded (both in the depot and replace windows) as well as bought and sold. .dat files can now specify the vehicles to which the current vehicle can be upgraded, and the price of upgrading to that vehicle, as well as whether it is available only as an upgrade. Also, the colours indicating whether or not vehicles can be purchased and/or are obsolete in the depot window have been made more subdued. --- bauer/vehikelbauer.cc | 12 +- bauer/vehikelbauer.h | 7 +- besch/vehikel_besch.h | 4 +- besch/writer/vehicle_writer.cc | 4 +- gui/components/gui_convoy_assembler.cc | 354 +++++++++++++++++++++---- gui/components/gui_convoy_assembler.h | 11 + gui/depot_frame.cc | 27 +- gui/replace_frame.cc | 155 +++++++++-- gui/replace_frame.h | 11 +- simconvoi.cc | 90 ++++++- simdepot.cc | 14 +- simdepot.h | 2 +- utils/log.cc | 2 +- vehicle/simvehikel.cc | 4 + vehicle/simvehikel.h | 1 + 15 files changed, 586 insertions(+), 112 deletions(-) diff --git a/bauer/vehikelbauer.cc b/bauer/vehikelbauer.cc index 19659bf73c5..9bd246f9729 100644 --- a/bauer/vehikelbauer.cc +++ b/bauer/vehikelbauer.cc @@ -147,7 +147,7 @@ sint32 vehikelbauer_t::get_speedbonus( sint32 monthyear, waytype_t wt ) -vehikel_t* vehikelbauer_t::baue(koord3d k, spieler_t* sp, convoi_t* cnv, const vehikel_besch_t* vb ) +vehikel_t* vehikelbauer_t::baue(koord3d k, spieler_t* sp, convoi_t* cnv, const vehikel_besch_t* vb, bool upgrade ) { vehikel_t* v; switch (vb->get_waytype()) { @@ -164,7 +164,15 @@ vehikel_t* vehikelbauer_t::baue(koord3d k, spieler_t* sp, convoi_t* cnv, const v dbg->fatal("vehikelbauer_t::baue()", "cannot built a vehicle with waytype %i", vb->get_waytype()); } - sp->buche(-(sint32)vb->get_preis(), k.get_2d(), COST_NEW_VEHICLE ); + if(upgrade) + { + sp->buche(-(sint32)vb->get_upgrade_price(), k.get_2d(), COST_NEW_VEHICLE ); + } + else + { + sp->buche(-(sint32)vb->get_preis(), k.get_2d(), COST_NEW_VEHICLE ); + } + sp->buche( (sint32)vb->get_preis(), COST_ASSETS ); return v; diff --git a/bauer/vehikelbauer.h b/bauer/vehikelbauer.h index b0e71b467f7..b77a21c659e 100644 --- a/bauer/vehikelbauer.h +++ b/bauer/vehikelbauer.h @@ -41,7 +41,12 @@ class vehikelbauer_t static bool register_besch(const vehikel_besch_t *besch); static bool alles_geladen(); - static vehikel_t* baue(koord3d k, spieler_t* sp, convoi_t* cnv, const vehikel_besch_t* vb ); + static vehikel_t* baue(koord3d k, spieler_t* sp, convoi_t* cnv, const vehikel_besch_t* vb ) + { + return baue(k, sp, cnv, vb, false); + } + + static vehikel_t* baue(koord3d k, spieler_t* sp, convoi_t* cnv, const vehikel_besch_t* vb, bool upgrade ); static const vehikel_besch_t * get_info(const char *name); static slist_tpl<const vehikel_besch_t*>* get_info(waytype_t typ); diff --git a/besch/vehikel_besch.h b/besch/vehikel_besch.h index da5f029d43b..a9afc8c3b96 100644 --- a/besch/vehikel_besch.h +++ b/besch/vehikel_besch.h @@ -252,7 +252,7 @@ class vehikel_besch_t : public obj_besch_std_name_t { int get_nachfolger_count() const { return nachfolger; } - // Returns the vehicle types to which this vehicle type is an upgrade. + // Returns the vehicle types to which this vehicle type may be upgraded. const vehikel_besch_t * get_upgrades(int i) const { @@ -280,7 +280,7 @@ class vehikel_besch_t : public obj_besch_std_name_t { uint16 get_overcrowded_capacity() const { return overcrowded_capacity; } uint16 get_loading_time() const { return loading_time; } uint32 get_upgrade_price() const { return upgrade_price; } - bool is_available_only_as_upgrade() { return available_only_as_upgrade; } + bool is_available_only_as_upgrade() const { return available_only_as_upgrade; } /** diff --git a/besch/writer/vehicle_writer.cc b/besch/writer/vehicle_writer.cc index 81e38bc9fe6..03224be6c85 100644 --- a/besch/writer/vehicle_writer.cc +++ b/besch/writer/vehicle_writer.cc @@ -314,8 +314,8 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj } } while (str.len() > 0); - // Upgrades: these are the vehicle types to which this vehicle type - // is an upgrade. "None" means that it is not an upgrade. + // Upgrades: these are the vehicle types to which this vehicle + // can be upgraded. "None" means that it cannot be upgraded. uint8 upgrades = 0; do { char buf[40]; diff --git a/gui/components/gui_convoy_assembler.cc b/gui/components/gui_convoy_assembler.cc index 2ed849fd36c..94a2ec03201 100644 --- a/gui/components/gui_convoy_assembler.cc +++ b/gui/components/gui_convoy_assembler.cc @@ -11,6 +11,7 @@ #include "gui_convoy_assembler.h" #include "../depot_frame.h" +#include "../replace_frame.h" #include "../../simworld.h" @@ -115,12 +116,12 @@ const char * gui_convoy_assembler_t::get_haenger_name(waytype_t wt) bool gui_convoy_assembler_t::show_retired_vehicles = false; -bool gui_convoy_assembler_t::show_all = true; +bool gui_convoy_assembler_t::show_all = false; gui_convoy_assembler_t::gui_convoy_assembler_t(karte_t *w, waytype_t wt, bool electrified, signed char player_nr) : way_type(wt), weg_electrified(electrified), welt(w), last_changed_vehicle(NULL), - depot_frame(NULL), placement(get_placement(wt)), + depot_frame(NULL), replace_frame(NULL), placement(get_placement(wt)), placement_dx(get_grid(wt).x * get_base_tile_raster_width() / 64 / 4), grid(get_grid(wt)), grid_dx(get_grid(wt).x * get_base_tile_raster_width() / 64 / 2), @@ -128,6 +129,7 @@ gui_convoy_assembler_t::gui_convoy_assembler_t(karte_t *w, waytype_t wt, bool el lb_convoi_count(NULL, COL_BLACK, gui_label_t::left), lb_convoi_speed(NULL, COL_BLACK, gui_label_t::left), lb_veh_action("Fahrzeuge:", COL_BLACK, gui_label_t::left), + //lb_upgrade("New/upgrade:", COL_BLACK, gui_label_t::left), convoi_pics(depot_t::get_max_convoy_length(wt)), convoi(&convoi_pics), pas(&pas_vec), @@ -233,6 +235,7 @@ gui_convoy_assembler_t::gui_convoy_assembler_t(karte_t *w, waytype_t wt, bool el add_komponente(&tabs); add_komponente(&div_tabbottom); add_komponente(&lb_veh_action); + //add_komponente(&lb_upgrade); veh_action = va_append; action_selector.add_listener(this); @@ -244,6 +247,14 @@ gui_convoy_assembler_t::gui_convoy_assembler_t(karte_t *w, waytype_t wt, bool el action_selector.append_element( new gui_scrolled_list_t::const_text_scrollitem_t( translator::translate(txt_veh_action[2]), COL_BLACK ) ); action_selector.set_selection( 0 ); + upgrade = u_buy; + upgrade_selector.add_listener(this); + add_komponente(&upgrade_selector); + upgrade_selector.clear_elements(); + static const char *txt_upgrade[2] = { "Buy/sell", "Upgrade" }; + upgrade_selector.append_element(new gui_scrolled_list_t::const_text_scrollitem_t(translator::translate(txt_upgrade[0]), COL_BLACK ) ); + upgrade_selector.append_element(new gui_scrolled_list_t::const_text_scrollitem_t(translator::translate(txt_upgrade[1]), COL_BLACK ) ); + upgrade_selector.set_selection(0); bt_obsolete.set_typ(button_t::square); bt_obsolete.set_text("Show obsolete"); @@ -345,12 +356,17 @@ void gui_convoy_assembler_t::layout() int ABUTTON_WIDTH=96; int ABUTTON_HEIGHT=14; lb_veh_action.set_pos(koord(groesse.x-ABUTTON_WIDTH, PANEL_VSTART + get_panel_height() + 4)); + //lb_upgrade.set_pos(koord(groesse.x-ABUTTON_WIDTH, PANEL_VSTART + get_panel_height() + 34)); action_selector.set_pos(koord(groesse.x-ABUTTON_WIDTH, PANEL_VSTART + get_panel_height() + 14)); action_selector.set_groesse(koord(ABUTTON_WIDTH, ABUTTON_HEIGHT)); action_selector.set_max_size(koord(ABUTTON_WIDTH - 8, LINESPACE*3+2+16)); action_selector.set_highlight_color(1); + upgrade_selector.set_pos(koord(groesse.x-ABUTTON_WIDTH, PANEL_VSTART + get_panel_height() + 34)); + upgrade_selector.set_groesse(koord(ABUTTON_WIDTH, ABUTTON_HEIGHT)); + upgrade_selector.set_max_size(koord(ABUTTON_WIDTH - 8, LINESPACE*2+2+16)); + upgrade_selector.set_highlight_color(1); bt_show_all.set_pos(koord(groesse.x-(ABUTTON_WIDTH*5)/2, PANEL_VSTART + get_panel_height() + 4 )); bt_show_all.set_groesse(koord(ABUTTON_WIDTH, ABUTTON_HEIGHT)); @@ -359,6 +375,13 @@ void gui_convoy_assembler_t::layout() bt_obsolete.set_pos(koord(groesse.x-(ABUTTON_WIDTH*5)/2, PANEL_VSTART + get_panel_height() + 16)); bt_obsolete.set_groesse(koord(ABUTTON_WIDTH, ABUTTON_HEIGHT)); bt_obsolete.pressed = show_retired_vehicles; + + if(replace_frame == NULL) + { + // Do not display this if this is not the replacing window. + // Vehicles cannot be upgraded from the depot window. + //upgrade_selector.set_visible(false); + } } @@ -390,11 +413,23 @@ bool gui_convoy_assembler_t::action_triggered( gui_action_creator_t *komp,value_ action_selector.set_selection(0); selection=0; } - if( (unsigned)(selection)<=va_sell ) { + if( (unsigned)(selection)<=va_sell ) { veh_action=(unsigned)(selection); build_vehicle_lists(); update_data(); } + } else if(komp == &upgrade_selector) { + int upgrade_selection = p.i; + if ( upgrade_selection < 0 ) { + upgrade_selector.set_selection(0); + upgrade_selection=0; + } + if( (unsigned)(upgrade_selection)<=u_upgrade ) { + upgrade=(unsigned)(upgrade_selection); + build_vehicle_lists(); + update_data(); + } + } else { return false; } @@ -522,14 +557,65 @@ void gui_convoy_assembler_t::build_vehicle_lists() ((!info->is_future(month_now)) && (show_retired_vehicles || (!info->is_retired(month_now)) ) ) )) { // check, if allowed bool append = true; - if(!show_all) { - if(veh_action == va_insert) { + bool upgradeable = true; + if(!show_all) + { + if(veh_action == va_insert) + { append = !(!convoi_t::pruefe_nachfolger(info, veh) || (veh && !convoi_t::pruefe_vorgaenger(info, veh))); - } else if(veh_action == va_append) { + } + else if(veh_action == va_append) + { append = convoi_t::pruefe_vorgaenger(veh, info); } + if(upgrade == u_upgrade) + { + vector_tpl<const vehikel_besch_t*> vehicle_list; + upgradeable = false; + + if(replace_frame == NULL) + { + ITERATE(vehicles,i) + { + vehicle_list.append(vehicles[i]); + } + } + else + { + const convoihandle_t cnv = replace_frame->get_convoy(); + + for(uint8 i = 0; i < cnv->get_vehikel_anzahl(); i ++) + { + vehicle_list.append(cnv->get_vehikel(i)->get_besch()); + } + } + + if(vehicle_list.get_count() < 1) + { + break; + } + + ITERATE(vehicle_list, i) + { + for(uint16 c = 0; c < vehicle_list[i]->get_upgrades_count(); c++) + { + if(info->get_name() == vehicle_list[i]->get_upgrades(c)->get_name()) + { + upgradeable = true; + } + } + } + } + else + { + if(info->is_available_only_as_upgrade()) + { + append = false; + } + } } - if(append) { + if(append && (upgrade == u_buy || upgradeable)) + { add_to_vehicle_list( info ); } } @@ -628,11 +714,16 @@ void gui_convoy_assembler_t::image_from_storage_list(gui_image_list_t::image_dat if(bild_data->lcolor != COL_RED && bild_data->rcolor != COL_RED && + bild_data->rcolor != COL_DARK_PURPLE && + bild_data->lcolor != COL_DARK_PURPLE && + bild_data->rcolor != COL_PURPLE && + bild_data->lcolor != COL_PURPLE && !((bild_data->lcolor == COL_DARK_ORANGE || bild_data->rcolor == COL_DARK_ORANGE) && veh_action != va_sell && depot_frame != NULL && !depot_frame->get_depot()->find_oldest_newest(info, true))) { - //Dark orange = too expensive + // Dark orange = too expensive + // Purple = available only as upgrade // we buy/sell all vehicles together! slist_tpl<const vehikel_besch_t *>new_vehicle_info; @@ -647,7 +738,8 @@ void gui_convoy_assembler_t::image_from_storage_list(gui_image_list_t::image_dat info = start_info; } // not get the end ... - while(info) { + while(info) + { new_vehicle_info.append( info ); DBG_MESSAGE("gui_convoy_assembler_t::image_from_storage_list()","appended %s",info->get_name() ); if(info->get_nachfolger_count()!=1 || (veh_action==va_insert && info==start_info)) { @@ -656,7 +748,8 @@ DBG_MESSAGE("gui_convoy_assembler_t::image_from_storage_list()","appended %s",in info = info->get_nachfolger(0); } - if(veh_action == va_sell) { + if(veh_action == va_sell) + { while(new_vehicle_info.get_count() && depot_frame) { /* * We sell the newest vehicle - gives most money back. @@ -669,8 +762,8 @@ DBG_MESSAGE("gui_convoy_assembler_t::image_from_storage_list()","appended %s",in } } } - else { - + else + { // append/insert into convoi if(vehicles.get_count()+new_vehicle_info.get_count() <= max_convoy_length) { @@ -694,7 +787,6 @@ DBG_MESSAGE("gui_convoy_assembler_t::image_from_storage_list()","built nr %i", n } - void gui_convoy_assembler_t::update_data() { // change green into blue for retired vehicles @@ -723,21 +815,21 @@ void gui_convoy_assembler_t::update_data() } /* color bars for current convoi: */ - convoi_pics[0].lcolor = convoi_t::pruefe_vorgaenger(NULL, vehicles[0]) ? COL_GREEN : COL_YELLOW; + convoi_pics[0].lcolor = convoi_t::pruefe_vorgaenger(NULL, vehicles[0]) ? COL_DARK_GREEN : COL_YELLOW; for( i=1; i<vehicles.get_count(); i++) { - convoi_pics[i - 1].rcolor = convoi_t::pruefe_nachfolger(vehicles[i - 1], vehicles[i]) ? COL_GREEN : COL_RED; - convoi_pics[i].lcolor = convoi_t::pruefe_vorgaenger(vehicles[i - 1], vehicles[i]) ? COL_GREEN : COL_RED; + convoi_pics[i - 1].rcolor = convoi_t::pruefe_nachfolger(vehicles[i - 1], vehicles[i]) ? COL_DARK_GREEN : COL_RED; + convoi_pics[i].lcolor = convoi_t::pruefe_vorgaenger(vehicles[i - 1], vehicles[i]) ? COL_DARK_GREEN : COL_RED; } - convoi_pics[i - 1].rcolor = convoi_t::pruefe_nachfolger(vehicles[i - 1], NULL) ? COL_GREEN : COL_YELLOW; + convoi_pics[i - 1].rcolor = convoi_t::pruefe_nachfolger(vehicles[i - 1], NULL) ? COL_DARK_GREEN : COL_YELLOW; // change grren into blue for retired vehicles for(i=0; i<vehicles.get_count(); i++) { if(vehicles[i]->is_future(month_now) || vehicles[i]->is_retired(month_now)) { - if (convoi_pics[i].lcolor == COL_GREEN) { - convoi_pics[i].lcolor = COL_BLUE; + if (convoi_pics[i].lcolor == COL_DARK_GREEN) { + convoi_pics[i].lcolor = COL_DARK_BLUE; } - if (convoi_pics[i].rcolor == COL_GREEN) { - convoi_pics[i].rcolor = COL_BLUE; + if (convoi_pics[i].rcolor == COL_DARK_GREEN) { + convoi_pics[i].rcolor = COL_DARK_BLUE; } } } @@ -753,9 +845,10 @@ void gui_convoy_assembler_t::update_data() const spieler_t *sp = welt->get_active_player(); - while(iter1.next()) { + while(iter1.next()) + { const vehikel_besch_t *info = iter1.get_current_key(); - const uint8 ok_color = info->is_future(month_now) || info->is_retired(month_now) ? COL_BLUE: COL_GREEN; + const uint8 ok_color = info->is_future(month_now) || info->is_retired(month_now) ? COL_DARK_BLUE: COL_DARK_GREEN; iter1.get_current_value()->count = 0; iter1.get_current_value()->lcolor = ok_color; @@ -768,6 +861,8 @@ void gui_convoy_assembler_t::update_data() * green/yellow append okay, cannot be end of train * yellow/green insert okay, cannot be start of train * orange/orange - too expensive + * purple/purple available only as upgrade + * dark purple/dark purple cannot upgrade to this vehicle */ if(veh_action == va_insert) { @@ -789,17 +884,132 @@ void gui_convoy_assembler_t::update_data() { //Check whether too expensive //@author: jamespetts - if(iter1.get_current_value()->lcolor == COL_GREEN || iter1.get_current_value()->lcolor == COL_YELLOW) + if(iter1.get_current_value()->lcolor == ok_color || iter1.get_current_value()->lcolor == COL_YELLOW) { //Only flag as too expensive that which could be purchased anyway. - if(!sp->can_afford(info->get_preis())) + if(upgrade == u_buy) { - iter1.get_current_value()->lcolor = COL_DARK_ORANGE; - iter1.get_current_value()->rcolor = COL_DARK_ORANGE; + if(!sp->can_afford(info->get_preis())) + { + iter1.get_current_value()->lcolor = COL_DARK_ORANGE; + iter1.get_current_value()->rcolor = COL_DARK_ORANGE; + } + } + else + { + if(!sp->can_afford(info->get_upgrade_price())) + { + iter1.get_current_value()->lcolor = COL_DARK_ORANGE; + iter1.get_current_value()->rcolor = COL_DARK_ORANGE; + } } } } + if(upgrade == u_upgrade) + { + //Check whether there are any vehicles to upgrade + iter1.get_current_value()->lcolor = COL_DARK_PURPLE; + iter1.get_current_value()->rcolor = COL_DARK_PURPLE; + vector_tpl<const vehikel_besch_t*> vehicle_list; + + if(replace_frame == NULL) + { + ITERATE(vehicles,i) + { + vehicle_list.append(vehicles[i]); + } + } + else + { + const convoihandle_t cnv = replace_frame->get_convoy(); + + for(uint8 i = 0; i < cnv->get_vehikel_anzahl(); i ++) + { + vehicle_list.append(cnv->get_vehikel(i)->get_besch()); + } + } + + ITERATE(vehicle_list, i) + { + for(uint16 c = 0; c < vehicle_list[i]->get_upgrades_count(); c++) + { + if(info->get_name() == vehicle_list[i]->get_upgrades(c)->get_name()) + { + iter1.get_current_value()->lcolor = COL_DARK_GREEN; + iter1.get_current_value()->rcolor = COL_DARK_GREEN; + if(replace_frame != NULL) + { + // If we are using the replacing window, + // vehicle_list is the list of all vehicles in the current convoy. + // vehicles is the list of the vehicles to replace them with. + sint8 upgradeable_count = 0; + ITERATE(vehicles,j) + { + if(vehicles[j]->get_name() == info->get_name()) + { + // Counts the number of vehicles in the current convoy that can + // upgrade to the currently selected vehicle. + upgradeable_count --; + } + } + ITERATE(vehicle_list,j) + { + for(uint16 k = 0; k < vehicle_list[j]->get_upgrades_count(); k++) + { + if(vehicle_list[j]->get_upgrades(k)->get_name() == info->get_name()) + { + // Counts the number of vehicles currently marked to be upgraded + // to the selected vehicle. + upgradeable_count ++; + } + } + } + + if(upgradeable_count < 1) + { + //There are not enough vehicles left to upgrade. + iter1.get_current_value()->lcolor = COL_DARK_PURPLE; + iter1.get_current_value()->rcolor = COL_DARK_PURPLE; + } + + } + if(veh_action == va_insert) + { + if (!convoi_t::pruefe_nachfolger(info, veh) || (veh && !convoi_t::pruefe_vorgaenger(info, veh))) + { + iter1.get_current_value()->lcolor = COL_RED; + iter1.get_current_value()->rcolor = COL_RED; + } + else if(!convoi_t::pruefe_vorgaenger(NULL, info)) + { + iter1.get_current_value()->lcolor = COL_YELLOW; + } + } + else if(veh_action == va_append) + { + if(!convoi_t::pruefe_vorgaenger(veh, info) || (veh && !convoi_t::pruefe_nachfolger(veh, info))) { + iter1.get_current_value()->lcolor = COL_RED; + iter1.get_current_value()->rcolor = COL_RED; + } + else if(!convoi_t::pruefe_nachfolger(info, NULL)) + { + iter1.get_current_value()->rcolor = COL_YELLOW; + } + } + } + } + } + } + else + { + if(info->is_available_only_as_upgrade()) + { + iter1.get_current_value()->lcolor = COL_PURPLE; + iter1.get_current_value()->rcolor = COL_PURPLE; + } + } + DBG_DEBUG("gui_convoy_assembler_t::update_data()","current %i = %s with color %i",info->get_name(),iter1.get_current_value()->lcolor); } @@ -811,8 +1021,8 @@ DBG_DEBUG("gui_convoy_assembler_t::update_data()","current %i = %s with color %i if(imgdat) { imgdat->count++; if(veh_action == va_sell) { - imgdat->lcolor = COL_GREEN; - imgdat->rcolor = COL_GREEN; + imgdat->lcolor = COL_DARK_GREEN; + imgdat->rcolor = COL_DARK_GREEN; } } } @@ -899,15 +1109,32 @@ void gui_convoy_assembler_t::draw_vehicle_info_text(koord pos) translator::translate(veh_type->get_name()), translator::translate(engine_type_names[veh_type->get_engine_type()+1])); - int n = sprintf(buf, - translator::translate("LOCO_INFO"), - name, - veh_type->get_preis()/100, - veh_type->get_betriebskosten(get_welt())/100.0, - veh_type->get_leistung(), - veh_type->get_geschw(), - veh_type->get_gewicht() - ); + int n; + + if(upgrade == u_buy) + { + n = sprintf(buf, + translator::translate("LOCO_INFO"), + name, + veh_type->get_preis()/100, + veh_type->get_betriebskosten(get_welt())/100.0, + veh_type->get_leistung(), + veh_type->get_geschw(), + veh_type->get_gewicht() + ); + } + else + { + n = sprintf(buf, + translator::translate("LOCO_INFO"), + name, + veh_type->get_upgrade_price()/100, + veh_type->get_betriebskosten(get_welt())/100.0, + veh_type->get_leistung(), + veh_type->get_geschw(), + veh_type->get_gewicht() + ); + } //"Payload" (Google) if(zuladung>0) { @@ -923,19 +1150,39 @@ void gui_convoy_assembler_t::draw_vehicle_info_text(koord pos) } else { // waggon - int n = sprintf(buf, - translator::translate("WAGGON_INFO"), - translator::translate(veh_type->get_name()), - veh_type->get_preis()/100, - veh_type->get_betriebskosten(get_welt())/100.0, - veh_type->get_zuladung(), - translator::translate(veh_type->get_ware()->get_mass()), - veh_type->get_ware()->get_catg() == 0 ? - translator::translate(veh_type->get_ware()->get_name()) : - translator::translate(veh_type->get_ware()->get_catg_name()), - veh_type->get_gewicht(), - veh_type->get_geschw() - ); + int n; + if(upgrade == u_buy) + { + n = sprintf(buf, + translator::translate("WAGGON_INFO"), + translator::translate(veh_type->get_name()), + veh_type->get_preis()/100, + veh_type->get_betriebskosten(get_welt())/100.0, + veh_type->get_zuladung(), + translator::translate(veh_type->get_ware()->get_mass()), + veh_type->get_ware()->get_catg() == 0 ? + translator::translate(veh_type->get_ware()->get_name()) : + translator::translate(veh_type->get_ware()->get_catg_name()), + veh_type->get_gewicht(), + veh_type->get_geschw() + ); + } + else + { + n = sprintf(buf, + translator::translate("WAGGON_INFO"), + translator::translate(veh_type->get_name()), + veh_type->get_upgrade_price()/100, + veh_type->get_betriebskosten(get_welt())/100.0, + veh_type->get_zuladung(), + translator::translate(veh_type->get_ware()->get_mass()), + veh_type->get_ware()->get_catg() == 0 ? + translator::translate(veh_type->get_ware()->get_name()) : + translator::translate(veh_type->get_ware()->get_catg_name()), + veh_type->get_gewicht(), + veh_type->get_geschw() + ); + } k = n; } @@ -1051,4 +1298,9 @@ void gui_convoy_assembler_t::infowin_event(const event_t *ev) // close combo box; we must do it ourselves, since the box does not recieve outside events ... action_selector.close_box(); } + + if(IS_LEFTCLICK(ev) && !upgrade_selector.getroffen(ev->cx, ev->cy-16)) { + // close combo box; we must do it ourselves, since the box does not recieve outside events ... + upgrade_selector.close_box(); + } } \ No newline at end of file diff --git a/gui/components/gui_convoy_assembler.h b/gui/components/gui_convoy_assembler.h index 75871d95dd3..888c8ff9ab0 100644 --- a/gui/components/gui_convoy_assembler.h +++ b/gui/components/gui_convoy_assembler.h @@ -70,6 +70,7 @@ class gui_convoy_assembler_t : // If this is used for a depot, which depot_frame manages, else NULL class depot_frame_t *depot_frame; + class replace_frame_t *replace_frame; /* Gui parameters */ koord placement; // ...of first vehicle image @@ -93,6 +94,9 @@ class gui_convoy_assembler_t : gui_label_t lb_veh_action; gui_combobox_t action_selector; + //gui_label_t lb_upgrade; + gui_combobox_t upgrade_selector; + vector_tpl<gui_image_list_t::image_data_t> convoi_pics; gui_image_list_t convoi; @@ -119,6 +123,7 @@ class gui_convoy_assembler_t : enum { va_append, va_insert, va_sell }; uint8 veh_action; + uint8 upgrade; // text for the tabs is defaulted to the train names static const char * get_electrics_name(waytype_t wt); @@ -156,6 +161,8 @@ class gui_convoy_assembler_t : // Used for listeners to know what has happened enum { clear_convoy_action, remove_vehicle_action, insert_vehicle_in_front_action, append_vehicle_action }; + enum { u_buy, u_upgrade }; + gui_convoy_assembler_t(karte_t *w, waytype_t wt, bool electrified, signed char player_nr ); /** @@ -206,6 +213,7 @@ class gui_convoy_assembler_t : inline karte_t *get_welt() const {return welt;} inline void set_depot_frame(depot_frame_t *df) {depot_frame=df;} + inline void set_replace_frame(replace_frame_t *rf) {replace_frame=rf;} inline const vector_tpl<const vehikel_besch_t *>* get_vehicles() const {return &vehicles;} void set_vehicles(convoihandle_t cnv); @@ -243,6 +251,9 @@ class gui_convoy_assembler_t : inline int get_height() const {return get_convoy_height() + convoy_tabs_skip + 8 + get_panel_height() + get_vinfo_height();} inline int get_min_height() const {return get_convoy_height() + convoy_tabs_skip + 8 + get_min_panel_height() + get_vinfo_height();} + + inline uint8 get_upgrade() const { return upgrade; } + inline uint8 get_action() const { return veh_action; } }; #endif \ No newline at end of file diff --git a/gui/depot_frame.cc b/gui/depot_frame.cc index e2d67a2f245..977b0dfd61f 100644 --- a/gui/depot_frame.cc +++ b/gui/depot_frame.cc @@ -415,10 +415,28 @@ bool depot_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) vb=(*convoy_assembler->get_vehicles())[convoy_assembler->get_vehicles()->get_count()-1]; } vehikel_t* veh = depot->find_oldest_newest(vb, true); - if (veh == NULL) { + if (veh == NULL) + { // nothing there => we buy it - veh = depot->buy_vehicle(vb); + veh = depot->buy_vehicle(vb, convoy_assembler->get_upgrade() == gui_convoy_assembler_t::u_upgrade); + if(convoy_assembler->get_upgrade() == gui_convoy_assembler_t::u_upgrade && cnv.is_bound()) + { + //Upgrading, so vehicles must be *replaced*. + for(uint16 i = 0; i < cnv->get_vehikel_anzahl(); i ++) + { + for(uint8 c = 0; c < cnv->get_vehikel(i)->get_besch()->get_upgrades_count(); c ++) + { + if(cnv->get_vehikel(i)->get_besch()->get_upgrades(c)->get_name() == vb->get_name()) + { + cnv->get_vehikel(i)->set_besch(vb); + update_convoy(); + goto end; + } + } + } + } } +end: if(!cnv.is_bound()) { // create a new convoi @@ -426,7 +444,10 @@ bool depot_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) icnv = depot->convoi_count() - 1; cnv->set_name((*convoy_assembler->get_vehicles())[0]->get_name()); } - depot->append_vehicle(cnv, veh, k.x == gui_convoy_assembler_t::insert_vehicle_in_front_action); + if(convoy_assembler->get_upgrade() == gui_convoy_assembler_t::u_buy) + { + depot->append_vehicle(cnv, veh, k.x == gui_convoy_assembler_t::insert_vehicle_in_front_action); + } break; } } else if(komp == &bt_start) { diff --git a/gui/replace_frame.cc b/gui/replace_frame.cc index fbfe258797d..8ceee600a9d 100644 --- a/gui/replace_frame.cc +++ b/gui/replace_frame.cc @@ -18,7 +18,7 @@ replace_frame_t::replace_frame_t(convoihandle_t cnv, const char *name): gui_frame_t(translator::translate("Replace"), cnv->get_besitzer()), - cnv(cnv), new_convoy_cost(0), + cnv(cnv), replace_line(false), replace_all(false), depot(false), autostart(true), state(state_replace), replaced_so_far(0), lb_convoy(cnv, true, true), @@ -78,8 +78,8 @@ replace_frame_t::replace_frame_t(convoihandle_t cnv, const char *name): if (cnv->get_vehikel_anzahl()>0) { // Should always be true wt=cnv->get_vehikel(0)->get_besch()->get_waytype(); } - const bool weg_electrified = true; // TODO: refine - convoy_assembler=new gui_convoy_assembler_t(cnv->get_welt(), wt, weg_electrified, cnv->get_besitzer()->get_player_nr() ); + const bool weg_electrified = cnv->get_welt()->lookup(cnv->get_vehikel(0)->get_pos())->get_weg(wt)->is_electrified(); + convoy_assembler = new gui_convoy_assembler_t(cnv->get_welt(), wt, weg_electrified, cnv->get_besitzer()->get_player_nr() ); convoy_assembler->set_convoy_tabs_skip(-2*LINESPACE+3*LINESPACE+2*margin+a_button_height); convoy_assembler->add_listener(this); convoy_assembler->set_vehicles(cnv->get_replacing_vehicles()); @@ -120,6 +120,8 @@ replace_frame_t::replace_frame_t(convoihandle_t cnv, const char *name): // Hajo: Trigger layouting set_resizemode(diagonal_resize); + + convoy_assembler->set_replace_frame(this); } @@ -263,10 +265,11 @@ void replace_frame_t::update_data() n[1]=0; n[2]=0; money = 0; + sint32 base_total_cost = calc_total_cost(); if (replace_line || replace_all) { start_replacing(); } else { - money=cnv->calc_restwert()-new_convoy_cost; + money -= base_total_cost; } if (replace_line) { linehandle_t line=cnv.is_bound()?cnv->get_line():linehandle_t(); @@ -278,9 +281,23 @@ void replace_frame_t::update_data() if (present_state==-1) { continue; } - money-=(present_state==state_replace?new_convoy_cost:0); - money+=(present_state==state_replace||present_state==state_sell?cnv_aux->calc_restwert():0); - n[present_state]++; + switch(convoy_assembler->get_action()) + { + + case gui_convoy_assembler_t::clear_convoy_action: + money = 0; + n[present_state]++; + break; + + case gui_convoy_assembler_t::remove_vehicle_action: + money += base_total_cost; + n[present_state]++; + break; + + default: + money -= base_total_cost; + n[present_state]++; + }; } } } @@ -288,14 +305,31 @@ void replace_frame_t::update_data() karte_t *welt=cnv->get_welt(); for (unsigned int i=0; i<welt->get_convoi_count(); i++) { convoihandle_t cnv_aux=welt->get_convoi(i); - if (cnv_aux.is_bound() && cnv_aux->get_besitzer()==cnv->get_besitzer() && cnv->has_same_vehicles(cnv_aux)) { - int present_state=get_present_state(); - if (present_state==-1) { - continue; - } - money-=(present_state==state_replace?new_convoy_cost:0); - money+=(present_state==state_replace||present_state==state_sell?cnv_aux->calc_restwert():0); + if (cnv_aux.is_bound() && cnv_aux->get_besitzer()==cnv->get_besitzer() && cnv->has_same_vehicles(cnv_aux)) + { + int present_state=get_present_state(); + if (present_state==-1) + { + continue; + } + + switch(convoy_assembler->get_action()) + { + + case gui_convoy_assembler_t::clear_convoy_action: + money = 0; n[present_state]++; + break; + + case gui_convoy_assembler_t::remove_vehicle_action: + money += base_total_cost; + n[present_state]++; + break; + + default: + money -= base_total_cost; + n[present_state]++; + }; } } } @@ -314,7 +348,7 @@ void replace_frame_t::update_data() } -int replace_frame_t::get_present_state() { +uint8 replace_frame_t::get_present_state() { if (numinp[state_replace].get_value()==0 && numinp[state_sell].get_value()==0 && numinp[state_skip].get_value()==0) { return -1; } @@ -359,6 +393,7 @@ void replace_frame_t::replace_convoy(convoihandle_t cnv) cnv->set_no_load(false); cnv->go_to_depot(false); } + //TODO: Add code for upgrading. break; case state_sell: @@ -378,17 +413,17 @@ bool replace_frame_t::action_triggered( gui_action_creator_t *komp,value_t p) if(komp != NULL) { // message from outside! if(komp == convoy_assembler) { const koord k=*static_cast<const koord *>(p.p); - switch (k.x) { - case gui_convoy_assembler_t::clear_convoy_action: - new_convoy_cost=0; - break; - case gui_convoy_assembler_t::remove_vehicle_action: - new_convoy_cost-=convoy_assembler->get_last_changed_vehicle()->get_preis(); - break; - default: // append/insert_in_front - new_convoy_cost+=convoy_assembler->get_last_changed_vehicle()->get_preis(); - break; - } + //switch (k.x) { + // case gui_convoy_assembler_t::clear_convoy_action: + // new_convoy_cost=0; + // break; + // case gui_convoy_assembler_t::remove_vehicle_action: + // new_convoy_cost-=convoy_assembler->get_last_changed_vehicle()->get_preis(); + // break; + // default: // append/insert_in_front + // new_convoy_cost+=convoy_assembler->get_last_changed_vehicle()->get_preis(); + // break; + //} } else if(komp == &bt_replace_line) { replace_line=!replace_line; replace_all=false; @@ -475,4 +510,72 @@ void replace_frame_t::zeichnen(koord pos, koord groesse) lb_skip.set_color(color); gui_frame_t::zeichnen(pos, groesse); +} + +sint32 replace_frame_t::calc_total_cost() +{ + sint32 total_cost = 0; + vector_tpl<const vehikel_t*> current_vehicles; + vector_tpl<uint8> keep_vehicles; + for(uint8 i = 0; i < cnv->get_vehikel_anzahl(); i ++) + { + current_vehicles.append(cnv->get_vehikel(i)); + } + ITERATE((*convoy_assembler->get_vehicles()),j) + { + const vehikel_besch_t* veh = NULL; + const vehikel_besch_t* test_new_vehicle = (*convoy_assembler->get_vehicles())[j]; + // First - check whether there are any of the required vehicles already + // in the convoy (free) + ITERATE(current_vehicles,k) + { + const vehikel_besch_t* test_old_vehicle = current_vehicles[k]->get_besch(); + if(!keep_vehicles.is_contained(k) && current_vehicles[k]->get_besch() == (*convoy_assembler->get_vehicles())[j]) + { + veh = current_vehicles[k]->get_besch(); + keep_vehicles.append_unique(k); + // No change to price here. + break; + } + } + + // We cannot look up the home depot here, so we cannot check whether there are any + // suitable vehicles stored there as is done when the actual replacing takes place. + + if (veh == NULL) + { + // Second - check whether the vehicle can be upgraded (cheap) + ITERATE(current_vehicles,l) + { + for(uint8 c = 0; c < current_vehicles[l]->get_besch()->get_upgrades_count(); c ++) + { + const vehikel_besch_t* possible_upgrade_test = current_vehicles[l]->get_besch()->get_upgrades(c); + if(!keep_vehicles.is_contained(l) && (*convoy_assembler->get_vehicles())[j] == current_vehicles[l]->get_besch()->get_upgrades(c)) + { + veh = current_vehicles[l]->get_besch(); + keep_vehicles.append_unique(l); + total_cost += veh->get_upgrades(c)->get_upgrade_price(); + goto end_loop; + } + } + } +end_loop: + if(veh == NULL) + { + // Third - if all else fails, buy from new (expensive). + total_cost += (*convoy_assembler->get_vehicles())[j]->get_preis(); + } + } + } + ITERATE(current_vehicles,m) + { + if(!keep_vehicles.is_contained(m)) + { + // This vehicle will not be kept after replacing - + // deduct its resale value from the total cost. + total_cost -= current_vehicles[m]->calc_restwert(); + } + } + + return total_cost; } \ No newline at end of file diff --git a/gui/replace_frame.h b/gui/replace_frame.h index 6118a51f854..f859bd9b4f3 100644 --- a/gui/replace_frame.h +++ b/gui/replace_frame.h @@ -33,15 +33,14 @@ class replace_frame_t : public gui_frame_t, * The convoy to be replaced */ convoihandle_t cnv; - sint32 new_convoy_cost; bool replace_line; // True if all convoys like this in its line are to be replaced bool replace_all; // True if all convoys like this are to be replaced bool depot; // True if convoy is to be sent to depot only bool autostart; // True if convoy is to be sent to depot and restarted automatically enum {state_replace=0, state_sell, state_skip, n_states}; - int state; - int replaced_so_far; + uint8 state; + uint8 replaced_so_far; sint32 money; /** @@ -88,10 +87,12 @@ class replace_frame_t : public gui_frame_t, void update_total_width(int width); void replace_convoy(convoihandle_t cnv); inline void start_replacing() {state=state_replace; replaced_so_far=0;} - int get_present_state(); + uint8 get_present_state(); karte_t* get_welt() { return cnv->get_welt(); } + sint32 calc_total_cost(); + public: replace_frame_t(convoihandle_t cnv, const char *name); virtual ~replace_frame_t(); @@ -128,6 +129,8 @@ class replace_frame_t : public gui_frame_t, */ bool action_triggered( gui_action_creator_t *komp, value_t extra); + const convoihandle_t get_convoy() const { return cnv; } + }; #endif \ No newline at end of file diff --git a/simconvoi.cc b/simconvoi.cc index 2ff65690fac..ea0c95a59f9 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -822,24 +822,86 @@ void convoi_t::step() const grund_t *gr = welt->lookup(home_depot); depot_t *dep; if ( gr && (dep=gr->get_depot()) ) { - bool keep_name=(anz_vehikel>0 && strcmp(get_name(),fahr[0]->get_besch()->get_name())!=0); - // Sell the old convoy - besitzer_p->buche( calc_restwert(), dep->get_pos().get_2d(), COST_NEW_VEHICLE ); - besitzer_p->buche( -calc_restwert(), COST_ASSETS ); - for(int i=anz_vehikel-1; i>=0; i--) { - delete fahr[i]; + bool keep_name=(anz_vehikel>0 && strcmp(get_name(),fahr[0]->get_besch()->get_name())!=0); + vector_tpl<vehikel_t*> new_vehicles; + + // Acquire the new one + ITERATE(replacing_vehicles,i) + { + vehikel_t* veh = NULL; + // First - check whether there are any of the required vehicles already + // in the convoy (free) + for(uint8 k = 0; k < anz_vehikel; k++) + { + if(fahr[k]->get_besch() == replacing_vehicles[i]) + { + veh = remove_vehikel_bei(k); + //keep_vehicles.append_unique(k); + break; + } + } + + // This part of the code is abandoned, as it causes problems: vehicles that have already been bought + // are added twice to the convoy, causing bizarre corruption issues. + /*if( veh == NULL) + { + //Second - check whether there are any of the required vehicles already + //in the depot (more or less free). + veh = dep->find_oldest_newest(replacing_vehicles[i], true); + }*/ + + if (veh == NULL) + { + // Third - check whether the vehicle can be upgraded (cheap) + for(uint16 j = 0; j < anz_vehikel; j ++) + { + + for(uint8 c = 0; c < fahr[j]->get_besch()->get_upgrades_count(); c ++) + { + if(replacing_vehicles[i] == fahr[j]->get_besch()->get_upgrades(c)) + { + veh = remove_vehikel_bei(j); + veh->set_besch(replacing_vehicles[i]); + dep->buy_vehicle(veh->get_besch(), true); + goto end_loop; + } + } + } +end_loop: + if(veh == NULL) + { + // Fourth - if all else fails, buy from new (expensive). + veh = dep->buy_vehicle(replacing_vehicles[i], false); + } + } + + //dep->append_vehicle(self, veh, false); + + // This new method is needed to enable this method to iterate over + // the existing vehicles in the convoy while it is adding new vehicles. + // They must be added to temporary storage, and appended to the existing + // convoy at the end, after the existing convoy has been deleted. + new_vehicles.append(veh); + + } + + //First, delete the existing convoy + for(sint8 a = anz_vehikel-1; a >= 0; a--) + { + //Sell any vehicles not upgraded or kept. + besitzer_p->buche( fahr[a]->calc_restwert(), dep->get_pos().get_2d(), COST_NEW_VEHICLE ); + besitzer_p->buche( -fahr[a]->calc_restwert(), COST_ASSETS ); + delete fahr[a]; } anz_vehikel = 0; reset(); - // Buy the new one - for (unsigned int i=0; i<replacing_vehicles.get_count(); ++i) { - vehikel_t* veh = dep->find_oldest_newest(replacing_vehicles[i], true); - if (veh == NULL) { - // nothing there => we buy it - veh = dep->buy_vehicle(replacing_vehicles[i]); - } - dep->append_vehicle(self, veh, false); + + //Next, add all the new vehicles to the convoy in order. + ITERATE(new_vehicles,b) + { + dep->append_vehicle(self, new_vehicles[b], false); } + if (!keep_name) { set_name(fahr[0]->get_besch()->get_name()); } diff --git a/simdepot.cc b/simdepot.cc index 47eb7353083..0a9827c089f 100644 --- a/simdepot.cc +++ b/simdepot.cc @@ -175,17 +175,21 @@ bool depot_t::can_convoi_start(convoihandle_t /*cnv*/) const } -vehikel_t* depot_t::buy_vehicle(const vehikel_besch_t* info) +vehikel_t* depot_t::buy_vehicle(const vehikel_besch_t* info, bool upgrade) { // Offen: prüfen ob noch platz im depot ist??? // "Hours: check whether there is space in the depot?" (Google) DBG_DEBUG("depot_t::buy_vehicle()", info->get_name()); - vehikel_t* veh = vehikelbauer_t::baue(get_pos(), get_besitzer(), NULL, info ); //"besitzer" = "owner" (Google) + vehikel_t* veh = vehikelbauer_t::baue(get_pos(), get_besitzer(), NULL, info, upgrade ); //"besitzer" = "owner" (Google) DBG_DEBUG("depot_t::buy_vehicle()", "vehiclebauer %p", veh); - vehicles.append(veh); - DBG_DEBUG("depot_t::buy_vehicle()", "appended %i vehicle", vehicles.get_count()); - return veh; + if(!upgrade) + { + vehicles.append(veh); + DBG_DEBUG("depot_t::buy_vehicle()", "appended %i vehicle", vehicles.get_count()); + return veh; + } + return NULL; } diff --git a/simdepot.h b/simdepot.h index 28fab977a37..2ed368a3644 100644 --- a/simdepot.h +++ b/simdepot.h @@ -134,7 +134,7 @@ class depot_t : public gebaeude_t * @author Volker Meyer * @date 09.06.2003 */ - vehikel_t* buy_vehicle(const vehikel_besch_t* info); + vehikel_t* buy_vehicle(const vehikel_besch_t* info, bool upgrade); /** * Sell a vehicle from the vehicle list. diff --git a/utils/log.cc b/utils/log.cc index 35697cc2b7e..ef001bb2048 100644 --- a/utils/log.cc +++ b/utils/log.cc @@ -194,7 +194,7 @@ void log_t::fatal(const char *who, const char *format, ...) va_end(argptr); -#define MAKEOBJ +//#define MAKEOBJ #ifdef MAKEOBJ // no display available puts( buffer ); diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index bb13a6ade86..e044762f34c 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -2045,6 +2045,10 @@ DBG_MESSAGE("vehicle_t::rdwr_from_convoi()","bought at %i/%i.",(insta_zeit%12)+1 total_freight += iter.get_current().menge; } } + // TODO - Add saves for: + // (1) whether vehicle is reversed; and + // (2) whether vehicle is to be upgrade-replaced. + } diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index 17a4914aaf4..df74a6dc11f 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -321,6 +321,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t * @author Hj. Malthaner */ const vehikel_besch_t *get_besch() const {return besch; } + void set_besch(const vehikel_besch_t* value) { besch = value; } /** * @return die Betriebskosten in Cr/100Km From db4ff5bbc283f09333b714eed25cfdb6f7b47be1 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 9 Mar 2009 15:53:19 +0000 Subject: [PATCH 34/61] Loading time for each vehicle can now be set by a value in each vehicle's .dat file in ms. The highest loading time of any vehicle in the convoy will be used for that vehicle's loading time. The default is the old value of 2000ms (2 secs at default speed). --- simconvoi.cc | 27 ++++++++++++++++++++++++--- simconvoi.h | 4 ++++ vehicle/simvehikel.cc | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/simconvoi.cc b/simconvoi.cc index ea0c95a59f9..ac558025d4c 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -128,6 +128,7 @@ void convoi_t::reset() sp_soll = 0; heaviest_vehicle = 0; + longest_loading_time = 0; } void convoi_t::init(karte_t *wl, spieler_t *sp) @@ -1313,6 +1314,7 @@ DBG_MESSAGE("convoi_t::add_vehikel()","extend array_tpl to %i totals.",max_rail_ set_erstes_letztes(); heaviest_vehicle = calc_heaviest_vehicle(); + longest_loading_time = calc_longest_loading_time(); DBG_MESSAGE("convoi_t::add_vehikel()","now %i of %i total vehikels.",anz_vehikel,max_vehicle); return true; @@ -1378,6 +1380,7 @@ convoi_t::remove_vehikel_bei(uint16 i) } heaviest_vehicle = calc_heaviest_vehicle(); + longest_loading_time = calc_longest_loading_time(); return v; } @@ -2201,8 +2204,9 @@ convoi_t::rdwr(loadsave_t *file) // (1) origin; // (2) last transfer; // (3) origin departure time; - // (4) last transfer departure time; and - // (5) whether the convoy is in reverse formation. + // (4) last transfer departure time; + // (5) whether the convoy is in reverse formation; and + // (6) how overcrowded that the vehicle is. // Then, reversion the save game file format. // no_load, withdraw @@ -2216,6 +2220,7 @@ convoi_t::rdwr(loadsave_t *file) } heaviest_vehicle = calc_heaviest_vehicle(); + longest_loading_time = calc_longest_loading_time(); //HACK: Should be loaded from file. reversed = false; @@ -2541,7 +2546,8 @@ void convoi_t::laden() //"load" (Babelfish) state = ROUTING_1; } // This is the minimum time it takes for loading - wait_lock = WTT_LOADING; + //wait_lock = WTT_LOADING; + wait_lock = longest_loading_time; } @@ -3228,4 +3234,19 @@ convoi_t::calc_heaviest_vehicle() } } return heaviest; +} + +uint16 +convoi_t::calc_longest_loading_time() +{ + uint16 longest = 0; + for(uint8 i = 0; i < anz_vehikel; i ++) + { + uint16 tmp = fahr[i]->get_besch()->get_loading_time(); + if(tmp > longest) + { + longest = tmp; + } + } + return longest; } \ No newline at end of file diff --git a/simconvoi.h b/simconvoi.h index b6446e2bab3..dfc7bd1540e 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -386,6 +386,7 @@ class convoi_t : public sync_steppable, public overtaker_t bool reversed; uint32 heaviest_vehicle; + uint16 longest_loading_time; public: @@ -860,6 +861,9 @@ class convoi_t : public sync_steppable, public overtaker_t uint32 calc_heaviest_vehicle(); uint32 get_heaviest_vehicle() const { return heaviest_vehicle; } + + uint16 calc_longest_loading_time(); + uint16 get_longest_loading_time() const { return longest_loading_time; } }; #endif diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 46b9fccbf1e..ce4568ef521 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -2655,7 +2655,7 @@ waggon_t::set_convoi(convoi_t *c) if(c->get_state()>=convoi_t::WAITING_FOR_CLEARANCE) { // DBG_MESSAGE("waggon_t::set_convoi()","new route %p, route_index %i",c->get_route(),route_index); // find about next signal after loading - uint16 next_signal_index=65535; + uint16 next_signal_index=65535; route_t *route=c->get_route(); if(route->empty() || get_pos()==route->position_bei(route->get_max_n())) { From 4521673bc91011eb9ef333f9f27f1fedf75e4705 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 9 Mar 2009 19:00:57 +0000 Subject: [PATCH 35/61] Added the loading time to the GUI in the depot window --- gui/components/gui_convoy_assembler.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gui/components/gui_convoy_assembler.cc b/gui/components/gui_convoy_assembler.cc index 94a2ec03201..c6c1c667c9b 100644 --- a/gui/components/gui_convoy_assembler.cc +++ b/gui/components/gui_convoy_assembler.cc @@ -1218,7 +1218,9 @@ void gui_convoy_assembler_t::draw_vehicle_info_text(koord pos) // column 2 - int j = sprintf(buf, "%s %s %04d\n", + int j = sprintf(buf, "%s %i \n", translator::translate("Loading time:"), veh_type->get_loading_time()); + + j += sprintf(buf + j, "%s %s %04d\n", translator::translate("Intro. date:"), translator::get_month_name(veh_type->get_intro_year_month()%12), veh_type->get_intro_year_month()/12 ); @@ -1234,15 +1236,16 @@ void gui_convoy_assembler_t::draw_vehicle_info_text(koord pos) j+= sprintf(buf + j, "%s %0.2f : 1\n", translator::translate("Gear: "), veh_type->get_gear()/64.0); } - if(veh_type->get_copyright()!=NULL && veh_type->get_copyright()[0]!=0) - { - j += sprintf(buf + j, translator::translate("Constructed by %s\n"), veh_type->get_copyright()); - } if(veh_type->get_tilting()) { j += sprintf(buf + j, translator::translate("This is a tilting vehicle\n")); } + if(veh_type->get_copyright()!=NULL && veh_type->get_copyright()[0]!=0) + { + j += sprintf(buf + j, translator::translate("Constructed by %s\n"), veh_type->get_copyright()); + } + if(value != -1) { sprintf(buf + strlen(buf), "%s %d Cr", translator::translate("Restwert: "), value); //"Restwert" = residual (Google) From bd6249a8ca7686b37eb6906b050f8d2b7189c2dd Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 9 Mar 2009 23:52:55 +0000 Subject: [PATCH 36/61] Minor improvements to reversing and loading time. --- besch/reader/vehicle_reader.cc | 2 +- besch/vehikel_besch.h | 2 +- besch/writer/vehicle_writer.cc | 2 +- dataobj/einstellungen.cc | 8 +++++--- gui/components/gui_convoy_assembler.cc | 14 +++++++++++++- simconvoi.cc | 7 ++++--- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/besch/reader/vehicle_reader.cc b/besch/reader/vehicle_reader.cc index eb8a09591ea..f54a1b3ddf0 100644 --- a/besch/reader/vehicle_reader.cc +++ b/besch/reader/vehicle_reader.cc @@ -274,7 +274,7 @@ vehicle_reader_t::read_node(FILE *fp, obj_node_info_t &node) besch->catering_level = 0; besch->bidirectional = false; besch->can_lead_from_rear = false; - besch->comfort = 1; + besch->comfort = 100; besch->overcrowded_capacity = 0; besch->loading_time = 2000; besch->upgrades = 0; diff --git a/besch/vehikel_besch.h b/besch/vehikel_besch.h index a9afc8c3b96..d6bf7a937ac 100644 --- a/besch/vehikel_besch.h +++ b/besch/vehikel_besch.h @@ -278,7 +278,7 @@ class vehikel_besch_t : public obj_besch_std_name_t { bool get_can_lead_from_rear() const { return can_lead_from_rear; } uint8 get_comfort() const { return comfort; } uint16 get_overcrowded_capacity() const { return overcrowded_capacity; } - uint16 get_loading_time() const { return loading_time; } + uint16 get_loading_time() const { return zuladung > 0 ? loading_time : 0; } uint32 get_upgrade_price() const { return upgrade_price; } bool is_available_only_as_upgrade() const { return available_only_as_upgrade; } diff --git a/besch/writer/vehicle_writer.cc b/besch/writer/vehicle_writer.cc index 03224be6c85..6b516061072 100644 --- a/besch/writer/vehicle_writer.cc +++ b/besch/writer/vehicle_writer.cc @@ -439,7 +439,7 @@ void vehicle_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj // Passenger comfort rating - affects revenue on longer journies. //@author: jamespetts - uint8 comfort = (obj.get_int("ccomfort", 1)); + uint8 comfort = (obj.get_int("comfort", 100)); node.write_uint8(fp, comfort, 37); // Overcrowded capacity - can take this much *in addition to* normal capacity, diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index 215962fa126..36a74b933ab 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -476,6 +476,8 @@ void einstellungen_t::rdwr(loadsave_t *file) if(file->get_version()>102000) { file->rdwr_bool( avoid_overcrowding, "" ); } + + //TODO: Add *all* Simutrans-Experimental settings here. } } @@ -715,9 +717,9 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s allow_purhcases_when_insolvent = contents.get_int("allow_purhcases_when_insolvent", 0); //Reversing settings - unit_reverse_time = contents.get_int("unit_reverse_time", 1500); - hauled_reverse_time = contents.get_int("hauled_reverse_time", 2500); - turntable_reverse_time = contents.get_int("turntable_reverse_time", 4000); + unit_reverse_time = contents.get_int("unit_reverse_time", 0); + hauled_reverse_time = contents.get_int("hauled_reverse_time", 0); + turntable_reverse_time = contents.get_int("turntable_reverse_time", 0); /* * Selection of savegame format through inifile diff --git a/gui/components/gui_convoy_assembler.cc b/gui/components/gui_convoy_assembler.cc index c6c1c667c9b..61c705e448b 100644 --- a/gui/components/gui_convoy_assembler.cc +++ b/gui/components/gui_convoy_assembler.cc @@ -1218,7 +1218,19 @@ void gui_convoy_assembler_t::draw_vehicle_info_text(koord pos) // column 2 - int j = sprintf(buf, "%s %i \n", translator::translate("Loading time:"), veh_type->get_loading_time()); + int j = 0; + + if(veh_type->get_zuladung() > 0) + { + //Loading time is only relevant if there is something to load. + j += sprintf(buf, "%s %i \n", translator::translate("Loading time:"), veh_type->get_loading_time()); + } + + if(veh_type->get_ware()->get_catg_index() == 0) + { + //Comfort only applies to passengers. + j += sprintf(buf + j, "%s %i \n", translator::translate("Comfort:"), veh_type->get_comfort()); + } j += sprintf(buf + j, "%s %s %04d\n", translator::translate("Intro. date:"), diff --git a/simconvoi.cc b/simconvoi.cc index ac558025d4c..4d3af8bcab0 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -1199,7 +1199,7 @@ void convoi_t::ziel_erreicht() if(reversed) { //Always enter a depot facing forward - reversable = fahr[anz_vehikel - 1]->get_besch()->get_can_lead_from_rear(); + reversable = fahr[anz_vehikel - 1]->get_besch()->get_can_lead_from_rear() || (anz_vehikel == 1 && fahr[0]->get_besch()->is_bidirectional()); reverse_order(reversable); } @@ -1658,11 +1658,11 @@ convoi_t::vorfahren() //"move forward" (Babelfish) default: if(reversed) { - reversable = fahr[0]->get_besch()->get_can_lead_from_rear(); + reversable = fahr[0]->get_besch()->get_can_lead_from_rear() || (anz_vehikel == 1 && fahr[0]->get_besch()->is_bidirectional()); } else { - reversable = fahr[anz_vehikel - 1]->get_besch()->get_can_lead_from_rear(); + reversable = fahr[anz_vehikel - 1]->get_besch()->get_can_lead_from_rear() || (anz_vehikel == 1 && fahr[0]->get_besch()->is_bidirectional()); } if(reversable) @@ -1747,6 +1747,7 @@ convoi_t::vorfahren() //"move forward" (Babelfish) train_length += (v->get_besch()->get_length()); // this give the length in 1/TILE_STEPS of a full tile => all cars closely coupled! v->darf_rauchen(true); } + train_length -= fahr[anz_vehikel - 1]->get_besch()->get_length(); } else From 92f6c36ece4415a2fd580ad5875e3f32e4110ad6 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 15 Mar 2009 23:42:48 +0000 Subject: [PATCH 37/61] New Simutrans-Experimental specific save game version. Now saves data about (1) reversed state; (2) vehicle replacing; (3) origins and timings; (4) weight limits; and (5) settings. --- boden/wege/weg.cc | 9 ++- dataobj/einstellungen.cc | 165 +++++++++++++++++++++++++++++++++------ dataobj/loadsave.cc | 98 +++++++++++++++++++---- dataobj/loadsave.h | 13 ++- gui/halt_detail.cc | 1 - gui/replace_frame.cc | 1 - simcity.h | 2 +- simconvoi.cc | 94 +++++++++++++++++++--- simconvoi.h | 13 +++ simmain.cc | 2 +- simversion.h | 4 + simware.cc | 41 ++++++++-- simworld.cc | 2 +- tpl/fixed_list_tpl.h | 12 +-- vehicle/simvehikel.cc | 11 ++- 15 files changed, 394 insertions(+), 74 deletions(-) diff --git a/boden/wege/weg.cc b/boden/wege/weg.cc index a5d59249424..4698fd97f84 100644 --- a/boden/wege/weg.cc +++ b/boden/wege/weg.cc @@ -242,8 +242,6 @@ void weg_t::rdwr(loadsave_t *file) file->rdwr_short(dummy16, "\n"); max_speed=dummy16; - //TODO: Implement load/save for weight limits - if(file->get_version()>=89000) { dummy8 = flags; file->rdwr_byte(dummy8,"f"); @@ -261,6 +259,13 @@ void weg_t::rdwr(loadsave_t *file) // DBG_DEBUG("weg_t::rdwr()", "statistics[%d][%d]=%d", month, type, statistics[month][type]); } } + + if(file->get_experimental_version() >= 1) + { + uint16 wdummy16 = max_weight; + file->rdwr_short(wdummy16, "\n"); + max_weight = wdummy16; + } } diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index 4a56d886e39..c7490a50c03 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -175,26 +175,50 @@ einstellungen_t::einstellungen_t() : seperate_halt_capacities = false; // Local bonus adjustment - uint16 min_bonus_max_distance = 16; - uint16 max_bonus_min_distance = 256; - uint16 local_bonus_multiplier = 10; + min_bonus_max_distance = 16; + max_bonus_min_distance = 256; + local_bonus_multiplier = 10; // Obsolete vehicles running costs adjustment - uint16 obsolete_running_cost_increase_percent = 400; //Running costs will be this % of normal costs after vehicle has been obsolete - uint16 obsolete_running_cost_increase_phase_years = 20; //for this number of years. + obsolete_running_cost_increase_percent = 400; //Running costs will be this % of normal costs after vehicle has been obsolete + obsolete_running_cost_increase_phase_years = 20; //for this number of years. // Passenger destination ranges - uint16 local_passengers_min_distance = 0; - uint16 local_passengers_max_distance = 64; - uint16 midrange_passengers_min_distance = 0; - uint16 midrange_passengers_max_distance = 128; - uint16 longdistance_passengers_min_distance = 0; - uint16 longdistance_passengers_max_distance = 4096; + local_passengers_min_distance = 0; + local_passengers_max_distance = 64; + midrange_passengers_min_distance = 0; + midrange_passengers_max_distance = 128; + longdistance_passengers_min_distance = 0; + longdistance_passengers_max_distance = 4096; // Passenger routing settings - uint8 passenger_routing_packet_size = 7; - uint8 max_alternative_destinations = 3; + passenger_routing_packet_size = 7; + max_alternative_destinations = 3; + + always_prefer_car_percent = 10; + base_car_preference_percent = 90; + congestion_density_factor = 12; + + //@author: jamespetts + // Passenger routing settings + passenger_routing_packet_size = 7; + + //@author: jamespetts + // Factory retirement settings + factory_max_years_obsolete = 30; + + //@author: jamespetts + // Insolvency and debt settings + interest_rate_percent = 10; + allow_bankruptsy = 0; + allow_purhcases_when_insolvent = 0; + + // Reversing settings + //@author: jamespetts + unit_reverse_time = 0; + hauled_reverse_time = 0; + turntable_reverse_time = 0; // this will pay for distance to next change station @@ -482,7 +506,100 @@ void einstellungen_t::rdwr(loadsave_t *file) file->rdwr_bool( no_routing_over_overcrowding, "" ); } - //TODO: Add *all* Simutrans-Experimental settings here. + if(file->get_experimental_version() >= 1) + { + file->rdwr_short(min_bonus_max_distance, ""); + file->rdwr_short(max_bonus_min_distance, ""); + file->rdwr_short(local_bonus_multiplier, ""); + + file->rdwr_short(obsolete_running_cost_increase_percent, ""); + file->rdwr_short(obsolete_running_cost_increase_phase_years, ""); + + file->rdwr_short(local_passengers_min_distance, ""); + file->rdwr_short(local_passengers_max_distance, ""); + file->rdwr_short(midrange_passengers_min_distance, ""); + file->rdwr_short(midrange_passengers_max_distance, ""); + file->rdwr_short(longdistance_passengers_min_distance, ""); + file->rdwr_short(longdistance_passengers_max_distance, ""); + + file->rdwr_byte(passenger_routing_packet_size, ""); + file->rdwr_byte(max_alternative_destinations, ""); + file->rdwr_byte(passenger_routing_local_chance, ""); + file->rdwr_byte(passenger_routing_midrange_chance, ""); + file->rdwr_byte(base_car_preference_percent, ""); + file->rdwr_byte(always_prefer_car_percent, ""); + file->rdwr_byte(congestion_density_factor, ""); + + file->rdwr_long(max_corner_limit[waytype_t(road_wt)], ""); + file->rdwr_long(min_corner_limit[waytype_t(road_wt)], ""); + double tmp = (double)max_corner_adjustment_factor[waytype_t(road_wt)]; + file->rdwr_double(tmp); + tmp = (double)min_corner_adjustment_factor[waytype_t(road_wt)]; + file->rdwr_double(tmp); + file->rdwr_byte(min_direction_steps[waytype_t(road_wt)], ""); + file->rdwr_byte(max_direction_steps[waytype_t(road_wt)], ""); + file->rdwr_byte(curve_friction_factor[waytype_t(road_wt)], ""); + + file->rdwr_long(max_corner_limit[waytype_t(track_wt)], ""); + file->rdwr_long(min_corner_limit[waytype_t(track_wt)], ""); + tmp = (double)max_corner_adjustment_factor[waytype_t(track_wt)]; + file->rdwr_double(tmp); + tmp = (double)min_corner_adjustment_factor[waytype_t(track_wt)]; + file->rdwr_double(tmp); + file->rdwr_byte(min_direction_steps[waytype_t(track_wt)], ""); + file->rdwr_byte(max_direction_steps[waytype_t(track_wt)], ""); + file->rdwr_byte(curve_friction_factor[waytype_t(track_wt)], ""); + + file->rdwr_long(max_corner_limit[waytype_t(tram_wt)], ""); + file->rdwr_long(min_corner_limit[waytype_t(tram_wt)], ""); + tmp = (double)max_corner_adjustment_factor[waytype_t(tram_wt)]; + file->rdwr_double(tmp); + tmp = (double)min_corner_adjustment_factor[waytype_t(tram_wt)]; + file->rdwr_double(tmp); + file->rdwr_byte(min_direction_steps[waytype_t(tram_wt)], ""); + file->rdwr_byte(max_direction_steps[waytype_t(tram_wt)], ""); + file->rdwr_byte(curve_friction_factor[waytype_t(tram_wt)], ""); + + file->rdwr_long(max_corner_limit[waytype_t(monorail_wt)], ""); + file->rdwr_long(min_corner_limit[waytype_t(monorail_wt)], ""); + tmp = (double)max_corner_adjustment_factor[waytype_t(monorail_wt)]; + file->rdwr_double(tmp); + tmp = (double)min_corner_adjustment_factor[waytype_t(monorail_wt)]; + file->rdwr_double(tmp); + file->rdwr_byte(min_direction_steps[waytype_t(monorail_wt)], ""); + file->rdwr_byte(max_direction_steps[waytype_t(monorail_wt)], ""); + file->rdwr_byte(curve_friction_factor[waytype_t(monorail_wt)], ""); + + file->rdwr_long(max_corner_limit[waytype_t(maglev_wt)], ""); + file->rdwr_long(min_corner_limit[waytype_t(maglev_wt)], ""); + tmp = (double)max_corner_adjustment_factor[waytype_t(maglev_wt)]; + file->rdwr_double(tmp); + tmp = (double)min_corner_adjustment_factor[waytype_t(maglev_wt)]; + file->rdwr_double(tmp); + file->rdwr_byte(min_direction_steps[waytype_t(maglev_wt)], ""); + file->rdwr_byte(max_direction_steps[waytype_t(maglev_wt)], ""); + file->rdwr_byte(curve_friction_factor[waytype_t(maglev_wt)], ""); + + file->rdwr_long(max_corner_limit[waytype_t(narrowgauge_wt)], ""); + file->rdwr_long(min_corner_limit[waytype_t(narrowgauge_wt)], ""); + tmp = (double)max_corner_adjustment_factor[waytype_t(narrowgauge_wt)]; + file->rdwr_double(tmp); + tmp = min_corner_adjustment_factor[waytype_t(narrowgauge_wt)]; + file->rdwr_double(tmp); + file->rdwr_byte(min_direction_steps[waytype_t(narrowgauge_wt)], ""); + file->rdwr_byte(max_direction_steps[waytype_t(narrowgauge_wt)], ""); + file->rdwr_byte(curve_friction_factor[waytype_t(narrowgauge_wt)], ""); + + file->rdwr_short(factory_max_years_obsolete, ""); + + file->rdwr_byte(interest_rate_percent, ""); + file->rdwr_bool(allow_bankruptsy, ""); + file->rdwr_bool(allow_purhcases_when_insolvent, ""); + + file->rdwr_short(unit_reverse_time, ""); + file->rdwr_short(hauled_reverse_time, ""); + file->rdwr_short(turntable_reverse_time, ""); + } } } @@ -654,9 +771,9 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s max_alternative_destinations = contents.get_int("max_alternative_destinations", max_alternative_destinations); passenger_routing_local_chance = contents.get_int("passenger_routing_local_chance ", passenger_routing_local_chance); passenger_routing_midrange_chance = contents.get_int("passenger_routing_midrange_chance", passenger_routing_midrange_chance); - base_car_preference_percent = contents.get_int("base_car_preference_percent", 90); - always_prefer_car_percent = contents.get_int("always_prefer_car_percent", 10); - congestion_density_factor = contents.get_int("congestion_density_factor", 12); + base_car_preference_percent = contents.get_int("base_car_preference_percent", base_car_preference_percent); + always_prefer_car_percent = contents.get_int("always_prefer_car_percent", always_prefer_car_percent); + congestion_density_factor = contents.get_int("congestion_density_factor", congestion_density_factor); //Cornering settings max_corner_limit[waytype_t(road_wt)] = contents.get_int("max_corner_limit_road", 200); @@ -716,18 +833,18 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s curve_friction_factor[waytype_t(narrowgauge_wt)] = contents.get_int("curve_friction_factor_narrowgauge", 0); //Factory settings - factory_max_years_obsolete = contents.get_int("max_years_obsolete", 30); + factory_max_years_obsolete = contents.get_int("max_years_obsolete", factory_max_years_obsolete); //@author: jamespetts // Insolvency and debt settings - interest_rate_percent = contents.get_int("interest_rate_percent", 10); - allow_bankruptsy = contents.get_int("allow_bankruptsy", 0); - allow_purhcases_when_insolvent = contents.get_int("allow_purhcases_when_insolvent", 0); + interest_rate_percent = contents.get_int("interest_rate_percent", interest_rate_percent); + allow_bankruptsy = contents.get_int("allow_bankruptsy", allow_bankruptsy); + allow_purhcases_when_insolvent = contents.get_int("allow_purhcases_when_insolvent", allow_purhcases_when_insolvent); //Reversing settings - unit_reverse_time = contents.get_int("unit_reverse_time", 0); - hauled_reverse_time = contents.get_int("hauled_reverse_time", 0); - turntable_reverse_time = contents.get_int("turntable_reverse_time", 0); + unit_reverse_time = contents.get_int("unit_reverse_time", unit_reverse_time); + hauled_reverse_time = contents.get_int("hauled_reverse_time", hauled_reverse_time); + turntable_reverse_time = contents.get_int("turntable_reverse_time", turntable_reverse_time); /* * Selection of savegame format through inifile diff --git a/dataobj/loadsave.cc b/dataobj/loadsave.cc index f84fe15c0fc..81b541d1015 100644 --- a/dataobj/loadsave.cc +++ b/dataobj/loadsave.cc @@ -18,9 +18,16 @@ loadsave_t::mode_t loadsave_t::save_mode = zipped; // default to use for saving +loadsave_t::loadsave_t(bool experimental) : filename() +{ + fp = NULL; + save_experimental = experimental; +} + loadsave_t::loadsave_t() : filename() { fp = NULL; + save_experimental = true; } loadsave_t::~loadsave_t() @@ -33,6 +40,7 @@ bool loadsave_t::rd_open(const char *filename) close(); version = 0; + experimental_version = 0; fp = (FILE *)gzopen(filename, "rb"); if(!fp) { return false; @@ -70,7 +78,10 @@ bool loadsave_t::rd_open(const char *filename) } *s = 0; int dummy; - version = int_version(str, &dummy, pak_extension); + + combined_version versions = int_version(str, &dummy, pak_extension); + version = versions.version; + experimental_version = versions.experimental_version; read( buf, sizeof(" pak=\"")-1 ); s = pak_extension; @@ -86,7 +97,9 @@ bool loadsave_t::rd_open(const char *filename) } } else { - version = int_version(buf + sizeof(SAVEGAME_PREFIX) - 1, &mode, pak_extension); + combined_version versions = int_version(buf + sizeof(SAVEGAME_PREFIX) - 1, &mode, pak_extension); + version = versions.version; + experimental_version = versions.experimental_version; } if(mode==text) { close(); @@ -135,6 +148,21 @@ bool loadsave_t::wr_open(const char *filename, mode_t m, const char *pak_extensi const char *start = pak_extension; const char *end = pak_extension + strlen(pak_extension)-1; const char *c = pak_extension; + + // Use Experimental version numbering if appropriate. + char *savegame_version; + char *savegame_ver_nr; + if(save_experimental) + { + savegame_version = EXPERIMENTAL_SAVEGAME_VERSION; + savegame_ver_nr = COMBINED_VER_NR; + } + else + { + savegame_version = SAVEGAME_VERSION; + savegame_ver_nr = SAVEGAME_VER_NR; + } + // find the start while(*c<*end) { if(*c==':' || *c=='\\' || *c=='/') { @@ -149,20 +177,22 @@ bool loadsave_t::wr_open(const char *filename, mode_t m, const char *pak_extensi if( !is_xml() ) { if(is_zipped()) { - gzprintf(fp, "%s%s%s\n", SAVEGAME_VERSION, "zip", this->pak_extension); + gzprintf(fp, "%s%s%s\n", savegame_version, "zip", this->pak_extension); } else { - fprintf(fp, "%s%s%s\n", SAVEGAME_VERSION, mode == binary ? "bin" : "", this->pak_extension); + fprintf(fp, "%s%s%s\n", savegame_version, mode == binary ? "bin" : "", this->pak_extension); } } else { char str[4096]; - int n = sprintf( str, "<?xml version=\"1.0\"?>\n<Simutrans version=\"%s\" pak=\"%s\">\n", SAVEGAME_VER_NR, this->pak_extension ); + int n = sprintf( str, "<?xml version=\"1.0\"?>\n<Simutrans version=\"%s\" pak=\"%s\">\n", savegame_ver_nr, this->pak_extension ); write( str, n ); ident = 1; } - version = int_version(SAVEGAME_VER_NR, NULL, NULL ); + combined_version versions = int_version(savegame_ver_nr, NULL, NULL ); + version = versions.version; + experimental_version = versions.experimental_version; this->mode = mode; this->filename = filename; @@ -447,6 +477,7 @@ void loadsave_t::rdwr_xml_number(sint64 &s, const char *typ) this->write( nr, strlen(nr) ); } else { + uint32 test = get_version(); const int len = (int)strlen(typ); assert(len<256); // find start of tag @@ -777,15 +808,21 @@ void loadsave_t::rd_obj_id(char *id_buf, int size) } -uint32 loadsave_t::int_version(const char *version_text, int *mode, char *pak_extension) -{ +loadsave_t::combined_version loadsave_t::int_version(const char *version_text, int *mode, char *pak_extension) +{ + uint32 version; + uint32 experimental_version = 0; + // major number (0..) uint32 v0 = atoi(version_text); while(*version_text && *version_text++ != '.') ; if(!*version_text) { dbg->fatal( "loadsave_t::int_version()","Really broken version string!" ); - return 0; + combined_version dud; + dud.version = 0; + dud.experimental_version = 0; + return dud; } // middle number (.99.) @@ -794,12 +831,42 @@ uint32 loadsave_t::int_version(const char *version_text, int *mode, char *pak_ex ; if(!*version_text) { dbg->fatal( "loadsave_t::int_version()","Really broken version string!" ); - return 0; + combined_version dud; + dud.version = 0; + dud.experimental_version = 0; + return dud; } // minor number (..08) uint32 v2 = atoi(version_text); - uint32 version = v0 * 1000000 + v1 * 1000 + v2; + uint16 count = 0; + while(*version_text && *version_text++ != '.') + { + count++; + } + if(!*version_text) + { + experimental_version = 0; + // Decrement the pointer if this is not an Experimental version. + //*version_text -= count; + while(count > 0) + { + *version_text --; + count--; + } + } + else + { + experimental_version = atoi(version_text); + while(count > 0) + { + *version_text --; + count--; + } + } + + + version = v0 * 1000000 + v1 * 1000 + v2; if(mode) { while(*version_text && *version_text != 'b' && *version_text != 'z') { @@ -814,7 +881,7 @@ uint32 loadsave_t::int_version(const char *version_text, int *mode, char *pak_ex } // also pak extension was saved - if(version>=99008) { + if(version >= 99008) { if(*mode!=text) { version_text += 3; } @@ -825,9 +892,12 @@ uint32 loadsave_t::int_version(const char *version_text, int *mode, char *pak_ex *pak_extension = 0; } - return version; -} + combined_version loadsave_version; + loadsave_version.version = version; + loadsave_version.experimental_version = experimental_version; + return loadsave_version; +} void loadsave_t::start_tag(const char *tag) diff --git a/dataobj/loadsave.h b/dataobj/loadsave.h index 7f9b82fca96..526871924b1 100644 --- a/dataobj/loadsave.h +++ b/dataobj/loadsave.h @@ -36,7 +36,8 @@ class loadsave_t { private: int mode; bool saving; - int version; + uint32 version; + uint32 experimental_version; int ident; // only for XML formatting char pak_extension[64]; // name of the pak folder during savetime @@ -54,10 +55,16 @@ class loadsave_t { void rdwr_xml_number(sint64 &s, const char *typ); + bool save_experimental; + public: + + struct combined_version { uint32 version; uint32 experimental_version; }; + static mode_t save_mode; // default to use for saving - static uint32 int_version(const char *version_text, int *mode, char *pak); + static combined_version int_version(const char *version_text, int *mode, char *pak); + loadsave_t(bool experimental); loadsave_t(); ~loadsave_t(); @@ -78,7 +85,9 @@ class loadsave_t { bool is_zipped() const { return mode&zipped; } bool is_xml() const { return mode&xml; } uint32 get_version() const { return version; } + uint32 get_experimental_version() const { return experimental_version; } const char *get_pak_extension() const { return pak_extension; } + bool get_save_experimental() const { return save_experimental; } void rdwr_byte(sint8 &c, const char *delim); void rdwr_byte(uint8 &c, const char *delim); diff --git a/gui/halt_detail.cc b/gui/halt_detail.cc index b283e023f7f..66693539f3c 100644 --- a/gui/halt_detail.cc +++ b/gui/halt_detail.cc @@ -275,7 +275,6 @@ bool halt_detail_t::action_triggered( gui_action_creator_t *, value_t extra) linehandle_t line=halt->registered_lines[j]; spieler_t *sp=halt->get_welt()->get_active_player(); if( sp==line->get_besitzer() ) { - //TODO: // Change player => change marked lines sp->simlinemgmt.show_lineinfo(sp,line); halt->get_welt()->set_dirty(); diff --git a/gui/replace_frame.cc b/gui/replace_frame.cc index a67cd19ce39..e775946ce0a 100644 --- a/gui/replace_frame.cc +++ b/gui/replace_frame.cc @@ -393,7 +393,6 @@ void replace_frame_t::replace_convoy(convoihandle_t cnv) cnv->set_no_load(false); cnv->go_to_depot(false); } - //TODO: Add code for upgrading. break; case state_sell: diff --git a/simcity.h b/simcity.h index 2ccf4fc92e0..0f96c03d698 100644 --- a/simcity.h +++ b/simcity.h @@ -169,7 +169,7 @@ class stadt_t slist_tpl<stadtauto_t *> current_cars; - int route_result; + uint8 route_result; public: /** diff --git a/simconvoi.cc b/simconvoi.cc index 4d3af8bcab0..7a3684b6adc 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -502,7 +502,11 @@ void convoi_t::calc_acceleration(long delta_t) delta_v += previous_delta_v; previous_delta_v = delta_v & 0x0FFF; // and finally calculate new speed +#ifdef TEST_SPEED + akt_speed = kmh_to_speed(10); +#else akt_speed = max(akt_speed_soll>>4, akt_speed+(sint32)(delta_v>>12l) ); + } else { // very old vehicle ... @@ -515,6 +519,7 @@ void convoi_t::calc_acceleration(long delta_t) if(akt_speed > akt_speed_soll+kmh_to_speed(20)) { akt_speed = akt_speed_soll+kmh_to_speed(20); } +#endif } // new record? @@ -757,6 +762,19 @@ bool convoi_t::sync_step(long delta_t) break; } +#ifdef TEST_SPEED + + speed_testing tmp; + tmp.ticks = welt->get_steps(); + tmp.tile = fahr[0]->get_pos().get_2d(); + if(ticks_per_tile.get_count() < 1 || ((tmp.tile.x != ticks_per_tile[0].tile.x) || (tmp.tile.y != ticks_per_tile[0].tile.y))) + { + ticks_per_tile.add_to_head(tmp); + } + + +#endif + return true; } @@ -1040,6 +1058,8 @@ void convoi_t::step() default: /* keeps compiler silent*/ break; } + + } @@ -1912,7 +1932,7 @@ convoi_t::rdwr(loadsave_t *file) } file->rdwr_long(wait_lock, " "); - // some versions may produce broken safegames apparently + // some versions may produce broken savegames apparently if(wait_lock > 60000) { dbg->warning("convoi_t::sync_prepre()","Convoi %d: wait lock out of bounds: wait_lock = %d, setting to 60000",self.get_id(), wait_lock); wait_lock = 60000; @@ -2201,14 +2221,7 @@ convoi_t::rdwr(loadsave_t *file) set_tiles_overtaking( tiles_overtaking ); } - // TODO: Add load/save parameters for: - // (1) origin; - // (2) last transfer; - // (3) origin departure time; - // (4) last transfer departure time; - // (5) whether the convoy is in reverse formation; and - // (6) how overcrowded that the vehicle is. - // Then, reversion the save game file format. + // no_load, withdraw if(file->get_version()<102001) { @@ -2219,12 +2232,66 @@ convoi_t::rdwr(loadsave_t *file) file->rdwr_bool( no_load, "" ); file->rdwr_bool( withdraw, "" ); } + + // Simutrans-Experimental specific parameters. + // Must *always* go after standard parameters. heaviest_vehicle = calc_heaviest_vehicle(); longest_loading_time = calc_longest_loading_time(); - - //HACK: Should be loaded from file. - reversed = false; + + if(file->get_experimental_version() >= 1) + { + file->rdwr_bool(reversed, ""); + + //Replacing settings + file->rdwr_bool(replace, ""); + file->rdwr_bool(autostart, ""); + file->rdwr_bool(depot_when_empty, ""); + + uint16 replacing_vehicles_count; + + if(file->is_saving()) + { + replacing_vehicles_count = replacing_vehicles.get_count(); + file->rdwr_short(replacing_vehicles_count, ""); + ITERATE(replacing_vehicles, i) + { + const char *s = replacing_vehicles[i]->get_name(); + file->rdwr_str(s); + } + } + else + { + + file->rdwr_short(replacing_vehicles_count, ""); + for(uint16 i = 0; i < replacing_vehicles_count; i ++) + { + char vehicle_name[256]; + file->rdwr_str(vehicle_name, 256); + const vehikel_besch_t* besch = vehikelbauer_t::get_info(vehicle_name); + if(besch == NULL) + { + besch = vehikelbauer_t::get_info(translator::compatibility_name(vehicle_name)); + } + if(besch == NULL) + { + dbg->warning("convoi_t::rdwr()","no vehicle pak for '%s' search for something similar", vehicle_name); + } + else + { + replacing_vehicles.append(besch); + } + } + } + + + + // TODO: Add load/save parameters for: + // (1) origin; + // (2) last transfer; + // (3) origin departure time; and + // (4) last transfer departure time. + } } @@ -2342,8 +2409,9 @@ void convoi_t::get_freight_info(cbuffer_t & buf) slist_tpl <ware_t>capacity; for(i=0; i<warenbauer_t::get_waren_anzahl(); i++ ) { if(max_loaded_waren[i]>0 && i!=warenbauer_t::INDEX_NONE) { - //TODO: Replace this with the new constructor with the origin and timekeeping values. ware_t ware(warenbauer_t::get_info(i)); + //halthandle_t origin = welt->get_halt_koord_index(fahr[0]->get_pos().get_2d()); + //ware_t ware(warenbauer_t::get_info(i), origin, welt->get_zeit_ms()) ware.menge = max_loaded_waren[i]; if(ware.get_catg()==0) { capacity.append( ware ); diff --git a/simconvoi.h b/simconvoi.h index dfc7bd1540e..417e5e62fb0 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -5,6 +5,7 @@ #ifndef simconvoi_h #define simconvoi_h +//#define TEST_SPEED #include "simtypes.h" #include "linehandle_t.h" @@ -14,10 +15,15 @@ #include "dataobj/route.h" #include "vehicle/overtaker.h" #include "tpl/array_tpl.h" +#include "tpl/fixed_list_tpl.h" #include "convoihandle_t.h" #include "halthandle_t.h" +#ifdef TEST_SPEED +#include "simconst.h" +#endif + #define MAX_CONVOI_COST 5 // Total number of cost items #define MAX_MONTHS 12 // Max history #define MAX_CONVOI_NON_MONEY_TYPES 2 // number of non money types in convoi's financial statistic @@ -534,7 +540,14 @@ class convoi_t : public sync_steppable, public overtaker_t * set from the first vehicle, and takes into account all speed limits, brakes at stations etc. * @author Hj. Malthaner */ +#ifdef TEST_SPEED + void set_akt_speed_soll(sint32 set_akt_speed) { akt_speed_soll = kmh_to_speed(10); } + struct speed_testing { uint32 ticks; koord tile; }; + fixed_list_tpl<speed_testing, 16> ticks_per_tile; + uint32 average_speed; +#else void set_akt_speed_soll(sint32 set_akt_speed) { akt_speed_soll = min( set_akt_speed, min_top_speed ); } +#endif /** * @return current speed, this might be different from topspeed diff --git a/simmain.cc b/simmain.cc index 5a95692e68f..297ab484452 100644 --- a/simmain.cc +++ b/simmain.cc @@ -381,7 +381,7 @@ int simu_main(int argc, char** argv) // now read last setting (might be overwritten by the tab-files) loadsave_t file; if(file.rd_open("settings.xml")) { - if( file.get_version()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL ) ) { + if( file.get_version()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL).version ) { // too new => remove it file.close(); remove( "settings.xml" ); diff --git a/simversion.h b/simversion.h index c4d14a07e26..e8346f3e732 100644 --- a/simversion.h +++ b/simversion.h @@ -14,6 +14,10 @@ #define SAVEGAME_VER_NR "0.102.1" #define SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR) +#define EXPERIMENTAL_VER_NR ".1" +#define EXPERIMENTAL_SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) +#define COMBINED_VER_NR (SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) + #define RES_VERSION_NUMBER 0, 102, 0, 0 #endif diff --git a/simware.cc b/simware.cc index 34db06f4183..0f3f4044b49 100644 --- a/simware.cc +++ b/simware.cc @@ -101,25 +101,56 @@ ware_t::rdwr(karte_t *welt,loadsave_t *file) } } // convert coordinate to halt indices - if(file->is_saving()) { + if(file->is_saving()) + { koord ziel_koord = ziel.is_bound() ? ziel->get_basis_pos() : koord::invalid; koord zwischenziel_koord = zwischenziel.is_bound() ? zwischenziel->get_basis_pos() : koord::invalid; ziel_koord.rdwr(file); zwischenziel_koord.rdwr(file); + if(file->get_experimental_version() >= 1) + { + koord origin_koord = origin.is_bound() ? origin->get_basis_pos() : koord::invalid; + koord previous_transfer_koord = previous_transfer.is_bound() ? previous_transfer->get_basis_pos() : koord::invalid; + + origin_koord.rdwr(file); + previous_transfer_koord.rdwr(file); + } } - else { + else + { koord ziel_koord; ziel_koord.rdwr(file); ziel = welt->get_halt_koord_index(ziel_koord); ziel_koord.rdwr(file); zwischenziel = welt->get_halt_koord_index(ziel_koord); - //TODO: Make the following the default option only if cannot load origin, etc., from file: - origin = previous_transfer = zwischenziel; - total_journey_start_time = journey_leg_start_time = welt->get_zeit_ms(); + + if(file->get_experimental_version() >= 1) + { + koord origin_koord; + koord previous_transfer_koord; + + origin_koord.rdwr(file); + previous_transfer_koord.rdwr(file); + + origin = welt->get_halt_koord_index(origin_koord); + previous_transfer = welt->get_halt_koord_index(previous_transfer_koord); + + } + else + { + origin = previous_transfer = zwischenziel; + total_journey_start_time = journey_leg_start_time = welt->get_zeit_ms(); + } } zielpos.rdwr(file); + + if(file->get_experimental_version() >= 1) + { + file->rdwr_long(total_journey_start_time, ""); + file->rdwr_long(journey_leg_start_time, ""); + } } diff --git a/simworld.cc b/simworld.cc index 1ea65dd10c1..90e98334603 100644 --- a/simworld.cc +++ b/simworld.cc @@ -3396,7 +3396,7 @@ karte_t::laden(const char *filename) if(!file.rd_open(filename)) { - if( (sint32)file.get_version()==-1 || file.get_version()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL ) ) { + if( (sint32)file.get_version()==-1 || file.get_version()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL).version ) { create_win( new news_img("WRONGSAVE"), w_info, magic_none ); } else { diff --git a/tpl/fixed_list_tpl.h b/tpl/fixed_list_tpl.h index 847b6d47ed5..c6545ebec71 100644 --- a/tpl/fixed_list_tpl.h +++ b/tpl/fixed_list_tpl.h @@ -43,30 +43,30 @@ template<class T, int N> class fixed_list_tpl T operator[](uint8 e) { + uint8 i; if(e > size) { dbg->fatal("fixed_list_tpl<T>::[]", "index out of bounds: %i not in 0..%d", e, size - 1); - return NULL; } else { - uint8 i = add_index(head, e, N); - return data[i]; + i = add_index(head, e, N); } + return data[i]; } const T operator[](uint8 e) const { + uint8 i; if(e > size) { dbg->fatal("fixed_list_tpl<T>::[]", "index out of bounds: %i not in 0..%d", e, size - 1); - return NULL; } else { - uint8 i = add_index(head, e, N); - return data[i]; + i = add_index(head, e, N); } + return data[i]; } void clear() diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index d76b5152889..a2bdb8ab234 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -2045,10 +2045,15 @@ DBG_MESSAGE("vehicle_t::rdwr_from_convoi()","bought at %i/%i.",(insta_zeit%12)+1 total_freight += iter.get_current().menge; } } - // TODO - Add saves for: - // (1) whether vehicle is reversed; and - // (2) whether vehicle is to be upgrade-replaced. + if(file->get_experimental_version() >= 1) + { + file->rdwr_bool(reversed, ""); + } + else + { + reversed = false; + } } From a7243f00c4c8bc62ff7188a36c8f5e4f92f9ead8 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 21 Mar 2009 11:29:32 +0000 Subject: [PATCH 38/61] Convoys and lines now have a graph showing their average speed for each month. --- dataobj/koord.h | 8 ++++ gui/convoi_info_t.cc | 3 +- gui/schedule_list.cc | 7 +-- simcolor.h | 1 + simconvoi.cc | 111 ++++++++++++++++++++++++++++++++++--------- simconvoi.h | 30 +++++++++--- simline.cc | 28 +++++++++-- simline.h | 35 ++++++++++---- simversion.h | 2 +- 9 files changed, 178 insertions(+), 47 deletions(-) diff --git a/dataobj/koord.h b/dataobj/koord.h index 2cd6c416730..5afb7282c58 100644 --- a/dataobj/koord.h +++ b/dataobj/koord.h @@ -3,6 +3,7 @@ #include <cstdlib> #include <assert.h> +#include <math.h> #include "ribi.h" #include "../simtypes.h" @@ -74,9 +75,16 @@ class koord static inline uint32 abs_distance(const koord &a, const koord &b) { + // Manhattan distance return abs(a.x - b.x) + abs(a.y - b.y); } +static inline double accurate_distance(const koord &a, const koord &b) +{ + // Euclidian distance + return sqrt(pow((double)a.x - (int)b.x, 2) + pow((double)a.y - (int)b.y, 2)); +} + static inline koord operator * (const koord &k, const sint16 m) { diff --git a/gui/convoi_info_t.cc b/gui/convoi_info_t.cc index 50fbfe4805e..9d57d52bd61 100644 --- a/gui/convoi_info_t.cc +++ b/gui/convoi_info_t.cc @@ -38,6 +38,7 @@ const char cost_type[MAX_CONVOI_COST][64] = { "Free Capacity", "Transported", + "Average speed", "Revenue", "Operation", "Profit" @@ -64,7 +65,7 @@ const char *convoi_info_t::sort_text[SORT_MODES] = { const int cost_type_color[MAX_CONVOI_COST] = { - COL_FREE_CAPACITY, COL_TRANSPORTED, COL_REVENUE, COL_OPERATION, COL_PROFIT + COL_FREE_CAPACITY, COL_TRANSPORTED, COL_AVERAGE_SPEED, COL_REVENUE, COL_OPERATION, COL_PROFIT }; diff --git a/gui/schedule_list.cc b/gui/schedule_list.cc index c835649de41..0e999d4f884 100644 --- a/gui/schedule_list.cc +++ b/gui/schedule_list.cc @@ -49,6 +49,7 @@ const char schedule_list_gui_t::cost_type[MAX_LINE_COST][64] = { "Free Capacity", "Transported", + "Average speed", "Revenue", "Operation", "Profit", @@ -60,15 +61,15 @@ static uint8 max_idx=0; const int schedule_list_gui_t::cost_type_color[MAX_LINE_COST] = { - COL_FREE_CAPACITY, COL_TRANSPORTED, COL_REVENUE, COL_OPERATION, COL_PROFIT, COL_VEHICLE_ASSETS + COL_FREE_CAPACITY, COL_TRANSPORTED, COL_AVERAGE_SPEED, COL_REVENUE, COL_OPERATION, COL_PROFIT, COL_VEHICLE_ASSETS }; uint8 schedule_list_gui_t::statistic[MAX_LINE_COST]={ - LINE_CAPACITY, LINE_TRANSPORTED_GOODS, LINE_REVENUE, LINE_OPERATIONS, LINE_PROFIT, LINE_CONVOIS + LINE_CAPACITY, LINE_TRANSPORTED_GOODS, LINE_AVERAGE_SPEED, LINE_REVENUE, LINE_OPERATIONS, LINE_PROFIT, LINE_CONVOIS }; uint8 schedule_list_gui_t::statistic_type[MAX_LINE_COST]={ - STANDARD, STANDARD, MONEY, MONEY, MONEY, STANDARD + STANDARD, STANDARD, STANDARD, MONEY, MONEY, MONEY, STANDARD }; #define LINE_NAME_COLUMN_WIDTH ((BUTTON_WIDTH*3)+11+11) diff --git a/simcolor.h b/simcolor.h index 842af4bd2ed..dbdaca46dbc 100644 --- a/simcolor.h +++ b/simcolor.h @@ -95,5 +95,6 @@ typedef unsigned char COLOR_VAL; #define COL_ARRIVED COL_DARK_ORANGE #define COL_DEPARTED COL_DARK_YELLOW #define COL_POWERLINES (87) +#define COL_AVERAGE_SPEED (69) #endif diff --git a/simconvoi.cc b/simconvoi.cc index 7a3684b6adc..1c2542766e5 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -129,6 +129,9 @@ void convoi_t::reset() heaviest_vehicle = 0; longest_loading_time = 0; + last_departure_time = welt->get_zeit_ms(); + rolling_average_speed = 0; + rolling_average_speed_count = 0; } void convoi_t::init(karte_t *wl, spieler_t *sp) @@ -709,9 +712,13 @@ bool convoi_t::sync_step(long delta_t) next_wolke = 0; for(int i=0; i<anz_vehikel; i++ ) { fahr[i]->rauche(); + fahr[i]->last_stop_pos = fahr[i]->get_pos().get_2d(); } } } + + last_departure_time = welt->get_zeit_ms(); + break; // LEAVING_DEPOT case DRIVING: @@ -1086,6 +1093,10 @@ void convoi_t::new_month() } financial_history[0][j] = 0; } + + rolling_average_speed = 0; + rolling_average_speed_count = 0; + // check for traffic jam if(state==WAITING_FOR_CLEARANCE) { state = WAITING_FOR_CLEARANCE_ONE_MONTH; @@ -2127,24 +2138,59 @@ convoi_t::rdwr(loadsave_t *file) // Hajo: since sp_ist became obsolete, sp_soll is used modulo 65536 sp_soll &= 65535; - if(file->get_version()<=88003) { + if(file->get_version()<=88003) + { // load statistics int j; - for (j = 0; j<3; j++) { - for (int k = MAX_MONTHS-1; k>=0; k--) { + for (j = 0; j < 3; j++) + { + for (int k = MAX_MONTHS-1; k >= 0; k--) + { + if(j == CONVOI_AVERAGE_SPEED && file->get_experimental_version() <= 1) + { + // Versions of Experimental saves with 1 and below + // did not have a setting for average speed. + // Thus, this value must be skipped properly to + // assign the values. + financial_history[k][j] = 0; + continue; + } file->rdwr_longlong(financial_history[k][j], " "); } } - for (j = 2; j<5; j++) { - for (int k = MAX_MONTHS-1; k>=0; k--) { + for (j = 2; j < 5; j++) + { + for (int k = MAX_MONTHS-1; k >= 0; k--) + { + if(j == CONVOI_AVERAGE_SPEED && file->get_experimental_version() <= 1) + { + // Versions of Experimental saves with 1 and below + // did not have a setting for average speed. + // Thus, this value must be skipped properly to + // assign the values. + financial_history[k][j] = 0; + continue; + } file->rdwr_longlong(financial_history[k][j], " "); } } } - else { + else + { // load statistics - for (int j = 0; j<MAX_CONVOI_COST; j++) { - for (int k = MAX_MONTHS-1; k>=0; k--) { + for (int j = 0; j < MAX_CONVOI_COST; j++) + { + for (int k = MAX_MONTHS-1; k >= 0; k--) + { + if(j == CONVOI_AVERAGE_SPEED && file->get_experimental_version() <= 1) + { + // Versions of Experimental saves with 1 and below + // did not have a setting for average speed. + // Thus, this value must be skipped properly to + // assign the values. + financial_history[k][j] = 0; + continue; + } file->rdwr_longlong(financial_history[k][j], " "); } } @@ -2152,9 +2198,11 @@ convoi_t::rdwr(loadsave_t *file) // since it was saved as an signed int // we recalc it anyhow - if(file->is_loading()) { - jahresgewinn = 0; - for(int i=welt->get_last_month()%12; i>=0; i-- ) { + if(file->is_loading()) + { + jahresgewinn = 0; //"annual profit" (Babelfish) + for(int i=welt->get_last_month()%12; i>=0; i-- ) + { jahresgewinn += financial_history[i][CONVOI_PROFIT]; } } @@ -2283,14 +2331,12 @@ convoi_t::rdwr(loadsave_t *file) } } } - - - - // TODO: Add load/save parameters for: - // (1) origin; - // (2) last transfer; - // (3) origin departure time; and - // (4) last transfer departure time. + } + if(file->get_experimental_version() >= 2) + { + file->rdwr_long(last_departure_time, ""); + file->rdwr_long(rolling_average_speed, ""); + file->rdwr_short(rolling_average_speed_count, ""); } } @@ -2370,7 +2416,8 @@ void convoi_t::get_freight_info(cbuffer_t & buf) slist_iterator_tpl<ware_t> iter_vehicle_ware(v->get_fracht()); while(iter_vehicle_ware.next()) { ware_t ware = iter_vehicle_ware.get_current(); - for(unsigned i = 0; i < total_fracht.get_count(); i++ ) { + ITERATE(total_fracht, i) + { // could this be joined with existing freight? ware_t &tmp = total_fracht[i]; @@ -2410,6 +2457,7 @@ void convoi_t::get_freight_info(cbuffer_t & buf) for(i=0; i<warenbauer_t::get_waren_anzahl(); i++ ) { if(max_loaded_waren[i]>0 && i!=warenbauer_t::INDEX_NONE) { ware_t ware(warenbauer_t::get_info(i)); + //TODO: Setup origins so that the ultimate origin, as well as the previous transfer, is stored. //halthandle_t origin = welt->get_halt_koord_index(fahr[0]->get_pos().get_2d()); //ware_t ware(warenbauer_t::get_info(i), origin, welt->get_zeit_ms()) ware.menge = max_loaded_waren[i]; @@ -2571,7 +2619,12 @@ convoi_t::pruefe_alle() //"examine all" (Babelfish) */ void convoi_t::laden() //"load" (Babelfish) { - if(state == FAHRPLANEINGABE) { + const double journey_time = (welt->get_zeit_ms() - last_departure_time) / 4096; + const double journey_distance = accurate_distance(fahr[0]->get_pos().get_2d(), fahr[0]->last_stop_pos); + const uint16 average_speed = (journey_distance / journey_time) * 20; + book(average_speed, CONVOI_AVERAGE_SPEED); + + if(state == FAHRPLANEINGABE) { //"ENTER SCHEDULE" (Google) return; } @@ -2579,7 +2632,7 @@ void convoi_t::laden() //"load" (Babelfish) // eigene haltestelle ? // "own stop?" (Babelfish) if (halt.is_bound()) { - const koord k = fpl->get_current_eintrag().pos.get_2d(); + const koord k = fpl->get_current_eintrag().pos.get_2d(); //"eintrag" = "entry" (Google) const spieler_t* owner = halt->get_besitzer(); if( owner == get_besitzer() || owner == welt->get_spieler(1) ) { // loading/unloading ... @@ -2617,6 +2670,7 @@ void convoi_t::laden() //"load" (Babelfish) // This is the minimum time it takes for loading //wait_lock = WTT_LOADING; wait_lock = longest_loading_time; + last_departure_time = welt->get_zeit_ms(); } @@ -2635,6 +2689,8 @@ void convoi_t::calc_gewinn() v->last_stop_pos = v->get_pos().get_2d(); } + last_departure_time = welt->get_zeit_ms(); + if(gewinn) { besitzer_p->buche(gewinn, fahr[0]->get_pos().get_2d(), COST_INCOME); jahresgewinn += gewinn; @@ -2915,7 +2971,16 @@ void convoi_t::book(sint64 amount, int cost_type) { assert( cost_type<MAX_CONVOI_COST); - financial_history[0][cost_type] += amount; + if(cost_type != CONVOI_AVERAGE_SPEED) + { + financial_history[0][cost_type] += amount; + } + else + { + rolling_average_speed += amount; + rolling_average_speed_count ++; + financial_history[0][cost_type] = rolling_average_speed / rolling_average_speed_count; + } if (line.is_bound()) { line->book(amount, simline_t::convoi_to_line_catgory[cost_type] ); } diff --git a/simconvoi.h b/simconvoi.h index 417e5e62fb0..d3dddc91f80 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -24,14 +24,17 @@ #include "simconst.h" #endif -#define MAX_CONVOI_COST 5 // Total number of cost items +#define MAX_CONVOI_COST 6 // Total number of cost items #define MAX_MONTHS 12 // Max history -#define MAX_CONVOI_NON_MONEY_TYPES 2 // number of non money types in convoi's financial statistic -#define CONVOI_CAPACITY 0 // the amount of ware that could be transported, theoretically -#define CONVOI_TRANSPORTED_GOODS 1 // the amount of ware that has been transported -#define CONVOI_REVENUE 2 // the income this CONVOI generated -#define CONVOI_OPERATIONS 3 // the cost of operations this CONVOI generated -#define CONVOI_PROFIT 4 // total profit of this convoi +#define MAX_CONVOI_NON_MONEY_TYPES 3 // number of non money types in convoi's financial statistic + +#define CONVOI_CAPACITY 0 // the amount of ware that could be transported, theoretically +#define CONVOI_TRANSPORTED_GOODS 1 // the amount of ware that has been transported +#define CONVOI_AVERAGE_SPEED 2 // The average speed of the convoy per rolling month +#define CONVOI_REVENUE 3 // the income this CONVOI generated +#define CONVOI_OPERATIONS 4 // the cost of operations this CONVOI generated +#define CONVOI_PROFIT 5 // total profit of this convoi + class depot_t; class karte_t; @@ -359,6 +362,7 @@ class convoi_t : public sync_steppable, public overtaker_t /** * Convoi haelt an Haltestelle und setzt quote fuer Fracht + * "Convoi holds by stop and sets ratio for freight" (Babelfish) * @author Hj. Malthaner */ void hat_gehalten(koord k, halthandle_t halt); @@ -394,6 +398,15 @@ class convoi_t : public sync_steppable, public overtaker_t uint32 heaviest_vehicle; uint16 longest_loading_time; + // Time in ticks since it departed from the previous stop. + // Used for measuring average speed. + // @author: jamespetts + uint32 last_departure_time; + + //@author: jamespetts + uint32 rolling_average_speed; + uint16 rolling_average_speed_count; + public: route_t* get_route() { return &route; } @@ -459,6 +472,7 @@ class convoi_t : public sync_steppable, public overtaker_t /** * Der Gewinn in diesem Jahr + * "The profit in this year" (Babelfish) * @author Hanjsörg Malthaner */ const sint64 & get_jahresgewinn() const {return jahresgewinn;} @@ -701,12 +715,14 @@ class convoi_t : public sync_steppable, public overtaker_t /** * pruefe ob Beschraenkungen fuer alle Fahrzeuge erfuellt sind + * " examine whether restrictions for all vehicles are fulfilled" (Google) * @author Hj. Malthaner */ bool pruefe_alle(); /** * Kontrolliert Be- und Entladen. + * "Controlled loading and unloading" (Google) * V.Meyer: returns nothing * @author Hj. Malthaner */ diff --git a/simline.cc b/simline.cc index 9eeb0047f22..35b27dc956d 100644 --- a/simline.cc +++ b/simline.cc @@ -10,7 +10,7 @@ #include "simlinemgmt.h" -uint8 simline_t::convoi_to_line_catgory[MAX_CONVOI_COST]={LINE_CAPACITY, LINE_TRANSPORTED_GOODS, LINE_REVENUE, LINE_OPERATIONS, LINE_PROFIT }; +uint8 simline_t::convoi_to_line_catgory[MAX_CONVOI_COST]={LINE_CAPACITY, LINE_TRANSPORTED_GOODS, LINE_AVERAGE_SPEED, LINE_REVENUE, LINE_OPERATIONS, LINE_PROFIT }; karte_t *simline_t::welt=NULL; @@ -27,6 +27,8 @@ simline_t::simline_t(karte_t* welt, spieler_t* sp) this->fpl = NULL; this->sp = sp; state_color = COL_YELLOW; + rolling_average_speed = 0; + rolling_average_speed_count = 0; } @@ -153,13 +155,30 @@ void simline_t::rdwr(loadsave_t *file) fpl->rdwr(file); //financial history - for (int j = 0; j<MAX_LINE_COST; j++) { - for (int k = MAX_MONTHS-1; k>=0; k--) { + for (int j = 0; j<MAX_LINE_COST; j++) + { + for (int k = MAX_MONTHS-1; k>=0; k--) + { + if(j == LINE_AVERAGE_SPEED && file->get_experimental_version() <= 1) + { + // Versions of Experimental saves with 1 and below + // did not have a setting for average speed. + // Thus, this value must be skipped properly to + // assign the values. + financial_history[k][j] = 0; + continue; + } file->rdwr_longlong(financial_history[k][j], " "); } } // otherwise inintialized to zero if loading ... financial_history[0][LINE_CONVOIS] = count_convoys(); + + if(file->get_experimental_version() >= 2) + { + file->rdwr_long(rolling_average_speed, ""); + file->rdwr_short(rolling_average_speed_count, ""); + } } @@ -237,6 +256,9 @@ void simline_t::new_month() financial_history[0][j] = 0; } financial_history[0][LINE_CONVOIS] = count_convoys(); + + rolling_average_speed = 0; + rolling_average_speed_count = 0; } diff --git a/simline.h b/simline.h index 9b7668d714d..6319e02e71e 100644 --- a/simline.h +++ b/simline.h @@ -19,16 +19,17 @@ #include "linehandle_t.h" #include "convoihandle_t.h" -#define MAX_LINE_COST 6 // Total number of cost items -#define MAX_MONTHS 12 // Max history -#define MAX_NON_MONEY_TYPES 2 // number of non money types in line's financial statistic - -#define LINE_CAPACITY 0 // the amount of ware that could be transported, theoretically -#define LINE_TRANSPORTED_GOODS 1 // the amount of ware that has been transported -#define LINE_CONVOIS 2 // number of convois for this line -#define LINE_REVENUE 3 // the income this line generated +#define MAX_LINE_COST 7 // Total number of cost items +#define MAX_MONTHS 12 // Max history +#define MAX_NON_MONEY_TYPES 3 // number of non money types in line's financial statistic + +#define LINE_CAPACITY 0 // the amount of ware that could be transported, theoretically +#define LINE_TRANSPORTED_GOODS 1 // the amount of ware that has been transported +#define LINE_AVERAGE_SPEED 2 // The average speed of all convoys in the line +#define LINE_REVENUE 3 // the income this line generated #define LINE_OPERATIONS 4 // the cost of operations this line generated #define LINE_PROFIT 5 // total profit of line +#define LINE_CONVOIS 6 // number of convois for this line class karte_t; class simlinemgmt_t; @@ -180,7 +181,19 @@ class simline_t { sint64 get_finance_history(int month, int cost_type) { return financial_history[month][cost_type]; } - void book(sint64 amount, int cost_type) { financial_history[0][cost_type] += amount; } + void book(sint64 amount, int cost_type) + { + if(cost_type != LINE_AVERAGE_SPEED) + { + financial_history[0][cost_type] += amount; + } + else + { + rolling_average_speed += amount; + rolling_average_speed_count ++; + financial_history[0][LINE_AVERAGE_SPEED] = rolling_average_speed / rolling_average_speed_count; + } + } void new_month(); @@ -200,6 +213,10 @@ class simline_t { int get_replacing_convoys_count() const; + //@author: jamespetts + uint32 rolling_average_speed; + uint16 rolling_average_speed_count; + public: spieler_t *get_besitzer() const {return sp;} diff --git a/simversion.h b/simversion.h index e8346f3e732..fc71b5766ab 100644 --- a/simversion.h +++ b/simversion.h @@ -14,7 +14,7 @@ #define SAVEGAME_VER_NR "0.102.1" #define SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR) -#define EXPERIMENTAL_VER_NR ".1" +#define EXPERIMENTAL_VER_NR ".2" #define EXPERIMENTAL_SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) #define COMBINED_VER_NR (SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) From 6d99293872f5b5be0b00036e407539f277714dbf Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 21 Mar 2009 13:18:49 +0000 Subject: [PATCH 39/61] Better (faster) system for calculating euclidian distance --- dataobj/koord.h | 21 ++++++++++++++++++--- simconvoi.cc | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/dataobj/koord.h b/dataobj/koord.h index 5afb7282c58..1eb28efdc05 100644 --- a/dataobj/koord.h +++ b/dataobj/koord.h @@ -3,7 +3,6 @@ #include <cstdlib> #include <assert.h> -#include <math.h> #include "ribi.h" #include "../simtypes.h" @@ -72,6 +71,22 @@ class koord static const koord from_hang[16]; }; +static inline uint32 int_sqrt(const uint32 num) +{ + if (0 == num) + { + // Avoid zero divide + return 0; + } + uint32 n = (num / 2) + 1; // Initial estimate, never low + uint32 n1 = (n + (num / n)) / 2; + while (n1 < n) + { + n = n1; + n1 = (n + (num / n)) / 2; + } + return n; +} static inline uint32 abs_distance(const koord &a, const koord &b) { @@ -79,10 +94,10 @@ static inline uint32 abs_distance(const koord &a, const koord &b) return abs(a.x - b.x) + abs(a.y - b.y); } -static inline double accurate_distance(const koord &a, const koord &b) +static inline uint32 accurate_distance(const koord &a, const koord &b) { // Euclidian distance - return sqrt(pow((double)a.x - (int)b.x, 2) + pow((double)a.y - (int)b.y, 2)); + return int_sqrt(((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y))); } diff --git a/simconvoi.cc b/simconvoi.cc index 1c2542766e5..e10bb4b45a1 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -2620,7 +2620,7 @@ convoi_t::pruefe_alle() //"examine all" (Babelfish) void convoi_t::laden() //"load" (Babelfish) { const double journey_time = (welt->get_zeit_ms() - last_departure_time) / 4096; - const double journey_distance = accurate_distance(fahr[0]->get_pos().get_2d(), fahr[0]->last_stop_pos); + const uint32 journey_distance = accurate_distance(fahr[0]->get_pos().get_2d(), fahr[0]->last_stop_pos); const uint16 average_speed = (journey_distance / journey_time) * 20; book(average_speed, CONVOI_AVERAGE_SPEED); From 8e913682300b5cd7b1050b73cdb35c0c960ace24 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 28 Mar 2009 10:57:52 +0000 Subject: [PATCH 40/61] Basic structure in place for the new revenue model. Also, enhanced the steam locomotive physics. Save game version updated. Added a new "global power factor" setting. Overcrowded capacity now has effect - overcrowded vehicles/lines are shown in purple. The convoy/line graph now shows average comfort, which takes into account catering and overcrowding. The maximum convoy length is now 64, instead of 24. --- dataobj/einstellungen.cc | 27 +- dataobj/einstellungen.h | 93 +++---- gui/components/gui_convoy_assembler.cc | 106 ++++++-- gui/convoi_info_t.cc | 5 +- gui/schedule_list.cc | 9 +- gui/stadt_info.cc | 1 + simcity.cc | 10 +- simcolor.h | 2 + simconvoi.cc | 337 +++++++++++++++++++------ simconvoi.h | 39 ++- simfab.cc | 5 +- simhalt.h | 9 +- simline.cc | 79 ++++-- simline.h | 26 +- simware.cc | 59 +++-- simware.h | 36 +-- simworld.cc | 22 +- tpl/fixed_list_tpl.h | 4 +- tpl/ordered_vector_tpl.h | 4 +- tpl/vector_tpl.h | 4 +- tpl/weighted_vector_tpl.h | 4 +- vehicle/simvehikel.cc | 140 +++++++--- vehicle/simvehikel.h | 35 ++- 23 files changed, 753 insertions(+), 303 deletions(-) diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index c7490a50c03..71b8aa57e0f 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -215,16 +215,20 @@ einstellungen_t::einstellungen_t() : allow_purhcases_when_insolvent = 0; // Reversing settings - //@author: jamespetts + // @author: jamespetts unit_reverse_time = 0; hauled_reverse_time = 0; turntable_reverse_time = 0; + // Global power factor + // @author: jamespetts + global_power_factor = 1.0; + // this will pay for distance to next change station pay_for_total_distance = 0; - avoid_overcrowding = true; + avoid_overcrowding = false; } @@ -599,6 +603,14 @@ void einstellungen_t::rdwr(loadsave_t *file) file->rdwr_short(unit_reverse_time, ""); file->rdwr_short(hauled_reverse_time, ""); file->rdwr_short(turntable_reverse_time, ""); + + } + + if(file->get_experimental_version() >= 2) + { + uint16 global_power_factor_percent = global_power_factor * 100; + //file->rdwr_short(global_power_factor_percent, ""); + global_power_factor = (float)global_power_factor_percent / 100; } } @@ -835,17 +847,24 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s //Factory settings factory_max_years_obsolete = contents.get_int("max_years_obsolete", factory_max_years_obsolete); - //@author: jamespetts + // @author: jamespetts // Insolvency and debt settings interest_rate_percent = contents.get_int("interest_rate_percent", interest_rate_percent); allow_bankruptsy = contents.get_int("allow_bankruptsy", allow_bankruptsy); allow_purhcases_when_insolvent = contents.get_int("allow_purhcases_when_insolvent", allow_purhcases_when_insolvent); - //Reversing settings + // Reversing settings + // @author: jamespetts unit_reverse_time = contents.get_int("unit_reverse_time", unit_reverse_time); hauled_reverse_time = contents.get_int("hauled_reverse_time", hauled_reverse_time); turntable_reverse_time = contents.get_int("turntable_reverse_time", turntable_reverse_time); + // Global power factor + // @author: jamespetts + uint16 global_power_factor_percent = 100; + global_power_factor_percent = contents.get_int("global_power_factor_percent", global_power_factor_percent); + global_power_factor = (float)global_power_factor_percent / 100; + /* * Selection of savegame format through inifile */ diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index fc0b2004672..e898620bd6c 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -168,46 +168,6 @@ class einstellungen_t /* if set, goods will not routed over overcroded stations but rather try detours (if possible) */ bool no_routing_over_overcrowding; -public: - /* the big cost section */ - sint32 maint_building; // normal building - - sint64 cst_multiply_dock; - sint64 cst_multiply_station; - sint64 cst_multiply_roadstop; - sint64 cst_multiply_airterminal; - sint64 cst_multiply_post; - sint64 cst_multiply_headquarter; - sint64 cst_depot_rail; - sint64 cst_depot_road; - sint64 cst_depot_ship; - sint64 cst_depot_air; - sint64 cst_signal; - sint64 cst_tunnel; - sint64 cst_third_rail; - - // alter landscape - sint64 cst_buy_land; - sint64 cst_alter_land; - sint64 cst_set_slope; - sint64 cst_found_city; - sint64 cst_multiply_found_industry; - sint64 cst_remove_tree; - sint64 cst_multiply_remove_haus; - sint64 cst_multiply_remove_field; - sint64 cst_transformer; - sint64 cst_maintain_transformer; - - // costs for the way searcher - sint32 way_count_straight; - sint32 way_count_curve; - sint32 way_count_double_curve; - sint32 way_count_90_curve; - sint32 way_count_slope; - sint32 way_count_tunnel; - uint32 way_max_bridge_len; - sint32 way_count_leaving_road; - //@author: jamespetts // Speed bonus local adjustment uint16 min_bonus_max_distance; @@ -231,7 +191,7 @@ class einstellungen_t uint16 longdistance_passengers_max_distance; // @author: jamespetts - // Private ar settings + // Private car settings uint8 always_prefer_car_percent; uint8 base_car_preference_percent; uint8 congestion_density_factor; @@ -259,6 +219,49 @@ class einstellungen_t uint16 hauled_reverse_time; uint16 turntable_reverse_time; + //@author: jamespetts + float global_power_factor; + +public: + /* the big cost section */ + sint32 maint_building; // normal building + + sint64 cst_multiply_dock; + sint64 cst_multiply_station; + sint64 cst_multiply_roadstop; + sint64 cst_multiply_airterminal; + sint64 cst_multiply_post; + sint64 cst_multiply_headquarter; + sint64 cst_depot_rail; + sint64 cst_depot_road; + sint64 cst_depot_ship; + sint64 cst_depot_air; + sint64 cst_signal; + sint64 cst_tunnel; + sint64 cst_third_rail; + + // alter landscape + sint64 cst_buy_land; + sint64 cst_alter_land; + sint64 cst_set_slope; + sint64 cst_found_city; + sint64 cst_multiply_found_industry; + sint64 cst_remove_tree; + sint64 cst_multiply_remove_haus; + sint64 cst_multiply_remove_field; + sint64 cst_transformer; + sint64 cst_maintain_transformer; + + // costs for the way searcher + sint32 way_count_straight; + sint32 way_count_curve; + sint32 way_count_double_curve; + sint32 way_count_90_curve; + sint32 way_count_slope; + sint32 way_count_tunnel; + uint32 way_max_bridge_len; + sint32 way_count_leaving_road; + // true if active bool automaten[MAX_PLAYER_COUNT]; // 0 = emtpy, otherwise some vaule from simplay @@ -448,6 +451,8 @@ class einstellungen_t uint16 get_hauled_reverse_time() const { return hauled_reverse_time; } uint16 get_turntable_reverse_time() const { return turntable_reverse_time; } + float get_global_power_factor() const { return global_power_factor; } + // do not take people to overcrowded destinations bool is_avoid_overcrowding() const { return avoid_overcrowding; } @@ -455,11 +460,11 @@ class einstellungen_t bool is_no_routing_over_overcrowding() const { return no_routing_over_overcrowding; } sint16 get_river_number() const { return river_number; } - void set_river_number( sint16 n ) { river_number=n; } + void set_river_number( sint16 n ) { river_number = n; } sint16 get_min_river_length() const { return min_river_length; } - void set_min_river_length( sint16 n ) { min_river_length=n; } + void set_min_river_length( sint16 n ) { min_river_length = n; } sint16 get_max_river_length() const { return max_river_length; } - void set_max_river_length( sint16 n ) { max_river_length=n; } + void set_max_river_length( sint16 n ) { max_river_length = n; } }; #endif diff --git a/gui/components/gui_convoy_assembler.cc b/gui/components/gui_convoy_assembler.cc index 61c705e448b..65e4e5bbea8 100644 --- a/gui/components/gui_convoy_assembler.cc +++ b/gui/components/gui_convoy_assembler.cc @@ -1137,7 +1137,8 @@ void gui_convoy_assembler_t::draw_vehicle_info_text(koord pos) } //"Payload" (Google) - if(zuladung>0) { + if(zuladung > 0 && veh_type->get_overcrowded_capacity() < 1) + { n += sprintf(buf + n, translator::translate("LOCO_CAP"), zuladung, @@ -1146,6 +1147,17 @@ void gui_convoy_assembler_t::draw_vehicle_info_text(koord pos) ); k = n; } + else if(zuladung > 0 && veh_type->get_overcrowded_capacity() > 0) + { + n += sprintf(buf + n, + translator::translate("Capacity: %d (%d)%s %s\n"), + zuladung, + veh_type->get_overcrowded_capacity(), + translator::translate(veh_type->get_ware()->get_mass()), + veh_type->get_ware()->get_catg() == 0 ? translator::translate(veh_type->get_ware()->get_name()) : translator::translate(veh_type->get_ware()->get_catg_name()) + ); + k = n; + } } else { @@ -1153,35 +1165,75 @@ void gui_convoy_assembler_t::draw_vehicle_info_text(koord pos) int n; if(upgrade == u_buy) { - n = sprintf(buf, - translator::translate("WAGGON_INFO"), - translator::translate(veh_type->get_name()), - veh_type->get_preis()/100, - veh_type->get_betriebskosten(get_welt())/100.0, - veh_type->get_zuladung(), - translator::translate(veh_type->get_ware()->get_mass()), - veh_type->get_ware()->get_catg() == 0 ? - translator::translate(veh_type->get_ware()->get_name()) : - translator::translate(veh_type->get_ware()->get_catg_name()), - veh_type->get_gewicht(), - veh_type->get_geschw() - ); + if(veh_type->get_overcrowded_capacity() < 1) + { + n = sprintf(buf, + translator::translate("WAGGON_INFO"), + translator::translate(veh_type->get_name()), + veh_type->get_preis()/100, + veh_type->get_betriebskosten(get_welt())/100.0, + veh_type->get_zuladung(), + translator::translate(veh_type->get_ware()->get_mass()), + veh_type->get_ware()->get_catg() == 0 ? + translator::translate(veh_type->get_ware()->get_name()) : + translator::translate(veh_type->get_ware()->get_catg_name()), + veh_type->get_gewicht(), + veh_type->get_geschw() + ); + } + else + { + n = sprintf(buf, + translator::translate("%s\nCost: %d$ (%1.2f$/km)\nCapacity: %d (%d)%s %s\nWeight: %dt\nTop speed: %dkm/h\n"), + translator::translate(veh_type->get_name()), + veh_type->get_preis()/100, + veh_type->get_betriebskosten(get_welt())/100.0, + veh_type->get_zuladung(), + veh_type->get_overcrowded_capacity(), + translator::translate(veh_type->get_ware()->get_mass()), + veh_type->get_ware()->get_catg() == 0 ? + translator::translate(veh_type->get_ware()->get_name()) : + translator::translate(veh_type->get_ware()->get_catg_name()), + veh_type->get_gewicht(), + veh_type->get_geschw() + ); + } } else { - n = sprintf(buf, - translator::translate("WAGGON_INFO"), - translator::translate(veh_type->get_name()), - veh_type->get_upgrade_price()/100, - veh_type->get_betriebskosten(get_welt())/100.0, - veh_type->get_zuladung(), - translator::translate(veh_type->get_ware()->get_mass()), - veh_type->get_ware()->get_catg() == 0 ? - translator::translate(veh_type->get_ware()->get_name()) : - translator::translate(veh_type->get_ware()->get_catg_name()), - veh_type->get_gewicht(), - veh_type->get_geschw() - ); + if(veh_type->get_overcrowded_capacity() < 1) + { + n = sprintf(buf, + translator::translate("WAGGON_INFO"), + translator::translate(veh_type->get_name()), + veh_type->get_upgrade_price()/100, + veh_type->get_betriebskosten(get_welt())/100.0, + veh_type->get_zuladung(), + translator::translate(veh_type->get_ware()->get_mass()), + veh_type->get_ware()->get_catg() == 0 ? + translator::translate(veh_type->get_ware()->get_name()) : + translator::translate(veh_type->get_ware()->get_catg_name()), + veh_type->get_gewicht(), + veh_type->get_geschw() + ); + } + else + { + n = sprintf(buf, + translator::translate("%s\nCost: %d$ (%1.2f$/km)\nCapacity: %d (%d)%s %s\nWeight: %dt\nTop speed: %dkm/h\n"), + translator::translate(veh_type->get_name()), + veh_type->get_upgrade_price()/100, + veh_type->get_betriebskosten(get_welt())/100.0, + veh_type->get_zuladung(), + veh_type->get_overcrowded_capacity(), + translator::translate(veh_type->get_ware()->get_mass()), + veh_type->get_ware()->get_catg() == 0 ? + translator::translate(veh_type->get_ware()->get_name()) : + translator::translate(veh_type->get_ware()->get_catg_name()), + veh_type->get_gewicht(), + veh_type->get_geschw() + ); + } } k = n; diff --git a/gui/convoi_info_t.cc b/gui/convoi_info_t.cc index 9d57d52bd61..eb7c3f3e2a0 100644 --- a/gui/convoi_info_t.cc +++ b/gui/convoi_info_t.cc @@ -39,12 +39,13 @@ const char cost_type[MAX_CONVOI_COST][64] = "Free Capacity", "Transported", "Average speed", + "Comfort", "Revenue", "Operation", "Profit" }; -bool convoi_info_t::route_search_in_progress=false; +bool convoi_info_t::route_search_in_progress = false; /** * This variable defines by which column the table is sorted @@ -65,7 +66,7 @@ const char *convoi_info_t::sort_text[SORT_MODES] = { const int cost_type_color[MAX_CONVOI_COST] = { - COL_FREE_CAPACITY, COL_TRANSPORTED, COL_AVERAGE_SPEED, COL_REVENUE, COL_OPERATION, COL_PROFIT + COL_FREE_CAPACITY, COL_TRANSPORTED, COL_AVERAGE_SPEED, COL_COMFORT, COL_REVENUE, COL_OPERATION, COL_PROFIT }; diff --git a/gui/schedule_list.cc b/gui/schedule_list.cc index 0e999d4f884..485f652e80b 100644 --- a/gui/schedule_list.cc +++ b/gui/schedule_list.cc @@ -50,26 +50,27 @@ const char schedule_list_gui_t::cost_type[MAX_LINE_COST][64] = "Free Capacity", "Transported", "Average speed", + "Comfort", "Revenue", "Operation", "Profit", "Convoys" }; -static uint8 tabs_to_lineindex[9]; +static uint8 tabs_to_lineindex[8]; static uint8 max_idx=0; const int schedule_list_gui_t::cost_type_color[MAX_LINE_COST] = { - COL_FREE_CAPACITY, COL_TRANSPORTED, COL_AVERAGE_SPEED, COL_REVENUE, COL_OPERATION, COL_PROFIT, COL_VEHICLE_ASSETS + COL_FREE_CAPACITY, COL_TRANSPORTED, COL_AVERAGE_SPEED, COL_COMFORT, COL_REVENUE, COL_OPERATION, COL_PROFIT, COL_VEHICLE_ASSETS }; uint8 schedule_list_gui_t::statistic[MAX_LINE_COST]={ - LINE_CAPACITY, LINE_TRANSPORTED_GOODS, LINE_AVERAGE_SPEED, LINE_REVENUE, LINE_OPERATIONS, LINE_PROFIT, LINE_CONVOIS + LINE_CAPACITY, LINE_TRANSPORTED_GOODS, LINE_AVERAGE_SPEED, LINE_COMFORT, LINE_REVENUE, LINE_OPERATIONS, LINE_PROFIT, LINE_CONVOIS }; uint8 schedule_list_gui_t::statistic_type[MAX_LINE_COST]={ - STANDARD, STANDARD, STANDARD, MONEY, MONEY, MONEY, STANDARD + STANDARD, STANDARD, STANDARD, STANDARD, MONEY, MONEY, MONEY, STANDARD }; #define LINE_NAME_COLUMN_WIDTH ((BUTTON_WIDTH*3)+11+11) diff --git a/gui/stadt_info.cc b/gui/stadt_info.cc index d6aeaf945a9..f83981d7006 100644 --- a/gui/stadt_info.cc +++ b/gui/stadt_info.cc @@ -188,6 +188,7 @@ void stadt_info_t::zeichnen(koord pos, koord gr) } pax_destinations_last_change = current_pax_destinations; + //TODO: Check whether this needs changing given that max_train_length has now increased. display_array_wh(pos.x + 140, pos.y + 24, PAX_DESTINATIONS_SIZE, PAX_DESTINATIONS_SIZE, pax_dest_old); display_array_wh(pos.x + 140 + PAX_DESTINATIONS_SIZE + 4, pos.y + 24, PAX_DESTINATIONS_SIZE, PAX_DESTINATIONS_SIZE, pax_dest_new); } diff --git a/simcity.cc b/simcity.cc index 9248a8eee6a..ee0f492aafa 100644 --- a/simcity.cc +++ b/simcity.cc @@ -1368,6 +1368,7 @@ void stadt_t::neuer_monat() //"New month" (Google) // that the player can have a better idea visually of the amount of traffic. #define DESTINATION_CITYCARS + #ifdef DESTINATION_CITYCARS // Subtract incoming trips and cars already generated to prevent double counting. sint16 factor = city_history_month[1][HIST_CITYCARS] - incoming_private_cars - current_cars.get_count(); @@ -1873,9 +1874,6 @@ void stadt_t::step_passagiere() pax.set_journey_steps(best_journey_steps); start_halt = best_destination[2]; pax.set_origin(start_halt); - pax.set_previous_transfer(start_halt); - pax.set_total_journey_start_time(welt->get_zeit_ms()); - pax.set_journey_leg_start_time(welt->get_zeit_ms()); // Now, decide whether passengers would prefer to use their private cars, // even though they can travel by public transport. @@ -2002,13 +2000,13 @@ void stadt_t::step_passagiere() if(private_car_chance <= car_preference) { set_private_car_trip(num_pax, destinations[current_destination].town); - #ifdef DESTINATION_CITYCARS +#ifdef DESTINATION_CITYCARS //citycars with destination if(start_halt.is_bound()) { erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, destinations[current_destination].location); } - #endif +#endif current_destination ++; break; } @@ -2082,7 +2080,7 @@ void stadt_t::step_passagiere() if( !ret_halt->is_overcrowded(wtyp->get_catg_index()) ) { // prissi: not overcrowded and can recieve => add them if (found) { - ware_t return_pax (wtyp, ret_halt, welt->get_zeit_ms()); + ware_t return_pax(wtyp, ret_halt); return_pax.menge = pax_left_to_do; return_pax.set_zielpos(k); return_pax.set_ziel(start_halt); diff --git a/simcolor.h b/simcolor.h index dbdaca46dbc..17f2a908610 100644 --- a/simcolor.h +++ b/simcolor.h @@ -96,5 +96,7 @@ typedef unsigned char COLOR_VAL; #define COL_DEPARTED COL_DARK_YELLOW #define COL_POWERLINES (87) #define COL_AVERAGE_SPEED (69) +#define COL_AVEARGE_WAIT COL_DARK_PURPLE +#define COL_COMFORT COL_DARK_TURQOISE #endif diff --git a/simconvoi.cc b/simconvoi.cc index e10bb4b45a1..34f27c2e9e7 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -130,8 +130,11 @@ void convoi_t::reset() heaviest_vehicle = 0; longest_loading_time = 0; last_departure_time = welt->get_zeit_ms(); - rolling_average_speed = 0; - rolling_average_speed_count = 0; + for(uint8 i = 0; i < MAX_CONVOI_COST; i ++) + { + rolling_average[i] = 0; + rolling_average_count[i] = 0; + } } void convoi_t::init(karte_t *wl, spieler_t *sp) @@ -534,19 +537,23 @@ void convoi_t::calc_acceleration(long delta_t) sint32 convoi_t::calc_adjusted_power() { - uint16 max_speed = speed_to_kmh(fahr[0]->get_besch()->get_geschw()); + //uint16 max_speed = speed_to_kmh(fahr[0]->get_besch()->get_geschw()); + uint16 max_speed = fahr[0]->get_besch()->get_geschw(); float highpoint_speed = (max_speed >= 30) ? max_speed - 30 : 30; uint16 current_speed = speed_to_kmh(akt_speed); - if(power_from_steam < 1 || speed_to_kmh(current_speed) > highpoint_speed) + // Within 15% of top speed - locomotive less efficient + float high_speed = (float)max_speed * 0.85; + + if(power_from_steam < 1 || current_speed > highpoint_speed && current_speed < high_speed) { // Either no steam engines, or going fast // enough that it makes no difference, // so the simple formula prevails. return sum_gear_und_leistung; } - // There must be a steam engine here. - // So, reduce the power at lower speeds. + // There must be a steam locomotive here. + // So, reduce the power at higher and lower speeds. // Should be approx (for medium speed locomotive): // 40% power at 15kph 70% power at 25kph; // 85% power at 32kph; and 100% power at >50kph. @@ -568,7 +575,6 @@ sint32 convoi_t::calc_adjusted_power() float factor = 0.66 * proportion; speed_factor = 1 + factor; } - //These values are needed to apply different power reduction factors //depending on the maximum speed. @@ -587,13 +593,22 @@ sint32 convoi_t::calc_adjusted_power() float factor_modification = speed_differential_actual / speed_differential_maximum; speed_factor *= ((factor_modification * 0.4) + 0.4); } - else + else if(current_speed <= high_speed) { + // Not at high speed float speed_differential_actual = (float)current_speed - (float)midpoint_speed; float speed_differential_maximum = (float)highpoint_speed - (float)lowpoint_speed; float factor_modification = speed_differential_actual / speed_differential_maximum; speed_factor *= ((factor_modification * 0.15) + 0.8); } + else + { + // Must be within 15% of top speed here. + float speed_differential_actual = (float)max_speed - (float)current_speed; + float speed_differential_maximum = (float)max_speed - (float)high_speed; + float factor_modification = speed_differential_actual / speed_differential_maximum; + speed_factor *= ((factor_modification * 0.15) + 0.8); + } uint32 modified_power_from_steam = power_from_steam_with_gear * speed_factor; return modified_power_from_steam + power_without_steam; @@ -1070,13 +1085,64 @@ void convoi_t::step() } - void convoi_t::neues_jahr() { jahresgewinn = 0; } +uint16 convoi_t::get_overcrowded() const +{ + uint16 overcrowded = 0; + for(uint8 i = 0; i < anz_vehikel; i ++) + { + overcrowded += fahr[i]->get_overcrowding(); + } + return overcrowded; +} + +uint8 convoi_t::get_comfort() const +{ + uint8 base_comfort = 0; + uint8 catering_level = get_catering_level(0); + for(uint8 i = 0; i < anz_vehikel; i ++) + { + base_comfort += fahr[i]->get_comfort(); + } + if(anz_vehikel > 1) + { + // Avoid division if possible + base_comfort /= anz_vehikel; + } + //Else + switch(catering_level) + { + case 0: + return base_comfort; + break; + + case 1: + return base_comfort + 5; + break; + + case 2: + return base_comfort + 10; + break; + + case 3: + return base_comfort + 16; + break; + + case 4: + return base_comfort + 20; + break; + + default: + case 5: + return base_comfort + 25; + break; + }; +} void convoi_t::new_month() { @@ -1094,8 +1160,11 @@ void convoi_t::new_month() financial_history[0][j] = 0; } - rolling_average_speed = 0; - rolling_average_speed_count = 0; + for(uint8 i = 0; i < MAX_CONVOI_COST; i ++) + { + rolling_average[i] = 0; + rolling_average_count[i] = 0; + } // check for traffic jam if(state==WAITING_FOR_CLEARANCE) { @@ -1235,7 +1304,8 @@ void convoi_t::ziel_erreicht() } // we still book the money for the trip; however, the frieght will be lost - calc_gewinn(); + //calc_gewinn(); + last_departure_time = welt->get_zeit_ms(); akt_speed = 0; if (!replace || !autostart) { @@ -1324,9 +1394,9 @@ DBG_MESSAGE("convoi_t::add_vehikel()","extend array_tpl to %i totals.",max_rail_ if(info->get_engine_type() == vehikel_besch_t::steam) { power_from_steam += info->get_leistung(); - power_from_steam_with_gear += info->get_leistung()*info->get_gear(); + power_from_steam_with_gear += info->get_leistung() * info->get_gear() * welt->get_einstellungen()->get_global_power_factor(); } - sum_gear_und_leistung += info->get_leistung()*info->get_gear(); + sum_gear_und_leistung += info->get_leistung() * info->get_gear() * welt->get_einstellungen()->get_global_power_factor(); sum_gewicht += info->get_gewicht(); min_top_speed = min( min_top_speed, kmh_to_speed( v->get_besch()->get_geschw() ) ); sum_gesamtgewicht = sum_gewicht; @@ -1373,9 +1443,9 @@ convoi_t::remove_vehikel_bei(uint16 i) if(info->get_engine_type() == vehikel_besch_t::steam) { power_from_steam -= info->get_leistung(); - power_from_steam_with_gear -= info->get_leistung()*info->get_gear(); + power_from_steam_with_gear -= info->get_leistung() * info->get_gear() * welt->get_einstellungen()->get_global_power_factor(); } - sum_gear_und_leistung -= info->get_leistung()*info->get_gear(); + sum_gear_und_leistung -= info->get_leistung() * info->get_gear() * welt->get_einstellungen()->get_global_power_factor(); sum_gewicht -= info->get_gewicht(); } sum_gesamtgewicht = sum_gewicht; @@ -2057,9 +2127,9 @@ convoi_t::rdwr(loadsave_t *file) if(info->get_engine_type() == vehikel_besch_t::steam) { power_from_steam += info->get_leistung(); - power_from_steam_with_gear += info->get_leistung()*info->get_gear(); + power_from_steam_with_gear += info->get_leistung() * info->get_gear() * welt->get_einstellungen()->get_global_power_factor(); } - sum_gear_und_leistung += info->get_leistung()*info->get_gear(); + sum_gear_und_leistung += info->get_leistung() * info->get_gear() * welt->get_einstellungen()->get_global_power_factor(); sum_gewicht += info->get_gewicht(); is_electric |= info->get_engine_type()==vehikel_besch_t::electric; } @@ -2146,10 +2216,10 @@ convoi_t::rdwr(loadsave_t *file) { for (int k = MAX_MONTHS-1; k >= 0; k--) { - if(j == CONVOI_AVERAGE_SPEED && file->get_experimental_version() <= 1) + if(j == CONVOI_AVERAGE_SPEED || j == CONVOI_COMFORT && file->get_experimental_version() <= 1) { // Versions of Experimental saves with 1 and below - // did not have a setting for average speed. + // did not have settings for average speed or comfort. // Thus, this value must be skipped properly to // assign the values. financial_history[k][j] = 0; @@ -2162,10 +2232,10 @@ convoi_t::rdwr(loadsave_t *file) { for (int k = MAX_MONTHS-1; k >= 0; k--) { - if(j == CONVOI_AVERAGE_SPEED && file->get_experimental_version() <= 1) + if(j == CONVOI_AVERAGE_SPEED || j == CONVOI_COMFORT && file->get_experimental_version() <= 1) { // Versions of Experimental saves with 1 and below - // did not have a setting for average speed. + // did not have settings for average speed or comfort. // Thus, this value must be skipped properly to // assign the values. financial_history[k][j] = 0; @@ -2182,10 +2252,10 @@ convoi_t::rdwr(loadsave_t *file) { for (int k = MAX_MONTHS-1; k >= 0; k--) { - if(j == CONVOI_AVERAGE_SPEED && file->get_experimental_version() <= 1) + if(j == CONVOI_AVERAGE_SPEED || j == CONVOI_COMFORT && file->get_experimental_version() <= 1) { // Versions of Experimental saves with 1 and below - // did not have a setting for average speed. + // did not have settings for average speed or comfort. // Thus, this value must be skipped properly to // assign the values. financial_history[k][j] = 0; @@ -2335,8 +2405,11 @@ convoi_t::rdwr(loadsave_t *file) if(file->get_experimental_version() >= 2) { file->rdwr_long(last_departure_time, ""); - file->rdwr_long(rolling_average_speed, ""); - file->rdwr_short(rolling_average_speed_count, ""); + for(uint8 i = 0; i < MAX_CONVOI_COST; i ++) + { + file->rdwr_long(rolling_average[i], ""); + file->rdwr_short(rolling_average_count[i], ""); + } } } @@ -2454,23 +2527,26 @@ void convoi_t::get_freight_info(cbuffer_t & buf) // append info on total capacity slist_tpl <ware_t>capacity; - for(i=0; i<warenbauer_t::get_waren_anzahl(); i++ ) { - if(max_loaded_waren[i]>0 && i!=warenbauer_t::INDEX_NONE) { + for(i=0; i<warenbauer_t::get_waren_anzahl(); i++ ) + { + if(max_loaded_waren[i]>0 && i!=warenbauer_t::INDEX_NONE) + { ware_t ware(warenbauer_t::get_info(i)); - //TODO: Setup origins so that the ultimate origin, as well as the previous transfer, is stored. - //halthandle_t origin = welt->get_halt_koord_index(fahr[0]->get_pos().get_2d()); - //ware_t ware(warenbauer_t::get_info(i), origin, welt->get_zeit_ms()) ware.menge = max_loaded_waren[i]; if(ware.get_catg()==0) { capacity.append( ware ); - } else { + } + else + { // append to category? slist_tpl<ware_t>::iterator j = capacity.begin(); slist_tpl<ware_t>::iterator end = capacity.end(); while (j != end && j->get_catg() < ware.get_catg()) ++j; if (j != end && j->get_catg() == ware.get_catg()) { j->menge += max_loaded_waren[i]; - } else { + } + else + { // not yet there capacity.insert(j, ware); } @@ -2505,7 +2581,8 @@ void convoi_t::open_schedule_window() if(state==DRIVING) { // book the current value of goods - calc_gewinn(); + //calc_gewinn(); + last_departure_time = welt->get_zeit_ms(); } akt_speed = 0; // stop the train ... @@ -2619,37 +2696,60 @@ convoi_t::pruefe_alle() //"examine all" (Babelfish) */ void convoi_t::laden() //"load" (Babelfish) { + //Calculate average speed + //@author: jamespetts const double journey_time = (welt->get_zeit_ms() - last_departure_time) / 4096; const uint32 journey_distance = accurate_distance(fahr[0]->get_pos().get_2d(), fahr[0]->last_stop_pos); const uint16 average_speed = (journey_distance / journey_time) * 20; book(average_speed, CONVOI_AVERAGE_SPEED); + last_departure_time = welt->get_zeit_ms(); + + // Recalculate comfort + book(get_comfort(), CONVOI_COMFORT); - if(state == FAHRPLANEINGABE) { //"ENTER SCHEDULE" (Google) + for(uint8 i = 0; i < anz_vehikel; i++) + { + // Accumulate distance + slist_iterator_tpl<ware_t> iter_cargo(fahr[i]->get_fracht()); + while(iter_cargo.next()) + { + iter_cargo.access_current().add_distance(journey_distance); + } + } + + if(state == FAHRPLANEINGABE) //"ENTER SCHEDULE" (Google) + { return; } halthandle_t halt = haltestelle_t::get_halt(welt, fpl->get_current_eintrag().pos); // eigene haltestelle ? // "own stop?" (Babelfish) - if (halt.is_bound()) { + if (halt.is_bound()) + { const koord k = fpl->get_current_eintrag().pos.get_2d(); //"eintrag" = "entry" (Google) - const spieler_t* owner = halt->get_besitzer(); - if( owner == get_besitzer() || owner == welt->get_spieler(1) ) { + const spieler_t* owner = halt->get_besitzer(); //"get owner" (Google) + if( owner == get_besitzer() || owner == welt->get_spieler(1) ) + { // loading/unloading ... hat_gehalten(k, halt); } } - if(go_on_ticks==WAIT_INFINITE && fpl->get_current_eintrag().waiting_time_shift>0) { + if(go_on_ticks==WAIT_INFINITE && fpl->get_current_eintrag().waiting_time_shift>0) + { go_on_ticks = welt->get_zeit_ms() + (welt->ticks_per_tag >> (16-fpl->get_current_eintrag().waiting_time_shift)); } INT_CHECK("simconvoi 1077"); // Nun wurde ein/ausgeladen werden - if(loading_level>=loading_limit || no_load || welt->get_zeit_ms()>go_on_ticks) { + // "Now, a / unloaded" (Google) + if(loading_level >= loading_limit || no_load || welt->get_zeit_ms()>go_on_ticks) + { - if(withdraw && has_no_cargo()) { + if(withdraw && has_no_cargo()) + { // destroy when empty besitzer_p->buche( calc_restwert(), COST_NEW_VEHICLE ); besitzer_p->buche( -calc_restwert(), COST_ASSETS ); @@ -2659,7 +2759,8 @@ void convoi_t::laden() //"load" (Babelfish) } // add available capacity after loading(!) to statistics - for (unsigned i = 0; i<anz_vehikel; i++) { + for (uint8 i = 0; i<anz_vehikel; i++) + { book(get_vehikel(i)->get_fracht_max()-get_vehikel(i)->get_fracht_menge(), CONVOI_CAPACITY); } @@ -2667,10 +2768,10 @@ void convoi_t::laden() //"load" (Babelfish) fpl->advance(); state = ROUTING_1; } + // This is the minimum time it takes for loading //wait_lock = WTT_LOADING; wait_lock = longest_loading_time; - last_departure_time = welt->get_zeit_ms(); } @@ -2689,8 +2790,6 @@ void convoi_t::calc_gewinn() v->last_stop_pos = v->get_pos().get_2d(); } - last_departure_time = welt->get_zeit_ms(); - if(gewinn) { besitzer_p->buche(gewinn, fahr[0]->get_pos().get_2d(), COST_INCOME); jahresgewinn += gewinn; @@ -2701,6 +2800,50 @@ void convoi_t::calc_gewinn() } +void convoi_t::calc_revenue(ware_t& ware) +{ + sint64 revenue = 0; + float average_speed; + if(financial_history[1][CONVOI_AVERAGE_SPEED] < 1) + { + average_speed = financial_history[0][CONVOI_AVERAGE_SPEED]; + } + else + { + average_speed = financial_history[1][CONVOI_AVERAGE_SPEED]; + } + + const uint32 distance = ware.get_accumulated_distance(); + ware.reset_accumulated_distance(); + //TODO: Consdier whether to tweak this with a multiplier factor. + float journey_hours = (float)distance / average_speed; + + const ware_besch_t* goods = ware.get_besch(); + const sint32 min_price = goods->get_preis()<<7; + const sint32 base_bonus = (goods->get_preis() * (1000 + average_speed * goods->get_speed_bonus())); + revenue = (sint64)(min_price > base_bonus ? min_price : base_bonus) * (sint64)distance * (sint64)ware.menge; + + //TODO: Refine the calculation of the revenue to include comfort and overcrowding of origin stop. + + //Apply the catering bonus, if applicable. + if(get_catering_level(ware.get_besch()->get_catg_index()) > 0) + { + float catering_bonus = 1; + //TODO: Add code for calculating catering bonus + } + + sint64 final_revenue = (revenue + 1500ll) / 3000ll; + + if(final_revenue > 0) + { + besitzer_p->buche(final_revenue, fahr[0]->get_pos().get_2d(), COST_INCOME); + jahresgewinn += final_revenue; + + book(final_revenue, CONVOI_PROFIT); + book(final_revenue, CONVOI_REVENUE); + } +} + /** * convoi an haltestelle anhalten * "Convoi stop at stop" (Google translations) @@ -2714,26 +2857,32 @@ void convoi_t::hat_gehalten(koord k, halthandle_t halt) //"has held" (Google) grund_t *gr = welt->lookup(fahr[0]->get_pos()); int station_lenght = 0; - if(gr->ist_wasser()) { + if(gr->ist_wasser()) + { // habour has any size station_lenght = 24*16; } - else { + else + { // calculate real station length koord zv = koord( ribi_t::rueckwaerts(fahr[0]->get_fahrtrichtung()) ); koord3d pos = fahr[0]->get_pos(); const grund_t *grund = welt->lookup(pos); - if( grund->get_weg_yoff()==TILE_HEIGHT_STEP ) { + if( grund->get_weg_yoff()==TILE_HEIGHT_STEP ) + { // start on bridge? pos.z += Z_TILE_STEP; } - while( grund && grund->get_halt() == halt ) { + while( grund && grund->get_halt() == halt ) + { station_lenght += TILE_STEPS; pos += zv; grund = welt->lookup(pos); - if( grund==NULL ) { + if( grund==NULL ) + { grund = welt->lookup(pos-koord3d(0,0,Z_TILE_STEP)); - if( grund && grund->get_weg_yoff()!=TILE_HEIGHT_STEP ) { + if( grund && grund->get_weg_yoff()!=TILE_HEIGHT_STEP ) + { // not end/start of bridge break; } @@ -2743,32 +2892,53 @@ void convoi_t::hat_gehalten(koord k, halthandle_t halt) //"has held" (Google) // only load vehicles in station // don't load when vehicle is being withdrawn - for(unsigned i=0; i<anz_vehikel; i++) { + bool second_run = anz_vehikel <= 1; + for(uint8 i=0; i < anz_vehikel ; i++) + { vehikel_t* v = fahr[i]; + + // Run this routine twice: first, load all vehicles to their non-overcrowded capacity. + // Then, allow them to run to their overcrowded capacity. + if(!second_run && i >= anz_vehikel - 1) + { + //Reset counter for one more go + second_run = true; + i = 0; + } station_lenght -= v->get_besch()->get_length(); - if(station_lenght<0) { + if(station_lenght<0) + { break; } // we need not to call this on the same position if( v->last_stop_pos != v->get_pos().get_2d() ) { // calc_revenue - convoi_t *tmp = this; - gewinn += v->calc_gewinn(v->last_stop_pos, v->get_pos().get_2d(), tmp ); v->last_stop_pos = v->get_pos().get_2d(); - freight_info_resort |= v->entladen(k, halt); - if(!no_load) { + if(!second_run || anz_vehikel == 1) + { + convoi_t *tmp = this; + // Replaced by new revenue model + //gewinn += v->calc_gewinn(v->last_stop_pos, v->get_pos().get_2d(), tmp ); + v->last_stop_pos = v->get_pos().get_2d(); + //Unload + freight_info_resort |= v->entladen(k, halt); + } + if(!no_load) + { // do not load anymore - freight_info_resort |= v->beladen(k, halt); + freight_info_resort |= v->beladen(k, halt, second_run); + } } // any loading went on? calc_loading(); - loading_limit = fpl->get_current_eintrag().ladegrad; + loading_limit = fpl->get_current_eintrag().ladegrad; //"charge degree" (??) (Babelfish) - if(gewinn) { + if(gewinn) + { besitzer_p->buche(gewinn, fahr[0]->get_pos().get_2d(), COST_INCOME); - jahresgewinn += gewinn; + jahresgewinn += gewinn; //"annual profit" (Babelfish) book(gewinn, CONVOI_PROFIT); book(gewinn, CONVOI_REVENUE); @@ -2807,7 +2977,7 @@ void convoi_t::calc_loading() /** - * Schedule convoid for self destruction. Will be executed + * Schedule convoi for self destruction. Will be executed * upon next sync step * @author Hj. Malthaner */ @@ -2971,21 +3141,26 @@ void convoi_t::book(sint64 amount, int cost_type) { assert( cost_type<MAX_CONVOI_COST); - if(cost_type != CONVOI_AVERAGE_SPEED) + if(cost_type != CONVOI_AVERAGE_SPEED && cost_type != CONVOI_COMFORT) { + // Summative types financial_history[0][cost_type] += amount; } else { - rolling_average_speed += amount; - rolling_average_speed_count ++; - financial_history[0][cost_type] = rolling_average_speed / rolling_average_speed_count; + // Average types + rolling_average[cost_type] += amount; + rolling_average_count[cost_type] ++; + sint32 tmp = rolling_average[cost_type] / rolling_average_count[cost_type]; + financial_history[0][cost_type] = tmp; } - if (line.is_bound()) { + if (line.is_bound()) + { line->book(amount, simline_t::convoi_to_line_catgory[cost_type] ); } - if(cost_type == CONVOI_TRANSPORTED_GOODS) { + if(cost_type == CONVOI_TRANSPORTED_GOODS) + { besitzer_p->buche(amount, COST_ALL_TRANSPORTED); } } @@ -3037,26 +3212,37 @@ void convoi_t::check_pending_updates() /* * the current state saved as color - * Meanings are BLACK (ok), WHITE (no convois), YELLOW (no vehicle moved), RED (last month income minus), BLUE (at least one convoi vehicle is obsolete) + * Meanings are BLACK (ok), WHITE (no convois), YELLOW (no vehicle moved), RED (last month income minus), DARK_PURPLE (convoy has overcrowded vehicles), BLUE (at least one convoi vehicle is obsolete) */ uint8 convoi_t::get_status_color() const { - if(state==INITIAL) { + if(state==INITIAL) + { // in depot/under assembly return COL_WHITE; } - else if(state==WAITING_FOR_CLEARANCE_ONE_MONTH || state==CAN_START_ONE_MONTH || hat_keine_route()) { + else if(state==WAITING_FOR_CLEARANCE_ONE_MONTH || state==CAN_START_ONE_MONTH || hat_keine_route()) + { // stuck or no route return COL_ORANGE; } - else if(financial_history[0][CONVOI_PROFIT]+financial_history[1][CONVOI_PROFIT]<0) { + else if(financial_history[0][CONVOI_PROFIT]+financial_history[1][CONVOI_PROFIT]<0) + { // ok, not performing best return COL_RED; - } else if((financial_history[0][CONVOI_OPERATIONS]|financial_history[1][CONVOI_OPERATIONS])==0) { + } + else if((financial_history[0][CONVOI_OPERATIONS]|financial_history[1][CONVOI_OPERATIONS])==0) + { // nothing moved return COL_YELLOW; } - else if(has_obsolete) { + else if(get_overcrowded() > 0) + { + // Overcrowded + return COL_DARK_PURPLE; + } + else if(has_obsolete) + { return COL_BLUE; } // normal state @@ -3068,7 +3254,8 @@ convoi_t::get_catering_level(uint8 type) const { uint8 max_catering_level = 0; uint8 current_catering_level; - for(sint16 i = fahr.get_size() - 1; i >= 0; i --) + //for(sint16 i = fahr.get_size() - 1; i >= 0; i --) + for(uint8 i = 0; i < anz_vehikel; i ++) { vehikel_t* v = get_vehikel(i); if(v == NULL) diff --git a/simconvoi.h b/simconvoi.h index d3dddc91f80..61e0b746ddb 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -24,16 +24,17 @@ #include "simconst.h" #endif -#define MAX_CONVOI_COST 6 // Total number of cost items +#define MAX_CONVOI_COST 7 // Total number of cost items #define MAX_MONTHS 12 // Max history -#define MAX_CONVOI_NON_MONEY_TYPES 3 // number of non money types in convoi's financial statistic +#define MAX_CONVOI_NON_MONEY_TYPES 4 // number of non money types in convoi's financial statistic #define CONVOI_CAPACITY 0 // the amount of ware that could be transported, theoretically #define CONVOI_TRANSPORTED_GOODS 1 // the amount of ware that has been transported #define CONVOI_AVERAGE_SPEED 2 // The average speed of the convoy per rolling month -#define CONVOI_REVENUE 3 // the income this CONVOI generated -#define CONVOI_OPERATIONS 4 // the cost of operations this CONVOI generated -#define CONVOI_PROFIT 5 // total profit of this convoi +#define CONVOI_COMFORT 3 // The aggregate comfort rating of this convoy +#define CONVOI_REVENUE 4 // the income this CONVOI generated +#define CONVOI_OPERATIONS 5 // the cost of operations this CONVOI generated +#define CONVOI_PROFIT 6 // total profit of this convoi class depot_t; @@ -44,6 +45,7 @@ class vehikel_t; class vehikel_besch_t; class schedule_t; class cbuffer_t; +class ware_t; /** * Basisklasse für alle Fahrzeugverbände. Convois könnnen über Zeiger @@ -58,7 +60,7 @@ class convoi_t : public sync_steppable, public overtaker_t /* Konstanten * @author prissi */ - enum { max_vehicle=4, max_rail_vehicle = 24 }; + enum { max_vehicle=4, max_rail_vehicle = 64 }; enum states {INITIAL, FAHRPLANEINGABE, @@ -404,8 +406,8 @@ class convoi_t : public sync_steppable, public overtaker_t uint32 last_departure_time; //@author: jamespetts - uint32 rolling_average_speed; - uint16 rolling_average_speed_count; + uint32 rolling_average[MAX_CONVOI_COST]; + uint16 rolling_average_count[MAX_CONVOI_COST]; public: @@ -885,14 +887,35 @@ class convoi_t : public sync_steppable, public overtaker_t //@author: jamespetts uint8 get_catering_level(uint8 type) const; + //@author: jamespetts bool get_reversable() const { return reversable; } bool is_reversed() const { return reversed; } + //@author: jamespetts uint32 calc_heaviest_vehicle(); uint32 get_heaviest_vehicle() const { return heaviest_vehicle; } + //@author: jamespetts uint16 calc_longest_loading_time(); uint16 get_longest_loading_time() const { return longest_loading_time; } + + // @author: jamespetts + // Returns the number of standing passengers (etc.) in this convoy. + uint16 get_overcrowded() const; + + // @author: jamespetts + // Returns the average comfort of this convoy, + // taking into account any catering. + uint8 get_comfort() const; + + // The new revenue calculation method for per-leg + // based revenue calculation, rather than per-hop + // based revenue calculation. This method calculates + // the revenue of a ware packet unloaded, rather + // than iterating through each ware packet in each + // vehicle in the convoy. + // @author: jamespetts + void calc_revenue(ware_t &ware); }; #endif diff --git a/simfab.cc b/simfab.cc index 4fd7e83ae7a..996bd3d7d21 100644 --- a/simfab.cc +++ b/simfab.cc @@ -1028,10 +1028,11 @@ class distribute_ware_t /** * Die erzeugten waren auf die Haltestellen verteilen + * "The produced were on the stops distribute" (Babelfish) * @author Hj. Malthaner */ void fabrik_t::verteile_waren(const uint32 produkt) -{ +{ // wohin liefern ? if (lieferziele.empty()) { return; @@ -1072,7 +1073,7 @@ void fabrik_t::verteile_waren(const uint32 produkt) if (ziel_fab && (vorrat = ziel_fab->verbraucht(ausgang[produkt].get_typ())) >= 0) { //ware_t ware(ausgang[produkt].get_typ()); - ware_t ware(ausgang[produkt].get_typ(), halt, welt->get_zeit_ms()); + ware_t ware(ausgang[produkt].get_typ(), halt); ware.menge = menge; ware.set_zielpos( lieferziel ); diff --git a/simhalt.h b/simhalt.h index 24a5119d7cd..2cdc38cb729 100644 --- a/simhalt.h +++ b/simhalt.h @@ -235,6 +235,8 @@ class haltestelle_t /** * Haltestellen werden beim warenrouting markiert. Jeder durchgang * hat eine eindeutige marke + * + * "Stops are at the routing were highlighted. Each passage has a unique brand" (Google) * @author Hj. Malthaner */ uint32 marke; @@ -597,7 +599,7 @@ class haltestelle_t * return a specified element from the financial history * @author hsiegeln */ - sint64 get_finance_history(int month, int cost_type) { return financial_history[month][cost_type]; } + sint64 get_finance_history(int month, int cost_type) const { return financial_history[month][cost_type]; } // flags station for a crowded message at the beginning of next month void bescheid_station_voll() { enables |= CROWDED; status_color = COL_RED; } @@ -606,5 +608,10 @@ class haltestelle_t * @author prissi */ void mark_unmark_coverage(const bool mark) const; + + // @author: jamespetts + // Returns the proportion of unhappy people of the total of + // happy and unhappy people. + float get_unhappy_proportion(uint8 month) const { return financial_history[month][HALT_UNHAPPY] / (financial_history[month][HALT_HAPPY] + financial_history[month][HALT_UNHAPPY]); } }; #endif diff --git a/simline.cc b/simline.cc index 35b27dc956d..7bb6b65e8a3 100644 --- a/simline.cc +++ b/simline.cc @@ -10,7 +10,7 @@ #include "simlinemgmt.h" -uint8 simline_t::convoi_to_line_catgory[MAX_CONVOI_COST]={LINE_CAPACITY, LINE_TRANSPORTED_GOODS, LINE_AVERAGE_SPEED, LINE_REVENUE, LINE_OPERATIONS, LINE_PROFIT }; +uint8 simline_t::convoi_to_line_catgory[MAX_CONVOI_COST]={LINE_CAPACITY, LINE_TRANSPORTED_GOODS, LINE_AVERAGE_SPEED, LINE_COMFORT, LINE_REVENUE, LINE_OPERATIONS, LINE_PROFIT }; karte_t *simline_t::welt=NULL; @@ -27,8 +27,11 @@ simline_t::simline_t(karte_t* welt, spieler_t* sp) this->fpl = NULL; this->sp = sp; state_color = COL_YELLOW; - rolling_average_speed = 0; - rolling_average_speed_count = 0; + for(uint8 i = 0; i < MAX_LINE_COST; i ++) + { + rolling_average[i] = 0; + rolling_average_count[i] = 0; + } } @@ -159,10 +162,10 @@ void simline_t::rdwr(loadsave_t *file) { for (int k = MAX_MONTHS-1; k>=0; k--) { - if(j == LINE_AVERAGE_SPEED && file->get_experimental_version() <= 1) + if(j == LINE_AVERAGE_SPEED || j == LINE_COMFORT && file->get_experimental_version() <= 1) { // Versions of Experimental saves with 1 and below - // did not have a setting for average speed. + // did not have settings for average speed or comfort. // Thus, this value must be skipped properly to // assign the values. financial_history[k][j] = 0; @@ -176,8 +179,11 @@ void simline_t::rdwr(loadsave_t *file) if(file->get_experimental_version() >= 2) { - file->rdwr_long(rolling_average_speed, ""); - file->rdwr_short(rolling_average_speed_count, ""); + for(uint8 i = 0; i < MAX_LINE_COST; i ++) + { + file->rdwr_long(rolling_average[i], ""); + file->rdwr_short(rolling_average_count[i], ""); + } } } @@ -257,8 +263,11 @@ void simline_t::new_month() } financial_history[0][LINE_CONVOIS] = count_convoys(); - rolling_average_speed = 0; - rolling_average_speed_count = 0; + for(uint8 i = 0; i < MAX_LINE_COST; i ++) + { + rolling_average[i] = 0; + rolling_average_count[i] = 0; + } } @@ -284,36 +293,60 @@ void simline_t::init_financial_history() /* * the current state saved as color - * Meanings are BLACK (ok), WHITE (no convois), YELLOW (no vehicle moved), RED (last month income minus), BLUE (at least one convoi vehicle is obsolete) + * Meanings are BLACK (ok), WHITE (no convois), YELLOW (no vehicle moved), RED (last month income minus), DARK PURPLE (some vehicles overcrowded), BLUE (at least one convoi vehicle is obsolete) */ void simline_t::recalc_status() { - if(financial_history[0][LINE_CONVOIS]==0) { - // noconvois assigned to this line + // normal state + // Moved from an else statement at bottom + // to ensure that this value is always initialised. + state_color = COL_BLACK; + + if(financial_history[0][LINE_CONVOIS]==0) + { + // no convoys assigned to this line state_color = COL_WHITE; } - else if(financial_history[0][LINE_PROFIT]<0) { - // ok, not performing best + else if(financial_history[0][LINE_PROFIT]<0) + { + // Loss-making state_color = COL_RED; - } else if((financial_history[0][LINE_OPERATIONS]|financial_history[1][LINE_OPERATIONS])==0) { - // nothing moved + } + + else if((financial_history[0][LINE_OPERATIONS]|financial_history[1][LINE_OPERATIONS])==0) + { + // Stuck or static state_color = COL_YELLOW; } - else if(welt->use_timeline()) { - // convois has obsolete vehicles? + else if(has_overcrowded()) + { + // Overcrowded + state_color = COL_DARK_PURPLE; + } + else if(welt->use_timeline()) + { + // Has obsolete vehicles. bool has_obsolete = false; - for(unsigned i=0; !has_obsolete && i<line_managed_convoys.get_count(); i++ ) { + for(unsigned i=0; !has_obsolete && i<line_managed_convoys.get_count(); i++ ) + { has_obsolete = line_managed_convoys[i]->has_obsolete_vehicles(); } // now we have to set it state_color = has_obsolete ? COL_DARK_BLUE : COL_BLACK; } - else { - // normal state - state_color = COL_BLACK; - } } +bool simline_t::has_overcrowded() const +{ + ITERATE(line_managed_convoys,i) + { + if(line_managed_convoys[i]->get_overcrowded() > 0) + { + return true; + } + } + return false; +} // recalc what good this line is moving diff --git a/simline.h b/simline.h index 6319e02e71e..6abc4504d54 100644 --- a/simline.h +++ b/simline.h @@ -19,17 +19,18 @@ #include "linehandle_t.h" #include "convoihandle_t.h" -#define MAX_LINE_COST 7 // Total number of cost items +#define MAX_LINE_COST 8 // Total number of cost items #define MAX_MONTHS 12 // Max history #define MAX_NON_MONEY_TYPES 3 // number of non money types in line's financial statistic #define LINE_CAPACITY 0 // the amount of ware that could be transported, theoretically #define LINE_TRANSPORTED_GOODS 1 // the amount of ware that has been transported #define LINE_AVERAGE_SPEED 2 // The average speed of all convoys in the line -#define LINE_REVENUE 3 // the income this line generated -#define LINE_OPERATIONS 4 // the cost of operations this line generated -#define LINE_PROFIT 5 // total profit of line -#define LINE_CONVOIS 6 // number of convois for this line +#define LINE_COMFORT 3 // The average comfort rating of all vehicles on this line (weighted by numbers) +#define LINE_REVENUE 4 // the income this line generated +#define LINE_OPERATIONS 5 // the cost of operations this line generated +#define LINE_PROFIT 6 // total profit of line +#define LINE_CONVOIS 7 // number of convois for this line class karte_t; class simlinemgmt_t; @@ -183,15 +184,15 @@ class simline_t { void book(sint64 amount, int cost_type) { - if(cost_type != LINE_AVERAGE_SPEED) + if(cost_type != LINE_AVERAGE_SPEED && cost_type != LINE_COMFORT) { financial_history[0][cost_type] += amount; } else { - rolling_average_speed += amount; - rolling_average_speed_count ++; - financial_history[0][LINE_AVERAGE_SPEED] = rolling_average_speed / rolling_average_speed_count; + rolling_average[cost_type] += amount; + rolling_average_count[cost_type] ++; + financial_history[0][cost_type] = rolling_average[cost_type] / rolling_average_count[cost_type]; } } @@ -213,9 +214,12 @@ class simline_t { int get_replacing_convoys_count() const; + // @author: jamespetts + uint32 rolling_average[MAX_LINE_COST]; + uint16 rolling_average_count[MAX_LINE_COST]; + //@author: jamespetts - uint32 rolling_average_speed; - uint16 rolling_average_speed_count; + bool has_overcrowded() const; public: spieler_t *get_besitzer() const {return sp;} diff --git a/simware.cc b/simware.cc index 0f3f4044b49..011262a2bb9 100644 --- a/simware.cc +++ b/simware.cc @@ -31,24 +31,29 @@ ware_t::ware_t() : ziel(), zwischenziel(), zielpos(-1, -1) { menge = 0; index = 0; + accumulated_distance = 0; + journey_steps = 0; } ware_t::ware_t(const ware_besch_t *wtyp) : ziel(), zwischenziel(), zielpos(-1, -1) { + //This constructor is called from simcity.cc menge = 0; index = wtyp->get_index(); - total_journey_start_time = journey_leg_start_time = 0; + accumulated_distance = 0; + journey_steps = 0; } // Constructor for new revenue system: packet of cargo keeps track of its origin. //@author: jamespetts -ware_t::ware_t(const ware_besch_t *wtyp, halthandle_t o, uint32 t) : ziel(), zwischenziel(), zielpos(-1, -1) +ware_t::ware_t(const ware_besch_t *wtyp, halthandle_t o) : ziel(), zwischenziel(), zielpos(-1, -1) { menge = 0; index = wtyp->get_index(); - origin = previous_transfer = o; - total_journey_start_time = journey_leg_start_time = t; + origin = o; + accumulated_distance = 0; + journey_steps = 0; } @@ -110,10 +115,8 @@ ware_t::rdwr(karte_t *welt,loadsave_t *file) if(file->get_experimental_version() >= 1) { koord origin_koord = origin.is_bound() ? origin->get_basis_pos() : koord::invalid; - koord previous_transfer_koord = previous_transfer.is_bound() ? previous_transfer->get_basis_pos() : koord::invalid; - origin_koord.rdwr(file); - previous_transfer_koord.rdwr(file); + } } else @@ -128,28 +131,45 @@ ware_t::rdwr(karte_t *welt,loadsave_t *file) if(file->get_experimental_version() >= 1) { koord origin_koord; - koord previous_transfer_koord; origin_koord.rdwr(file); - previous_transfer_koord.rdwr(file); + if(file->get_experimental_version() == 1) + { + // Simutrans-Experimental save version 1 had extra parameters + // such as "previous transfer" intended for use in the new revenue + // system. In the end, the system was designed differently, and + // these values are not present in versions 2 and above. + koord dummy; + dummy.rdwr(file); + } origin = welt->get_halt_koord_index(origin_koord); - previous_transfer = welt->get_halt_koord_index(previous_transfer_koord); } else { - origin = previous_transfer = zwischenziel; - total_journey_start_time = journey_leg_start_time = welt->get_zeit_ms(); + origin = zwischenziel; } } zielpos.rdwr(file); - if(file->get_experimental_version() >= 1) + if(file->get_experimental_version() == 1) + { + uint32 dummy_2; + file->rdwr_long(dummy_2, ""); + file->rdwr_long(dummy_2, ""); + } + + if(file->get_experimental_version() >= 2) + { + file->rdwr_long(accumulated_distance, ""); + file->rdwr_byte(journey_steps, ""); + } + else { - file->rdwr_long(total_journey_start_time, ""); - file->rdwr_long(journey_leg_start_time, ""); + accumulated_distance = 0; + journey_steps = 0; } } @@ -170,8 +190,9 @@ ware_t::laden_abschliessen(karte_t *welt) //"Invite finish" (Google); "load lock if(origin.is_bound()) { origin = welt->lookup(origin->get_init_pos())->get_halt(); } - - if(previous_transfer.is_bound()) { - previous_transfer = welt->lookup(previous_transfer->get_init_pos())->get_halt(); - } } + +void ware_t::add_distance(uint32 distance) +{ + accumulated_distance += distance; +} \ No newline at end of file diff --git a/simware.h b/simware.h index 6cb31be247e..dfb26f8ba34 100644 --- a/simware.h +++ b/simware.h @@ -41,15 +41,6 @@ class ware_t //A handle to the ultimate origin. halthandle_t origin; - //The immediately previous transfer (*not* hop) - halthandle_t previous_transfer; - - //The time at which the packet's whole journey began, in ticks. - uint32 total_journey_start_time; - - //The time at which the current leg of the journey began, in ticks. - uint32 journey_leg_start_time; - /** * die engültige Zielposition, * das ist i.a. nicht die Zielhaltestellenposition @@ -62,6 +53,10 @@ class ware_t //The number of remaining steps on this packet's journey. uint8 journey_steps; + // @author: jamespetts + // The distance travelled so far this leg of the journey. + uint32 accumulated_distance; + public: const halthandle_t &get_ziel() const { return ziel; } void set_ziel(const halthandle_t &ziel) { this->ziel = ziel; } @@ -74,7 +69,7 @@ class ware_t ware_t(); ware_t(const ware_besch_t *typ); - ware_t(const ware_besch_t *typ, halthandle_t o, uint32 t); + ware_t(const ware_besch_t *typ, halthandle_t o); ware_t(karte_t *welt,loadsave_t *file); /** @@ -91,12 +86,12 @@ class ware_t //@author: jamespetts halthandle_t get_origin() const { return origin; } void set_origin(halthandle_t value) { origin = value; } - halthandle_t get_previous_transfer() const { return previous_transfer; } - void set_previous_transfer(halthandle_t value) { previous_transfer = value; } - uint32 get_total_journey_start_time() const { return total_journey_start_time; } - void set_total_journey_start_time(uint32 value) { total_journey_start_time = value; } - uint32 get_journey_leg_start_time() const { return journey_leg_start_time; } - void set_journey_leg_start_time(uint32 value) { journey_leg_start_time = value; } + + //@author: jamespetts + uint32 get_accumulated_distance() const { return accumulated_distance; } + //void add_distance(uint32 distance) { accumulated_distance += distance; } + void add_distance(uint32 distance); + void reset_accumulated_distance() { accumulated_distance = 0; } const ware_besch_t* get_besch() const { return index_to_besch[index]; } void set_besch(const ware_besch_t* type); @@ -127,14 +122,7 @@ class ware_t ziel == w.ziel && // Only merge the destination *position* if the load is not freight (index > 2 || zielpos == w.zielpos) && - origin == w.origin && - previous_transfer == w.previous_transfer && - // Goods generated within 15 secs (at default speed) of each other - // treated as identical if identical in all other respects. - !(total_journey_start_time > w.total_journey_start_time + 15000) && - !(total_journey_start_time < w.total_journey_start_time - 15000) && - !(journey_leg_start_time > w.journey_leg_start_time + 15000) && - !(journey_leg_start_time < w.journey_leg_start_time - 15000); + origin == w.origin; } diff --git a/simworld.cc b/simworld.cc index 90e98334603..8f7a09fa2a9 100644 --- a/simworld.cc +++ b/simworld.cc @@ -2406,6 +2406,20 @@ void karte_t::neuer_monat() }*/ INT_CHECK("simworld 1278"); + // DBG_MESSAGE("karte_t::neuer_monat()","cities"); + // roll city history and copy the new citicens (i.e. the new weight) into the stadt array + // no INT_CHECK() here, or dialoges will go crazy!!! + weighted_vector_tpl<stadt_t*> new_weighted_stadt(stadt.get_count() + 1); + for (weighted_vector_tpl<stadt_t*>::const_iterator i = stadt.begin(), end = stadt.end(); i != end; ++i) { + stadt_t* s = *i; + s->neuer_monat(); + new_weighted_stadt.append(s, s->get_einwohner(), 64); + INT_CHECK("simworld 1278"); + } + swap(stadt, new_weighted_stadt); + + INT_CHECK("simworld 1282"); + // DBG_MESSAGE("karte_t::neuer_monat()","players"); // spieler for(int i=0; i<MAX_PLAYER_COUNT; i++) { @@ -2762,7 +2776,8 @@ karte_t::step() // to make sure the tick counter will be updated INT_CHECK("karte_t::step"); - for(unsigned i=0; i<convoi_array.get_count(); i++) { + ITERATE(convoi_array,i) + { convoihandle_t cnv = convoi_array[i]; cnv->step(); if((i&7)==0) { @@ -2780,11 +2795,8 @@ karte_t::step() // the inhabitants stuff finance_history_month[0][WORLD_CITICENS] = bev; - //slist_iterator_tpl<fabrik_t *> iter(fab_list); - //while(iter.next()) { - for(sint16 i = fab_list.get_count() - 1; i >= 0; i --) + ITERATE(fab_list,i) { - //iter.get_current()->step(delta_t); fab_list[i]->step(delta_t); } finance_history_year[0][WORLD_FACTORIES] = finance_history_month[0][WORLD_FACTORIES] = fab_list.get_count(); diff --git a/tpl/fixed_list_tpl.h b/tpl/fixed_list_tpl.h index c6545ebec71..5a29ce74a0e 100644 --- a/tpl/fixed_list_tpl.h +++ b/tpl/fixed_list_tpl.h @@ -16,11 +16,11 @@ #define TPL_FIXED_LIST_H #ifndef ITERATE -#define ITERATE(collection,i) for(uint16 i = 0; i < (collection).get_count(); i++) +#define ITERATE(collection,enumerator) for(uint16 enumerator = 0; enumerator < (collection).get_count(); enumerator++) #endif #ifndef ITERATE_PTR -#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < (collection)->get_count(); i++) +#define ITERATE_PTR(collection,enumerator) for(uint16 enumerator = 0; enumerator < (collection)->get_count(); enumerator++) #endif #include <typeinfo> diff --git a/tpl/ordered_vector_tpl.h b/tpl/ordered_vector_tpl.h index 71c255ddc6c..f9126b52b2c 100644 --- a/tpl/ordered_vector_tpl.h +++ b/tpl/ordered_vector_tpl.h @@ -2,11 +2,11 @@ #define TPL_ORDERED_VECTOR_TPL_H #ifndef ITERATE -#define ITERATE(collection,i) for(uint16 i = 0; i < (collection).get_count(); i++) +#define ITERATE(collection,enumerator) for(uint16 enumerator = 0; enumerator < (collection).get_count(); enumerator++) #endif #ifndef ITERATE_PTR -#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < (collection)->get_count(); i++) +#define ITERATE_PTR(collection,enumerator) for(uint16 enumerator = 0; enumerator < (collection)->get_count(); enumerator++) #endif #include "../simtypes.h" diff --git a/tpl/vector_tpl.h b/tpl/vector_tpl.h index f733eba672f..5e427ced88c 100644 --- a/tpl/vector_tpl.h +++ b/tpl/vector_tpl.h @@ -2,11 +2,11 @@ #define TPL_VECTOR_H #ifndef ITERATE -#define ITERATE(collection,i) for(uint16 i = 0; i < (collection).get_count(); i++) +#define ITERATE(collection,enumerator) for(uint16 enumerator = 0; enumerator < (collection).get_count(); enumerator++) #endif #ifndef ITERATE_PTR -#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < (collection)->get_count(); i++) +#define ITERATE_PTR(collection,enumerator) for(uint16 enumerator = 0; enumerator < (collection)->get_count(); enumerator++) #endif #include <stdlib.h> diff --git a/tpl/weighted_vector_tpl.h b/tpl/weighted_vector_tpl.h index beaa31a9f51..2792cd73574 100644 --- a/tpl/weighted_vector_tpl.h +++ b/tpl/weighted_vector_tpl.h @@ -2,11 +2,11 @@ #define TPL_WEIGHTED_VECTOR_H #ifndef ITERATE -#define ITERATE(collection,i) for(uint16 i = 0; i < collection.get_count(); i++) +#define ITERATE(collection,enumerator) for(uint16 enumerator = 0; enumerator < collection.get_count(); enumerator++) #endif #ifndef ITERATE_PTR -#define ITERATE_PTR(collection,i) for(uint16 i = 0; i < collection->get_count(); i++) +#define ITERATE_PTR(collection,enumerator) for(uint16 enumerator = 0; enumerator < collection->get_count(); ienumerator++) #endif #include "../macros.h" diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 5854889494b..71bf8c43e99 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -696,11 +696,14 @@ vehikel_t::unload_freight(halthandle_t halt) uint16 sum_menge = 0; slist_tpl<ware_t> kill_queue; - if(halt->is_enabled( get_fracht_typ() )) { - if (!fracht.empty()) { + if(halt->is_enabled( get_fracht_typ() )) + { + if (!fracht.empty()) + { slist_iterator_tpl<ware_t> iter (fracht); - while(iter.next()) { + while(iter.next()) + { const ware_t& tmp = iter.get_current(); halthandle_t end_halt = tmp.get_ziel(); @@ -709,10 +712,14 @@ vehikel_t::unload_freight(halthandle_t halt) // probleme mit fehlerhafter ware // vielleicht wurde zwischendurch die // Zielhaltestelle entfernt ? - if(!end_halt.is_bound() || !via_halt.is_bound()) { + if(!end_halt.is_bound() || !via_halt.is_bound()) + { DBG_MESSAGE("vehikel_t::entladen()", "destination of %d %s is no longer reachable",tmp.menge,translator::translate(tmp.get_name())); kill_queue.insert(tmp); - } else if(end_halt==halt || via_halt==halt) { + } + + else if(end_halt==halt || via_halt==halt) + { // printf("Liefere %d %s nach %s via %s an %s\n", // tmp->menge, @@ -722,13 +729,19 @@ vehikel_t::unload_freight(halthandle_t halt) // halt->get_name()); // hier sollte nur ordentliche ware verabeitet werden - // "here only tidy commodity should be processed" (Babelfish) + // "here only tidy commodity should be processed" (Babelfish) int menge = halt->liefere_an(tmp); //"supply" (Babelfish) sum_menge += menge; + // Calculates the revenue for each packet under the new + // revenue model. + // @author: jamespetts + cnv->calc_revenue(iter.access_current()); + // book delivered goods to destination - if(end_halt==halt) { - // pax is alway index 1 + if(end_halt==halt) + { + // pax is always index 1 const int categorie = tmp.get_index()>1 ? 2 : tmp.get_index(); get_besitzer()->buche( menge, (player_cost)(COST_TRANSPORTED_PAS+categorie) ); } @@ -742,7 +755,8 @@ vehikel_t::unload_freight(halthandle_t halt) } slist_iterator_tpl<ware_t> iter (kill_queue); - while( iter.next() ) { + while( iter.next() ) + { total_freight -= iter.get_current().menge; bool ok = fracht.remove(iter.get_current()); assert(ok); @@ -757,18 +771,24 @@ vehikel_t::unload_freight(halthandle_t halt) * @return loading successful? * @author Hj. Malthaner */ -bool vehikel_t::load_freight(halthandle_t halt) +bool vehikel_t::load_freight(halthandle_t halt, bool overcrowd) { const bool ok = halt->gibt_ab(besch->get_ware()); schedule_t *fpl = cnv->get_schedule(); - if( ok ) { + if( ok ) + { - while(total_freight < besch->get_zuladung()) { - const uint16 hinein = besch->get_zuladung() - total_freight; + while(total_freight < besch->get_zuladung() + (overcrowd ? besch->get_overcrowded_capacity() : 0)) //"Payload" (Google) + { + // Modified to allow overcrowding. + // @author: jamespetts + const uint16 hinein = (besch->get_zuladung() - total_freight) + (overcrowd ? besch->get_overcrowded_capacity() : 0); + //hinein = inside (Google) ware_t ware = halt->hole_ab(besch->get_ware(), hinein, fpl); - //hinein = inside (Google) - if(ware.menge==0) { + + if(ware.menge==0) + { // now empty, but usually, we can get it here ... return ok; } @@ -776,7 +796,8 @@ bool vehikel_t::load_freight(halthandle_t halt) slist_iterator_tpl<ware_t> iter (fracht); // could this be joined with existing freight? - while(iter.next()) { + while(iter.next()) + { ware_t &tmp = iter.access_current(); /* @@ -787,7 +808,7 @@ bool vehikel_t::load_freight(halthandle_t halt) * if(ware.same_destination(tmp)) { */ - // New system: only merges if origins and timings are alike. + // New system: only merges if origins are alike. // @author: jamespetts if(ware.can_merge_with(tmp)) { @@ -798,8 +819,9 @@ bool vehikel_t::load_freight(halthandle_t halt) } } - // if != 0 we could not joi it to existing => load it - if(ware.menge != 0) { + // if != 0 we could not join it to existing => load it + if(ware.menge != 0) + { fracht.insert(ware); total_freight += ware.menge; } @@ -1094,7 +1116,21 @@ vehikel_t::hop() { // Fahrtkosten // "Travel costs" (Babelfish) - cnv->add_running_cost(-besch->get_betriebskosten(welt)); + uint16 costs = besch->get_betriebskosten(welt); + if(costs != base_costs) + { + // Recalculate base costs only if necessary + // With this formula, no need to initialise base + // costs or diagonal costs! + base_costs = costs; + diagonal_costs = (costs * diagonal_length) / 255; + } + if(steps_next != 255) + { + costs = diagonal_costs; + } + + cnv->add_running_cost(-costs); verlasse_feld(); //"Verlasse" = "leave" (Babelfish) @@ -1586,11 +1622,13 @@ sint64 vehikel_t::calc_gewinn(koord start, koord end, convoi_t *cnv) const slist_tpl<ware_t> kill_queue; slist_iterator_tpl <ware_t> iter (fracht); - while( iter.next() ) { + while( iter.next() ) + { const ware_t &ware = iter.get_current(); - if(ware.menge==0 || !ware.get_zwischenziel().is_bound()) { + if(ware.menge==0 || !ware.get_zwischenziel().is_bound()) + { continue; } @@ -1730,13 +1768,14 @@ vehikel_t::loesche_fracht() bool -vehikel_t::beladen(koord , halthandle_t halt) +vehikel_t::beladen(koord, halthandle_t halt, bool overcrowd) { bool ok = true; - if(halt.is_bound()) { - ok = load_freight(halt); + if(halt.is_bound()) + { + ok = load_freight(halt, overcrowd); } - sum_weight = (get_fracht_gewicht()+499)/1000 + besch->get_gewicht(); + sum_weight = (get_fracht_gewicht()+499)/1000 + besch->get_gewicht(); calc_bild(); return ok; } @@ -1751,7 +1790,8 @@ bool vehikel_t::entladen(koord, halthandle_t halt) { // printf("Vehikel %p entladen\n", this); uint16 menge = unload_freight(halt); - if(menge>0) { + if(menge > 0) + { // add delivered goods to statistics cnv->book(menge, CONVOI_TRANSPORTED_GOODS); // add delivered goods to halt's statistics @@ -1836,8 +1876,7 @@ vehikel_t::get_direction_of_travel() return dir; } -void -vehikel_t::set_reversed(bool value) +void vehikel_t::set_reversed(bool value) { if(besch->is_bidirectional() || (cnv != NULL && cnv->get_reversable())) { @@ -1845,6 +1884,49 @@ vehikel_t::set_reversed(bool value) } } +uint16 vehikel_t::get_overcrowding() const +{ + return total_freight - besch->get_zuladung() > 0 ? total_freight - besch->get_zuladung() : 0; +} + +uint8 vehikel_t::get_comfort() const +{ + if(besch->get_comfort() == 0) + { + return 0; + } + else if(total_freight <= get_fracht_max()) + { + // Not overcrowded - return base level + return besch->get_comfort(); + } + + // Else + // Overcrowded - adjust comfort. Standing passengers + // are very uncomfortable (no more than 10). + const uint8 standing_comfort = 10 < besch->get_comfort() - 5 ? 10 : besch->get_comfort() / 2; + uint16 passenger_count = 0; + slist_iterator_tpl<ware_t> iter(fracht); + while(iter.next()) + { + ware_t ware = iter.get_current(); + if(ware.get_catg() == 0) + { + passenger_count += ware.menge; + } + } + const uint16 total_seated_passengers = passenger_count < get_fracht_max() ? passenger_count : get_fracht_max(); + const uint16 total_standing_passengers = passenger_count > total_seated_passengers ? passenger_count - total_seated_passengers : 0; + // Avoid division if we can + if(total_seated_passengers < 1) + { + return besch->get_comfort(); + } + // Else + // Average comfort of seated and standing + return ((total_seated_passengers * besch->get_comfort()) + (total_standing_passengers * standing_comfort)) / passenger_count; +} + void vehikel_t::rdwr(loadsave_t *file) { // this is only called from dingliste => we save nothing ... diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index df74a6dc11f..dc8976ea12c 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -180,8 +180,6 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t uint32 calc_modified_speed_limit(const koord3d *position, ribi_t::ribi current_direction, bool is_corner); - uint32 smooth_speed(uint32 current_limit); - /** * Unload freight to halt * @return sum of unloaded goods @@ -194,15 +192,17 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t * @return loading successful? * @author Hj. Malthaner */ - bool load_freight(halthandle_t halt); + bool load_freight(halthandle_t halt) { return load_freight(halt, false); } - //@author: jamespetts - //uint16 local_bonus_supplement; - //A supplementary bonus for local transportation, - //if needed, to compensate for not having the effect - //of the long-distance speed bonus. + bool load_freight(halthandle_t halt, bool overcrowd); - //@author: jamespetts + // @author: jamespetts + // uint16 local_bonus_supplement; + // A supplementary bonus for local transportation, + // if needed, to compensate for not having the effect + // of the long-distance speed bonus. + + // @author: jamespetts // Cornering settings. fixed_list_tpl<sint16, 16> pre_corner_direction; @@ -214,9 +214,14 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t bool is_overweight; // Whether this individual vehicle is reversed. - //@author: jamespetts + // @author: jamespetts bool reversed; + + //@author: jamespetts + uint16 diagonal_costs; + uint16 base_costs; + //#define debug_corners #ifdef debug_corners @@ -454,7 +459,9 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t /** * fahrzeug an haltestelle beladen */ - bool beladen(koord k, halthandle_t halt); + bool beladen(koord k, halthandle_t halt) { return beladen(k, halt, false); } + + bool beladen(koord k, halthandle_t halt, bool overcrowd); // sets or querey begin and end of convois void set_erstes(bool janein) {ist_erstes = janein;} //janein = "yesno" (Google) @@ -500,6 +507,12 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t uint16 get_sum_weight() const { return sum_weight; } + // @author: jamespetts + uint16 get_overcrowding() const; + + // @author: jamespetts + uint8 get_comfort() const; + }; From c16f4581895d1b45c8b6832c2cd2dfb6ec32f6b9 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 29 Mar 2009 16:08:04 +0100 Subject: [PATCH 41/61] Further work on the new revenue model. Not yet complete, but speed and comfort settings are present. Also, fixed a bug that would cause a crash when reading settings.xml in some caes. --- dataobj/einstellungen.cc | 80 +++++++++++++--- dataobj/einstellungen.h | 38 +++++++- simconvoi.cc | 191 ++++++++++++++++++++++++++++++++++++--- simconvoi.h | 10 +- simhalt.h | 2 +- simmain.cc | 3 +- vehicle/simvehikel.cc | 14 +-- vehicle/simvehikel.h | 2 +- 8 files changed, 298 insertions(+), 42 deletions(-) diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index 71b8aa57e0f..3dbf01e2eff 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -174,10 +174,27 @@ einstellungen_t::einstellungen_t() : // defualt: joined capacities seperate_halt_capacities = false; - // Local bonus adjustment + // Revenue calibration settings + // @author: jamespetts min_bonus_max_distance = 16; - max_bonus_min_distance = 256; - local_bonus_multiplier = 10; + max_bonus_min_distance = 1024; + median_bonus_distance = 0; + max_bonus_multiplier_percent = 300; + journey_time_multiplier_percent = 30; + tolerable_comfort_short = 15; + tolerable_comfort_median_short = 60; + tolerable_comfort_median_median = 100; + tolerable_comfort_median_long = 160; + tolerable_comfort_long = 220; + tolerable_comfort_short_minutes = 2; + tolerable_comfort_median_short_minutes = 30; + tolerable_comfort_median_median_minutes = 120; + tolerable_comfort_median_long_minutes = 300; + tolerable_comfort_long_minutes = 720; + max_luxury_bonus_differential = 75; + max_luxury_bonus_percent = 50; + max_discomfort_penalty_differential = 200; + max_discomfort_penalty_percent = 95; // Obsolete vehicles running costs adjustment obsolete_running_cost_increase_percent = 400; //Running costs will be this % of normal costs after vehicle has been obsolete @@ -514,7 +531,31 @@ void einstellungen_t::rdwr(loadsave_t *file) { file->rdwr_short(min_bonus_max_distance, ""); file->rdwr_short(max_bonus_min_distance, ""); - file->rdwr_short(local_bonus_multiplier, ""); + if(file->get_experimental_version() <= 1) + { + uint16 dummy; + file->rdwr_short(dummy, ""); + } + else + { + file->rdwr_short(median_bonus_distance, ""); + file->rdwr_short(max_bonus_multiplier_percent, ""); + file->rdwr_short(journey_time_multiplier_percent, ""); + file->rdwr_byte(tolerable_comfort_short, ""); + file->rdwr_byte(tolerable_comfort_median_short, ""); + file->rdwr_byte(tolerable_comfort_median_median, ""); + file->rdwr_byte(tolerable_comfort_median_long, ""); + file->rdwr_byte(tolerable_comfort_long, ""); + file->rdwr_short(tolerable_comfort_short_minutes, ""); + file->rdwr_short(tolerable_comfort_median_short_minutes, ""); + file->rdwr_short(tolerable_comfort_median_median_minutes, ""); + file->rdwr_short(tolerable_comfort_median_long_minutes, ""); + file->rdwr_short(tolerable_comfort_long_minutes, ""); + file->rdwr_byte(max_luxury_bonus_differential, ""); + file->rdwr_byte(max_discomfort_penalty_differential, ""); + file->rdwr_short(max_discomfort_penalty_percent, ""); + file->rdwr_short(max_luxury_bonus_percent, ""); + } file->rdwr_short(obsolete_running_cost_increase_percent, ""); file->rdwr_short(obsolete_running_cost_increase_phase_years, ""); @@ -609,7 +650,7 @@ void einstellungen_t::rdwr(loadsave_t *file) if(file->get_experimental_version() >= 2) { uint16 global_power_factor_percent = global_power_factor * 100; - //file->rdwr_short(global_power_factor_percent, ""); + file->rdwr_short(global_power_factor_percent, ""); global_power_factor = (float)global_power_factor_percent / 100; } @@ -761,12 +802,29 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s way_max_bridge_len = contents.get_int("way_max_bridge_len", way_max_bridge_len); way_count_leaving_road = contents.get_int("way_leaving_road", way_count_leaving_road); - //Local bonus adjustment + // Revenue calibration settings + // @author: jamespetts min_bonus_max_distance = contents.get_int("min_bonus_max_distance", min_bonus_max_distance); max_bonus_min_distance = contents.get_int("max_bonus_min_distance", max_bonus_min_distance); - local_bonus_multiplier = contents.get_int("local_bonus_multiplier_percent", local_bonus_multiplier); - - //Obsolete vehicles' running cost increase + median_bonus_distance = contents.get_int("median_bonus_distance", median_bonus_distance); + max_bonus_multiplier_percent = contents.get_int("max_bonus_multiplier_percent", max_bonus_multiplier_percent); + journey_time_multiplier_percent = contents.get_int("journey_time_multiplier_percent", journey_time_multiplier_percent); + tolerable_comfort_short = contents.get_int("tolerable_comfort_short", tolerable_comfort_short); + tolerable_comfort_long = contents.get_int("tolerable_comfort_long", tolerable_comfort_long); + tolerable_comfort_short_minutes = contents.get_int("tolerable_comfort_short_minutes", tolerable_comfort_short_minutes); + tolerable_comfort_long_minutes = contents.get_int("tolerable_comfort_long_minutes", tolerable_comfort_long_minutes); + tolerable_comfort_median_short = contents.get_int("tolerable_comfort_median_short", tolerable_comfort_median_short); + tolerable_comfort_median_median = contents.get_int("tolerable_comfort_median_median", tolerable_comfort_median_median); + tolerable_comfort_median_long = contents.get_int("tolerable_comfort_median_long", tolerable_comfort_median_long); + tolerable_comfort_median_short_minutes = contents.get_int("tolerable_comfort_median_short_minutes", tolerable_comfort_median_short_minutes); + tolerable_comfort_median_short_minutes = contents.get_int("tolerable_comfort_median_median_minutes", tolerable_comfort_median_median_minutes); + tolerable_comfort_median_long_minutes = contents.get_int("tolerable_comfort_median_long_minutes", tolerable_comfort_median_long_minutes); + max_luxury_bonus_differential = contents.get_int("max_luxury_bonus_differential", max_luxury_bonus_differential); + max_discomfort_penalty_differential = contents.get_int("max_discomfort_penalty_differential", max_discomfort_penalty_differential); + max_luxury_bonus_percent = contents.get_int("max_luxury_bonus_percent", max_luxury_bonus_percent); + max_discomfort_penalty_percent = contents.get_int("max_discomfort_penalty_percent", max_discomfort_penalty_percent); + + // Obsolete vehicles' running cost increase obsolete_running_cost_increase_percent = contents.get_int("obsolete_running_cost_increase_percent", obsolete_running_cost_increase_percent); obsolete_running_cost_increase_phase_years = contents.get_int("obsolete_running_cost_increase_phase_years", obsolete_running_cost_increase_phase_years); @@ -787,7 +845,7 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s always_prefer_car_percent = contents.get_int("always_prefer_car_percent", always_prefer_car_percent); congestion_density_factor = contents.get_int("congestion_density_factor", congestion_density_factor); - //Cornering settings + // Cornering settings max_corner_limit[waytype_t(road_wt)] = contents.get_int("max_corner_limit_road", 200); min_corner_limit[waytype_t(road_wt)] = contents.get_int("min_corner_limit_road", 30); max_corner_adjustment_factor[waytype_t(road_wt)] = contents.get_int("max_corner_adjustment_factor_road", 75); @@ -844,7 +902,7 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s max_direction_steps[waytype_t(narrowgauge_wt)] = contents.get_int("max_direction_steps_narrowgauge", 8); curve_friction_factor[waytype_t(narrowgauge_wt)] = contents.get_int("curve_friction_factor_narrowgauge", 0); - //Factory settings + // Factory settings factory_max_years_obsolete = contents.get_int("max_years_obsolete", factory_max_years_obsolete); // @author: jamespetts diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index e898620bd6c..f8dfc3d8b58 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -169,10 +169,26 @@ class einstellungen_t bool no_routing_over_overcrowding; //@author: jamespetts - // Speed bonus local adjustment + // Revenue calibration settings uint16 min_bonus_max_distance; uint16 max_bonus_min_distance; - uint16 local_bonus_multiplier; + uint16 median_bonus_distance; + uint16 max_bonus_multiplier_percent; + uint16 journey_time_multiplier_percent; + uint8 tolerable_comfort_short; + uint8 tolerable_comfort_median_short; + uint8 tolerable_comfort_median_median; + uint8 tolerable_comfort_median_long; + uint8 tolerable_comfort_long; + uint16 tolerable_comfort_short_minutes; + uint16 tolerable_comfort_median_short_minutes; + uint16 tolerable_comfort_median_median_minutes; + uint16 tolerable_comfort_median_long_minutes; + uint16 tolerable_comfort_long_minutes; + uint8 max_luxury_bonus_differential; + uint8 max_discomfort_penalty_differential; + uint16 max_luxury_bonus_percent; + uint16 max_discomfort_penalty_percent; //@author: jamespetts // Obsolete vehicle maintenance cost increases @@ -409,7 +425,23 @@ class einstellungen_t uint16 get_min_bonus_max_distance() const { return min_bonus_max_distance; } uint16 get_max_bonus_min_distance() const { return max_bonus_min_distance; } - uint16 get_local_bonus_multiplier() const { return local_bonus_multiplier; } + uint16 get_median_bonus_distance() const { return median_bonus_distance; } + float get_max_bonus_multiplier() const { return (float)max_bonus_multiplier_percent * 0.01; } + float get_journey_time_multiplier() const { return (float)journey_time_multiplier_percent * 0.01; } + uint8 get_tolerable_comfort_short() const { return tolerable_comfort_short; } + uint8 get_tolerable_comfort_median_short() const { return tolerable_comfort_median_short; } + uint8 get_tolerable_comfort_median_median() const { return tolerable_comfort_median_median; } + uint8 get_tolerable_comfort_median_long() const { return tolerable_comfort_median_long; } + uint8 get_tolerable_comfort_long() const { return tolerable_comfort_long; } + uint16 get_tolerable_comfort_short_minutes() const { return tolerable_comfort_short_minutes; } + uint16 get_tolerable_comfort_median_short_minutes() const { return tolerable_comfort_median_short_minutes; } + uint16 get_tolerable_comfort_median_median_minutes() const { return tolerable_comfort_median_median_minutes; } + uint16 get_tolerable_comfort_median_long_minutes() const { return tolerable_comfort_median_long_minutes; } + uint16 get_tolerable_comfort_long_minutes() const { return tolerable_comfort_long_minutes; } + uint8 get_max_luxury_bonus_differential() const { return max_luxury_bonus_differential; } + uint8 get_max_discomfort_penalty_differential() const { return max_discomfort_penalty_differential; } + float get_max_luxury_bonus() const { return (float)max_luxury_bonus_percent * 0.01; } + float get_max_discomfort_penalty() const { return (float) max_discomfort_penalty_percent * 0.01; } uint16 get_obsolete_running_cost_increase_percent() const { return obsolete_running_cost_increase_percent; } uint16 get_obsolete_running_cost_increase_phase_years() const { return obsolete_running_cost_increase_phase_years; } diff --git a/simconvoi.cc b/simconvoi.cc index 34f27c2e9e7..09c236b631d 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -2779,7 +2779,7 @@ void convoi_t::laden() //"load" (Babelfish) * calculate income for last hop * @author Hj. Malthaner */ -void convoi_t::calc_gewinn() +/*void convoi_t::calc_gewinn() { sint64 gewinn = 0; @@ -2797,12 +2797,11 @@ void convoi_t::calc_gewinn() book(gewinn, CONVOI_PROFIT); book(gewinn, CONVOI_REVENUE); } -} +}*/ void convoi_t::calc_revenue(ware_t& ware) { - sint64 revenue = 0; float average_speed; if(financial_history[1][CONVOI_AVERAGE_SPEED] < 1) { @@ -2813,26 +2812,86 @@ void convoi_t::calc_revenue(ware_t& ware) average_speed = financial_history[1][CONVOI_AVERAGE_SPEED]; } + // Cannot not charge for journey if the journey distance is more than a certain proportion of the straight line distance. + // This eliminates the possibility of cheating by building circuitous routes, or the need to prevent that by always using + // the straight line distance, which makes the game difficult and unrealistic. + const uint32 max_distance = accurate_distance(ware.get_origin()->get_basis_pos(), fahr[0]->get_pos().get_2d()) * 2.2; const uint32 distance = ware.get_accumulated_distance(); + const uint32 revenue_distance = distance < max_distance ? distance : max_distance; + ware.reset_accumulated_distance(); - //TODO: Consdier whether to tweak this with a multiplier factor. - float journey_hours = (float)distance / average_speed; - const ware_besch_t* goods = ware.get_besch(); - const sint32 min_price = goods->get_preis()<<7; - const sint32 base_bonus = (goods->get_preis() * (1000 + average_speed * goods->get_speed_bonus())); - revenue = (sint64)(min_price > base_bonus ? min_price : base_bonus) * (sint64)distance * (sint64)ware.menge; + //Multiply by a factor (default: 0.3) to ensure that it fits the scale properly. Journey times can easily appear too long. + uint16 journey_minutes = (((float)distance / average_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 60); - //TODO: Refine the calculation of the revenue to include comfort and overcrowding of origin stop. + const ware_besch_t* goods = ware.get_besch(); + const uint16 price = goods->get_preis(); + const sint32 min_price = price << 7; + const uint16 speed_bonus_rating = calc_adjusted_speed_bonus(goods->get_speed_bonus(), distance); + const sint32 ref_speed = welt->get_average_speed( fahr[0]->get_besch()->get_waytype() ); + const sint32 speed_base = (100 * average_speed) / ref_speed - 100; + const sint32 base_bonus = (price * (1000 + speed_base * speed_bonus_rating)); + const sint64 revenue = (sint64)(min_price > base_bonus ? min_price : base_bonus) * (sint64)revenue_distance * (sint64)ware.menge; + sint64 final_revenue = revenue; + + const float happy_ratio = ware.get_origin()->get_unhappy_proportion(1); + if(speed_bonus_rating > 0 && happy_ratio > 0) + { + // Reduce revenue if the origin stop is crowded, if speed is important for the cargo. + sint64 tmp = ((float)speed_bonus_rating / 100.0) * revenue; + tmp *= (happy_ratio * 2); + final_revenue -= tmp; + } + + if(goods->get_catg() == 0) + { + //Passengers care about their comfort + const uint8 tolerable_comfort = calc_tolerable_comfort(journey_minutes); + const uint8 comfort = get_comfort(); + if(comfort > tolerable_comfort) + { + // Apply luxury bonus + const uint8 max_differential = welt->get_einstellungen()->get_max_luxury_bonus_differential(); + const uint8 differential = comfort - tolerable_comfort; + const float multiplier = welt->get_einstellungen()->get_max_luxury_bonus(); + if(differential >= max_differential) + { + final_revenue *= multiplier; + } + else + { + const float proportion = (float)differential / (float)max_differential; + final_revenue += final_revenue * (multiplier * proportion); + } + } + else if(comfort < tolerable_comfort) + { + // Apply discomfort penalty + const uint8 max_differential = welt->get_einstellungen()->get_max_discomfort_penalty_differential(); + const uint8 differential = tolerable_comfort - comfort; + const float multiplier = welt->get_einstellungen()->get_max_discomfort_penalty(); + if(differential >= max_differential) + { + final_revenue *= multiplier; + } + else + { + const float proportion = (float)differential / (float)max_differential; + final_revenue -= final_revenue * (multiplier * proportion); + } + } + + // Do nothing if comfort == tolerable_comfort + } - //Apply the catering bonus, if applicable. - if(get_catering_level(ware.get_besch()->get_catg_index()) > 0) + //Add catering or TPO revenue + const uint8 catering_level = get_catering_level(ware.get_besch()->get_catg_index()); + if(catering_level > 0) { - float catering_bonus = 1; - //TODO: Add code for calculating catering bonus + //TODO: Add code for calculating catering/TPO revenue } - sint64 final_revenue = (revenue + 1500ll) / 3000ll; + final_revenue = (final_revenue + 1500ll) / 3000ll; if(final_revenue > 0) { @@ -2844,6 +2903,108 @@ void convoi_t::calc_revenue(ware_t& ware) } } +const uint8 convoi_t::calc_tolerable_comfort(uint16 journey_minutes) const +{ + const uint16 comfort_short_minutes = welt->get_einstellungen()->get_tolerable_comfort_short_minutes(); + const uint8 comfort_short = welt->get_einstellungen()->get_tolerable_comfort_short(); + if(journey_minutes <= comfort_short_minutes) + { + return comfort_short; + } + + const uint16 comfort_median_short_minutes = welt->get_einstellungen()->get_tolerable_comfort_median_short_minutes(); + const uint8 comfort_median_short = welt->get_einstellungen()->get_tolerable_comfort_median_short(); + if(journey_minutes == comfort_median_short_minutes) + { + return comfort_median_short; + } + if(journey_minutes < comfort_median_short_minutes) + { + const float proportion = (float)(journey_minutes - comfort_short_minutes) / (float)(comfort_median_short_minutes - comfort_short_minutes); + return (proportion * (comfort_median_short_minutes - comfort_short)) + comfort_short; + } + + const uint16 comfort_median_median_minutes = welt->get_einstellungen()->get_tolerable_comfort_median_median_minutes(); + const uint8 comfort_median_median = welt->get_einstellungen()->get_tolerable_comfort_median_median(); + if(journey_minutes == comfort_median_median_minutes) + { + return comfort_median_median; + } + if(journey_minutes < comfort_median_median_minutes) + { + const float proportion = (float)(journey_minutes - comfort_median_short_minutes) / (float)(comfort_median_median_minutes - comfort_median_short_minutes); + return (proportion * (comfort_median_median_minutes - comfort_median_short)) + comfort_median_short; + } + + const uint16 comfort_median_long_minutes = welt->get_einstellungen()->get_tolerable_comfort_median_long_minutes(); + const uint8 comfort_median_long = welt->get_einstellungen()->get_tolerable_comfort_median_long(); + if(journey_minutes == comfort_median_long_minutes) + { + return comfort_median_long; + } + if(journey_minutes < comfort_median_long_minutes) + { + const float proportion = (float)(journey_minutes - comfort_median_median_minutes) / (float)(comfort_median_long_minutes - comfort_median_median_minutes); + return (proportion * (comfort_median_long_minutes - comfort_median_median)) + comfort_median_median; + } + + const uint16 comfort_long_minutes = welt->get_einstellungen()->get_tolerable_comfort_long_minutes(); + const uint8 comfort_long = welt->get_einstellungen()->get_tolerable_comfort_long(); + if(journey_minutes >= comfort_long_minutes) + { + return comfort_long; + } + + const float proportion = (float)(journey_minutes - comfort_median_long_minutes) / (float)(comfort_long_minutes - comfort_median_long_minutes); + return (proportion * (comfort_long - comfort_median_long)) + comfort_median_long; +} + +const uint16 convoi_t::calc_adjusted_speed_bonus(uint16 base_bonus, uint32 distance) const +{ + const uint32 min_distance = welt->get_einstellungen()->get_min_bonus_max_distance(); + if(distance <= min_distance) + { + return 0; + } + + const uint16 max_distance = welt->get_einstellungen()->get_max_bonus_min_distance(); + const float multiplier = welt->get_einstellungen()->get_max_bonus_multiplier(); + + if(distance >= max_distance) + { + return base_bonus * multiplier; + } + + const uint16 median_distance = welt->get_einstellungen()->get_median_bonus_distance(); + if(median_distance == 0) + { + // There is no median, so scale evenly. + const double proportion = (double)(distance - min_distance) / (double)(max_distance - min_distance); + return (base_bonus * multiplier) * proportion; + } + + // There is a median, so scale differently each side of the median. + + if(distance == median_distance) + { + return base_bonus; + } + + if(distance < median_distance) + { + const double proportion = (double)(distance - min_distance) / (double)(median_distance - min_distance); + return base_bonus * proportion; + } + + // If the program gets here, it must be true that: + // distance > median_distance + + const double proportion = (double)(distance - median_distance) / (double)(max_distance - min_distance); + uint16 intermediate_bonus = (base_bonus * multiplier) - base_bonus; + intermediate_bonus *= proportion; + return intermediate_bonus + base_bonus; +} + /** * convoi an haltestelle anhalten * "Convoi stop at stop" (Google translations) diff --git a/simconvoi.h b/simconvoi.h index 61e0b746ddb..45e52d32144 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -157,7 +157,7 @@ class convoi_t : public sync_steppable, public overtaker_t * Current map * @author Hj. Malthaner */ - karte_t *welt; + karte_t *welt; /** * the convoi is being withdrawn from service @@ -343,7 +343,7 @@ class convoi_t : public sync_steppable, public overtaker_t * only used for entering depot or recalculating routes when a schedule window is opened * @author Hj. Malthaner */ - void calc_gewinn(); + //void calc_gewinn(); /** * Recalculates loading level and limit. @@ -405,10 +405,14 @@ class convoi_t : public sync_steppable, public overtaker_t // @author: jamespetts uint32 last_departure_time; - //@author: jamespetts + // @author: jamespetts uint32 rolling_average[MAX_CONVOI_COST]; uint16 rolling_average_count[MAX_CONVOI_COST]; + // @author: jamespetts + const uint16 calc_adjusted_speed_bonus(uint16 base_bonus, uint32 distance) const; + const uint8 calc_tolerable_comfort(uint16 journey_minutes) const; + public: route_t* get_route() { return &route; } diff --git a/simhalt.h b/simhalt.h index 2cdc38cb729..f115a9df054 100644 --- a/simhalt.h +++ b/simhalt.h @@ -612,6 +612,6 @@ class haltestelle_t // @author: jamespetts // Returns the proportion of unhappy people of the total of // happy and unhappy people. - float get_unhappy_proportion(uint8 month) const { return financial_history[month][HALT_UNHAPPY] / (financial_history[month][HALT_HAPPY] + financial_history[month][HALT_UNHAPPY]); } + float get_unhappy_proportion(uint8 month) const { return financial_history[month][HALT_HAPPY] > 0 ? (float)financial_history[month][HALT_UNHAPPY] / (float)(financial_history[month][HALT_HAPPY] + financial_history[month][HALT_UNHAPPY]) : 0; } }; #endif diff --git a/simmain.cc b/simmain.cc index 7842292e8eb..7048ad7aa3c 100644 --- a/simmain.cc +++ b/simmain.cc @@ -419,7 +419,8 @@ int simu_main(int argc, char** argv) // now read last setting (might be overwritten by the tab-files) loadsave_t file; if(file.rd_open("settings.xml")) { - if( file.get_version()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL).version ) { + if( file.get_version() > loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL).version || file.get_experimental_version() > loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL).experimental_version) + { // too new => remove it file.close(); remove( "settings.xml" ); diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 71bf8c43e99..8ff3d591542 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -1599,7 +1599,7 @@ vehikel_t::rauche() * @return income total for last hop * @author Hj. Malthaner */ -sint64 vehikel_t::calc_gewinn(koord start, koord end, convoi_t *cnv) const +/*sint64 vehikel_t::calc_gewinn(koord start, koord end, convoi_t *cnv) const { //According to Google translations: //Calculate profit ("gewinn") @@ -1640,11 +1640,11 @@ sint64 vehikel_t::calc_gewinn(koord start, koord end, convoi_t *cnv) const const sint32 grundwert128 = goods->get_preis()<<7; - /* Calculates the speed bonus, taking into account: ( - * (1) the local bonus; and - * (2) the speed bonus distance settings. - * @author: jamespetts - */ + // Calculates the speed bonus, taking into account: ( + // (1) the local bonus; and + // (2) the speed bonus distance settings. + // @author: jamespetts + const uint16 base_bonus = goods->get_speed_bonus(); uint16 adjusted_bonus = 0; @@ -1694,7 +1694,7 @@ sint64 vehikel_t::calc_gewinn(koord start, koord end, convoi_t *cnv) const // Hajo: Rounded value, in cents // prissi: Why on earth 1/3??? return (value+1500ll)/3000ll; -} +}*/ const char *vehikel_t::get_fracht_mass() const diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index dc8976ea12c..2bd193e0a03 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -448,7 +448,7 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t * @return income total for last hop * @author Hj. Malthaner */ - sint64 calc_gewinn(koord start, koord end, convoi_t* cnv) const; + //sint64 calc_gewinn(koord start, koord end, convoi_t* cnv) const; /** * fahrzeug an haltestelle entladen From f73de726aa89222233808a78475d3d3c4d60a977 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 29 Mar 2009 20:25:39 +0100 Subject: [PATCH 42/61] Ticks is now a 64 bit variable, to accomodate very long games without causing anomalies. The resetting of ticks has been disabled. --- dataobj/einstellungen.h | 2 +- dings/field.cc | 2 +- dings/gebaeude.cc | 11 ++++++++- dings/gebaeude.h | 3 ++- dings/groundobj.cc | 2 +- simconvoi.cc | 54 +++++++++++++++++++++++++++++------------ simconvoi.h | 4 +-- simwin.cc | 28 ++++++++++----------- simworld.cc | 37 ++++++++++++++++++++++------ simworld.h | 14 +++++------ vehicle/movingobj.cc | 2 +- 11 files changed, 107 insertions(+), 52 deletions(-) diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index f8dfc3d8b58..14c0a81e9c8 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -354,7 +354,7 @@ class einstellungen_t short get_starting_month() const {return starting_month;} void set_bits_per_month(short n) {bits_per_month=n;} // prissi, Oct-2005 - short get_bits_per_month() const {return bits_per_month;} + sint16 get_bits_per_month() const {return bits_per_month;} void set_filename(const char *n) {filename=n;} // prissi, Jun-06 const char* get_filename() const { return filename; } diff --git a/dings/field.cc b/dings/field.cc index 3ebad506b50..15410ad7ab3 100644 --- a/dings/field.cc +++ b/dings/field.cc @@ -87,7 +87,7 @@ field_t::get_bild() const } else { // resolution 1/8th month (0..95) - const uint32 yearsteps = (welt->get_current_month()%12)*8 + ((welt->get_zeit_ms()>>(welt->ticks_bits_per_tag-3))&7) + 1; + const sint64 yearsteps = (welt->get_current_month()%12)*8 + ((welt->get_zeit_ms()>>(welt->ticks_bits_per_tag-3))&7) + 1; const image_id bild = s->get_bild_nr( (anzahl*yearsteps-1)/96 ); if((anzahl*yearsteps-1)%96<anzahl) { mark_image_dirty( bild, 0 ); diff --git a/dings/gebaeude.cc b/dings/gebaeude.cc index 48256200e94..8902101b407 100644 --- a/dings/gebaeude.cc +++ b/dings/gebaeude.cc @@ -702,7 +702,16 @@ gebaeude_t::rdwr(loadsave_t *file) file->rdwr_str(buf, 128 ); } file->rdwr_short(idx, "\n"); - file->rdwr_long(insta_zeit, " "); + if(file->get_experimental_version() <= 1) + { + uint32 old_insta_zeit = (uint32) insta_zeit; + file->rdwr_long(old_insta_zeit, " "); + insta_zeit = old_insta_zeit; + } + else + { + file->rdwr_longlong(insta_zeit, " "); + } if(file->is_loading()) { tile = hausbauer_t::find_tile(buf, idx); diff --git a/dings/gebaeude.h b/dings/gebaeude.h index cdd6bf54313..045aad3fd4e 100644 --- a/dings/gebaeude.h +++ b/dings/gebaeude.h @@ -43,9 +43,10 @@ class gebaeude_t : public ding_t, sync_steppable /** * Zeitpunkt an dem das Gebaeude Gebaut wurde + * "Time at that was built the building" (Babelfish) * @author Hj. Malthaner */ - uint32 insta_zeit; + sint64 insta_zeit; /** * Time control for animation progress. diff --git a/dings/groundobj.cc b/dings/groundobj.cc index a79387331c2..98c2a3996ab 100644 --- a/dings/groundobj.cc +++ b/dings/groundobj.cc @@ -131,7 +131,7 @@ void groundobj_t::calc_bild() } else { // resolution 1/8th month (0..95) - const uint32 yearsteps = (welt->get_current_month()%12)*8 + ((welt->get_zeit_ms()>>(welt->ticks_bits_per_tag-3))&7) + 1; + const sint64 yearsteps = (welt->get_current_month()%12)*8 + ((welt->get_zeit_ms()>>(welt->ticks_bits_per_tag-3))&7) + 1; season = (seasons*yearsteps-1)/96; } break; diff --git a/simconvoi.cc b/simconvoi.cc index 09c236b631d..f6313ab9632 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -2305,19 +2305,43 @@ convoi_t::rdwr(loadsave_t *file) } // waiting time left ... - if(file->get_version()>=99017) { - if(file->is_saving()) { - if(go_on_ticks==WAIT_INFINITE) { - file->rdwr_long( go_on_ticks, "dt" ); + if(file->get_version()>=99017) + { + if(file->is_saving()) + { + if(go_on_ticks==WAIT_INFINITE) + { + if(file->get_experimental_version() <= 1) + { + uint32 old_go_on_ticks = (uint32)go_on_ticks; + file->rdwr_long( old_go_on_ticks, "dt" ); + } + else + { + file->rdwr_longlong((sint64)go_on_ticks, "dt" ); + } } - else { - uint32 diff_ticks = welt->get_zeit_ms()>go_on_ticks ? 0 : go_on_ticks-welt->get_zeit_ms(); - file->rdwr_long( diff_ticks, "dt" ); + else + { + sint64 diff_ticks= welt->get_zeit_ms()>go_on_ticks ? 0 : go_on_ticks-welt->get_zeit_ms(); + file->rdwr_longlong((sint64)diff_ticks, "dt" ); } } - else { - file->rdwr_long( go_on_ticks, "dt" ); - if(go_on_ticks!=WAIT_INFINITE) { + else + { + if(file->get_experimental_version() <= 1) + { + uint32 old_go_on_ticks = (uint32)go_on_ticks; + file->rdwr_long( old_go_on_ticks, "dt" ); + go_on_ticks = old_go_on_ticks; + } + else + { + file->rdwr_longlong((sint64)go_on_ticks, "dt" ); + } + + if(go_on_ticks!=WAIT_INFINITE) + { go_on_ticks += welt->get_zeit_ms(); } } @@ -2404,7 +2428,7 @@ convoi_t::rdwr(loadsave_t *file) } if(file->get_experimental_version() >= 2) { - file->rdwr_long(last_departure_time, ""); + file->rdwr_longlong((sint64)last_departure_time, ""); for(uint8 i = 0; i < MAX_CONVOI_COST; i ++) { file->rdwr_long(rolling_average[i], ""); @@ -2856,12 +2880,12 @@ void convoi_t::calc_revenue(ware_t& ware) const float multiplier = welt->get_einstellungen()->get_max_luxury_bonus(); if(differential >= max_differential) { - final_revenue *= multiplier; + final_revenue = revenue * multiplier; } else { const float proportion = (float)differential / (float)max_differential; - final_revenue += final_revenue * (multiplier * proportion); + final_revenue += revenue * (multiplier * proportion); } } else if(comfort < tolerable_comfort) @@ -2872,12 +2896,12 @@ void convoi_t::calc_revenue(ware_t& ware) const float multiplier = welt->get_einstellungen()->get_max_discomfort_penalty(); if(differential >= max_differential) { - final_revenue *= multiplier; + final_revenue = revenue * multiplier; } else { const float proportion = (float)differential / (float)max_differential; - final_revenue -= final_revenue * (multiplier * proportion); + final_revenue -= revenue * (multiplier * proportion); } } diff --git a/simconvoi.h b/simconvoi.h index 45e52d32144..3a5c731bc15 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -275,7 +275,7 @@ class convoi_t : public sync_steppable, public overtaker_t * time, when a convoi waiting for full load will drive on * @author prissi */ - uint32 go_on_ticks; + sint64 go_on_ticks; /** * akkumulierter gewinn über ein jahr hinweg @@ -403,7 +403,7 @@ class convoi_t : public sync_steppable, public overtaker_t // Time in ticks since it departed from the previous stop. // Used for measuring average speed. // @author: jamespetts - uint32 last_departure_time; + sint64 last_departure_time; // @author: jamespetts uint32 rolling_average[MAX_CONVOI_COST]; diff --git a/simwin.cc b/simwin.cc index 403a91a9694..3a19dac6e6b 100644 --- a/simwin.cc +++ b/simwin.cc @@ -1051,7 +1051,7 @@ void win_display_flush(double konto) } koord3d pos; - uint32 ticks=1, month=0, year=0; + sint64 ticks=1, month=0, year=0; const ding_t *dt = wl->get_zeiger(); pos = dt->get_pos(); @@ -1060,12 +1060,12 @@ void win_display_flush(double konto) ticks = wl->get_zeit_ms(); // calculate also days if desired - const uint32 ticks_this_month = ticks % wl->ticks_per_tag; + const sint64 ticks_this_month = ticks % wl->ticks_per_tag; uint32 tage, stunden, minuten; if(umgebung_t::show_month>1) { static sint32 tage_per_month[12]={31,28,31,30,31,30,31,31,30,31,30,31}; - tage = (((sint64)ticks_this_month*tage_per_month[month]) >> wl->ticks_bits_per_tag) + 1; - stunden = (((sint64)ticks_this_month*tage_per_month[month]) >> (wl->ticks_bits_per_tag-16)); + tage = ((ticks_this_month*tage_per_month[month]) >> wl->ticks_bits_per_tag) + 1; + stunden = ((ticks_this_month*tage_per_month[month]) >> (wl->ticks_bits_per_tag-16)); minuten = (((stunden*3) % 8192)*60)/8192; stunden = ((stunden*3) / 8192)%24; } @@ -1085,22 +1085,22 @@ void win_display_flush(double konto) // @author prissi - also show date if desired switch(umgebung_t::show_month) { // german style -#ifdef DEBUG - case 4: sprintf(time, "%s, %d %s %d %d:%02dh TICKS: %d", -#else - case 4: sprintf(time, "%s, %d %s %d %d:%02dh", -#endif +//#ifdef DEBUG +// case 4: sprintf(time, "%s, %d %s %d %d:%02dh TICKS: %li", +//#else + case 4: sprintf(time, "%s, %d %s %d %u:%02uh", +//#endif translator::translate(seasons[wl->get_jahreszeit()]), //Season tage, //Day translator::get_month_name(month%12), //Month year, stunden, //"Hours" (Google) -#ifdef DEBUG - minuten, //Minutes - ticks -#else +//#ifdef DEBUG +// minuten, //Minutes +// ticks +//#else minuten //Minutes -#endif +//#endif ); break; // us style diff --git a/simworld.cc b/simworld.cc index 8f7a09fa2a9..07cae87470a 100644 --- a/simworld.cc +++ b/simworld.cc @@ -2682,17 +2682,19 @@ karte_t::step() next_month_ticks += karte_t::ticks_per_tag; // avoid overflow here ... - if(ticks>next_month_ticks) { + // Should not overflow: now usint 64-bit values. + //@jamespetts + /*if(ticks>next_month_ticks) { ticks %= karte_t::ticks_per_tag; ticks += karte_t::ticks_per_tag; next_month_ticks = ticks+karte_t::ticks_per_tag; last_step_ticks %= karte_t::ticks_per_tag; - } + }*/ neuer_monat(); } - const long delta_t = (long)ticks-(long)last_step_ticks; + const long delta_t = ticks - last_step_ticks; if(!fast_forward) { /* Try to maintain a decent pause, with a step every 170-250 ms (~5,5 simloops/s) * Also avoid too large or negative steps @@ -3270,7 +3272,16 @@ DBG_MESSAGE("karte_t::speichern(loadsave_t *file)", "start"); einstellungen->set_player_type( i, old_sp[i] ); } - file->rdwr_long(ticks, " "); + if(file->get_experimental_version() <= 1) + { + uint32 old_ticks = (uint32)ticks; + file->rdwr_long(old_ticks, " "); + ticks = old_ticks; + } + else + { + file->rdwr_longlong((sint64)ticks, " "); + } file->rdwr_long(letzter_monat, " "); file->rdwr_long(letztes_jahr, "\n"); @@ -3495,7 +3506,7 @@ DBG_DEBUG("karte_t::laden", "einstellungen loaded (groesse %i,%i) timeline=%i be grundwasser = einstellungen->get_grundwasser(); grund_besch_t::calc_water_level( this, height_to_climate ); -DBG_DEBUG("karte_t::laden()","grundwasser %i",grundwasser); + DBG_DEBUG("karte_t::laden()","grundwasser %i",grundwasser); init_felder(); @@ -3505,12 +3516,22 @@ DBG_DEBUG("karte_t::laden()","grundwasser %i",grundwasser); hausbauer_t::neue_karte(); fabrikbauer_t::neue_karte(this); -DBG_DEBUG("karte_t::laden", "init felder ok"); + DBG_DEBUG("karte_t::laden", "init felder ok"); - file->rdwr_long(ticks, " "); + if(file->get_experimental_version() <= 1) + { + uint32 old_ticks = (uint32)ticks; + file->rdwr_long(old_ticks, " "); + ticks = old_ticks; + } + else + { + file->rdwr_longlong((sint64)ticks, ""); + } file->rdwr_long(letzter_monat, " "); file->rdwr_long(letztes_jahr, "\n"); - if(file->get_version()<86006) { + if(file->get_version()<86006) + { letztes_jahr += umgebung_t::default_einstellungen.get_starting_year(); } // old game might have wrong month diff --git a/simworld.h b/simworld.h index 0842ca88b82..7c2009d792e 100644 --- a/simworld.h +++ b/simworld.h @@ -307,9 +307,9 @@ class karte_t * Die Zeit in ms * @author Hj. Malthaner */ - uint32 ticks; // Anzahl ms seit Erzeugung - uint32 last_step_ticks; // ticks counter at last steps - uint32 next_month_ticks; // from now on is next month + sint64 ticks; // Anzahl ms seit Erzeugung + sint64 last_step_ticks; // ticks counter at last steps + sint64 next_month_ticks; // from now on is next month // default time stretching factor uint32 time_multiplier; @@ -541,7 +541,7 @@ class karte_t * * number ticks per day in bits (Babelfish) */ - uint32 ticks_bits_per_tag; + sint64 ticks_bits_per_tag; /** * anzahl ticks pro MONTH! @@ -549,9 +549,9 @@ class karte_t * * number ticks per MONTH! (Babelfish) */ - uint32 ticks_per_tag; + sint64 ticks_per_tag; - void set_ticks_bits_per_tag(uint32 bits) {ticks_bits_per_tag = bits; ticks_per_tag = (1 << ticks_bits_per_tag); } + void set_ticks_bits_per_tag(sint64 bits) {ticks_bits_per_tag = bits; ticks_per_tag = (1 << ticks_bits_per_tag); } sint32 get_time_multiplier() const { return time_multiplier; } void change_time_multiplier( sint32 delta ); @@ -569,7 +569,7 @@ class karte_t * * Time cards since creation / the last load in ms (Google) */ - uint32 get_zeit_ms() const { return ticks; } + sint64 get_zeit_ms() const { return ticks; } /** * absolute month (count start year zero) diff --git a/vehicle/movingobj.cc b/vehicle/movingobj.cc index d27c0aa6e4f..9bf0140ecd2 100644 --- a/vehicle/movingobj.cc +++ b/vehicle/movingobj.cc @@ -130,7 +130,7 @@ void movingobj_t::calc_bild() } else { // resolution 1/8th month (0..95) - const uint32 yearsteps = (welt->get_current_month()%12)*8 + ((welt->get_zeit_ms()>>(welt->ticks_bits_per_tag-3))&7) + 1; + const sint64 yearsteps = (welt->get_current_month()%12)*8 + ((welt->get_zeit_ms()>>(welt->ticks_bits_per_tag-3))&7) + 1; season = (seasons*yearsteps-1)/96; } break; From 35e953b6c581808d7602267a00ad66b78e1cf133 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 29 Mar 2009 21:08:52 +0100 Subject: [PATCH 43/61] Update to work with the latest trunk merge. --- gui/components/gui_convoy_assembler.cc | 4 ++-- gui/components/gui_convoy_label.cc | 4 ++-- player/simplay.h | 3 ++- simfab.cc | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/gui/components/gui_convoy_assembler.cc b/gui/components/gui_convoy_assembler.cc index 65e4e5bbea8..e836c49b1a7 100644 --- a/gui/components/gui_convoy_assembler.cc +++ b/gui/components/gui_convoy_assembler.cc @@ -467,8 +467,8 @@ void gui_convoy_assembler_t::zeichnen(koord parent_pos) min_weight = min(min_weight, ware->get_weight_per_unit()); } } - total_max_weight += max_weight*besch->get_zuladung()/1000; - total_min_weight += min_weight*besch->get_zuladung()/1000; + total_max_weight += (max_weight*besch->get_zuladung()+499)/1000; + total_min_weight += (min_weight*besch->get_zuladung()+499)/1000; min_top_speed=min(min_top_speed, besch->get_geschw()); // In kmh } diff --git a/gui/components/gui_convoy_label.cc b/gui/components/gui_convoy_label.cc index f6f3b7b0afc..82095def25c 100644 --- a/gui/components/gui_convoy_label.cc +++ b/gui/components/gui_convoy_label.cc @@ -111,8 +111,8 @@ void gui_convoy_label_t::zeichnen(koord offset) min_weight = min(min_weight, ware->get_weight_per_unit()); } } - total_max_weight += max_weight*besch->get_zuladung()/1000; - total_min_weight += min_weight*besch->get_zuladung()/1000; + total_max_weight += (max_weight*besch->get_zuladung()+499)/1000; + total_min_weight += (min_weight*besch->get_zuladung()+499)/1000; } max_speed = min(speed_to_kmh(cnv->get_min_top_speed()), (uint32) sqrt((((double)total_power/total_min_weight)-1)*2500)); min_speed = min(speed_to_kmh(cnv->get_min_top_speed()), (uint32) sqrt((((double)total_power/total_max_weight)-1)*2500)); diff --git a/player/simplay.h b/player/simplay.h index 5ef91db719d..e5171b8d89b 100644 --- a/player/simplay.h +++ b/player/simplay.h @@ -18,6 +18,8 @@ #include "../tpl/slist_tpl.h" #include "../tpl/vector_tpl.h" +#include "../simworld.h" + enum player_cost { COST_CONSTRUCTION=0,// Construction @@ -45,7 +47,6 @@ enum player_cost { #define MAX_PLAYER_HISTORY_MONTHS (12) // number of months to keep history -class karte_t; class fabrik_t; class stadt_t; class gebaeude_t; diff --git a/simfab.cc b/simfab.cc index 875bc6835ff..f08acbd7e28 100644 --- a/simfab.cc +++ b/simfab.cc @@ -33,7 +33,7 @@ #include "besch/ware_besch.h" #include "player/simplay.h" - +#include "simmesg.h" #include "simintr.h" #include "dings/wolke.h" From 69fb0b8873f79e5cb97fd3b01f8d3222e8a022cc Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 29 Mar 2009 22:57:57 +0100 Subject: [PATCH 44/61] Added catering and TPO revenue calculation. --- dataobj/einstellungen.cc | 45 +++++++++++++++++ dataobj/einstellungen.h | 30 +++++++++++ simconvoi.cc | 106 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 178 insertions(+), 3 deletions(-) diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index cac59045559..ce482410d47 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -197,6 +197,21 @@ einstellungen_t::einstellungen_t() : max_discomfort_penalty_differential = 200; max_discomfort_penalty_percent = 95; + catering_min_minutes = 60; + catering_level1_minutes = 90; + catering_level1_max_revenue = 150; + catering_level2_minutes = 120; + catering_level2_max_revenue = 250; + catering_level3_minutes = 150; + catering_level3_max_revenue = 350; + catering_level4_minutes = 240; + catering_level4_max_revenue = 400; + catering_level5_minutes = 300; + catering_level5_max_revenue = 475; + + tpo_min_minutes = 120; + tpo_revenue = 300; + // Obsolete vehicles running costs adjustment obsolete_running_cost_increase_percent = 400; //Running costs will be this % of normal costs after vehicle has been obsolete obsolete_running_cost_increase_phase_years = 20; //for this number of years. @@ -556,6 +571,21 @@ void einstellungen_t::rdwr(loadsave_t *file) file->rdwr_byte(max_discomfort_penalty_differential, ""); file->rdwr_short(max_discomfort_penalty_percent, ""); file->rdwr_short(max_luxury_bonus_percent, ""); + + file->rdwr_short(catering_min_minutes, ""); + file->rdwr_short(catering_level1_minutes, ""); + file->rdwr_short(catering_level1_max_revenue, ""); + file->rdwr_short(catering_level2_minutes, ""); + file->rdwr_short(catering_level2_max_revenue, ""); + file->rdwr_short(catering_level3_minutes, ""); + file->rdwr_short(catering_level3_max_revenue, ""); + file->rdwr_short(catering_level4_minutes, ""); + file->rdwr_short(catering_level4_max_revenue, ""); + file->rdwr_short(catering_level5_minutes, ""); + file->rdwr_short(catering_level5_max_revenue, ""); + + file->rdwr_short(tpo_min_minutes, ""); + file->rdwr_short(tpo_revenue, ""); } file->rdwr_short(obsolete_running_cost_increase_percent, ""); @@ -825,6 +855,21 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s max_luxury_bonus_percent = contents.get_int("max_luxury_bonus_percent", max_luxury_bonus_percent); max_discomfort_penalty_percent = contents.get_int("max_discomfort_penalty_percent", max_discomfort_penalty_percent); + catering_min_minutes = contents.get_int("catering_min_minutes", catering_min_minutes); + catering_level1_minutes = contents.get_int("catering_level1_minutes", catering_level1_minutes); + catering_level1_max_revenue = contents.get_int("catering_level1_max_revenue", catering_level1_max_revenue); + catering_level2_minutes = contents.get_int("catering_level2_minutes", catering_level2_minutes); + catering_level2_max_revenue = contents.get_int("catering_level2_max_revenue", catering_level2_max_revenue); + catering_level3_minutes = contents.get_int("catering_level3_minutes", catering_level3_minutes); + catering_level3_max_revenue = contents.get_int("catering_level3_max_revenue", catering_level3_max_revenue); + catering_level4_minutes = contents.get_int("catering_level4_minutes", catering_level4_minutes); + catering_level4_max_revenue = contents.get_int("catering_level4_max_revenue", catering_level4_max_revenue); + catering_level5_minutes = contents.get_int("catering_level5_minutes", catering_level5_minutes); + catering_level5_max_revenue = contents.get_int("catering_level5_max_revenue", catering_level5_max_revenue); + + tpo_min_minutes = contents.get_int("tpo_min_minutes", tpo_min_minutes); + tpo_revenue = contents.get_int("tpo_revenue", tpo_revenue); + // Obsolete vehicles' running cost increase obsolete_running_cost_increase_percent = contents.get_int("obsolete_running_cost_increase_percent", obsolete_running_cost_increase_percent); obsolete_running_cost_increase_phase_years = contents.get_int("obsolete_running_cost_increase_phase_years", obsolete_running_cost_increase_phase_years); diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index 106c59ddb26..f34f59553a9 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -190,6 +190,21 @@ class einstellungen_t uint16 max_luxury_bonus_percent; uint16 max_discomfort_penalty_percent; + uint16 catering_min_minutes; + uint16 catering_level1_minutes; + uint16 catering_level1_max_revenue; + uint16 catering_level2_minutes; + uint16 catering_level2_max_revenue; + uint16 catering_level3_minutes; + uint16 catering_level3_max_revenue; + uint16 catering_level4_minutes; + uint16 catering_level4_max_revenue; + uint16 catering_level5_minutes; + uint16 catering_level5_max_revenue; + + uint16 tpo_min_minutes; + uint16 tpo_revenue; + //@author: jamespetts // Obsolete vehicle maintenance cost increases uint16 obsolete_running_cost_increase_percent; @@ -443,6 +458,21 @@ class einstellungen_t float get_max_luxury_bonus() const { return (float)max_luxury_bonus_percent * 0.01; } float get_max_discomfort_penalty() const { return (float) max_discomfort_penalty_percent * 0.01; } + uint16 get_catering_min_minutes() const { return catering_min_minutes; } + uint16 get_catering_level1_minutes() const { return catering_level1_minutes; } + uint16 get_catering_level1_max_revenue() const { return catering_level1_max_revenue; } + uint16 get_catering_level2_minutes() const { return catering_level2_minutes; } + uint16 get_catering_level2_max_revenue() const { return catering_level2_max_revenue; } + uint16 get_catering_level3_minutes() const { return catering_level3_minutes; } + uint16 get_catering_level3_max_revenue() const { return catering_level3_max_revenue; } + uint16 get_catering_level4_minutes() const { return catering_level4_minutes; } + uint16 get_catering_level4_max_revenue() const { return catering_level4_max_revenue; } + uint16 get_catering_level5_minutes() const { return catering_level5_minutes; } + uint16 get_catering_level5_max_revenue() const { return catering_level5_max_revenue; } + + uint16 get_tpo_min_minutes() const { return tpo_min_minutes; } + uint16 get_tpo_revenue() const { return tpo_revenue; } + uint16 get_obsolete_running_cost_increase_percent() const { return obsolete_running_cost_increase_percent; } uint16 get_obsolete_running_cost_increase_phase_years() const { return obsolete_running_cost_increase_phase_years; } diff --git a/simconvoi.cc b/simconvoi.cc index 462940c8e68..67f6d717dbf 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -2890,7 +2890,7 @@ void convoi_t::calc_revenue(ware_t& ware) const float multiplier = welt->get_einstellungen()->get_max_luxury_bonus(); if(differential >= max_differential) { - final_revenue = revenue * multiplier; + final_revenue += (revenue * multiplier); } else { @@ -2906,7 +2906,7 @@ void convoi_t::calc_revenue(ware_t& ware) const float multiplier = welt->get_einstellungen()->get_max_discomfort_penalty(); if(differential >= max_differential) { - final_revenue = revenue * multiplier; + final_revenue -= (revenue * multiplier); } else { @@ -2922,7 +2922,107 @@ void convoi_t::calc_revenue(ware_t& ware) const uint8 catering_level = get_catering_level(ware.get_besch()->get_catg_index()); if(catering_level > 0) { - //TODO: Add code for calculating catering/TPO revenue + if(ware.get_index() == 1) + { + // Mail + if(journey_minutes >= welt->get_einstellungen()->get_tpo_min_minutes()) + { + final_revenue += (welt->get_einstellungen()->get_tpo_revenue() * ware.menge); + } + } + else if(ware.get_index() == 0) + { + // Passengers + float proportion = 0.0; + switch(catering_level) + { + + case 1: + case_1: + if(journey_minutes < welt->get_einstellungen()->get_catering_min_minutes()) + { + break; + } + if(journey_minutes > welt->get_einstellungen()->get_catering_level1_minutes()) + { + final_revenue += (welt->get_einstellungen()->get_catering_level1_max_revenue() * ware.menge); + break; + } + + proportion = (journey_minutes - welt->get_einstellungen()->get_catering_min_minutes()) / (welt->get_einstellungen()->get_catering_level1_minutes() - welt->get_einstellungen()->get_catering_min_minutes()); + final_revenue += (proportion * (welt->get_einstellungen()->get_catering_level1_max_revenue() * ware.menge)); + break; + + case 2: + case_2: + if(journey_minutes < welt->get_einstellungen()->get_catering_level1_minutes()) + { + // If only C++ had C#'s goto case syntax... + goto case_1; + } + if(journey_minutes > welt->get_einstellungen()->get_catering_level2_minutes()) + { + final_revenue += (welt->get_einstellungen()->get_catering_level2_max_revenue() * ware.menge); + break; + } + + proportion = (journey_minutes - welt->get_einstellungen()->get_catering_level1_max_revenue()) / (welt->get_einstellungen()->get_catering_level2_minutes() - welt->get_einstellungen()->get_catering_level1_minutes()); + final_revenue += (proportion * (welt->get_einstellungen()->get_catering_level2_max_revenue() * ware.menge)); + break; + + case 3: + case_3: + if(journey_minutes < welt->get_einstellungen()->get_catering_level2_minutes()) + { + goto case_2; + } + + if(journey_minutes > welt->get_einstellungen()->get_catering_level3_minutes()) + { + final_revenue += (welt->get_einstellungen()->get_catering_level3_max_revenue() * ware.menge); + break; + } + + proportion = (journey_minutes - welt->get_einstellungen()->get_catering_level2_max_revenue()) / (welt->get_einstellungen()->get_catering_level3_minutes() - welt->get_einstellungen()->get_catering_level2_minutes()); + final_revenue += (proportion * (welt->get_einstellungen()->get_catering_level3_max_revenue() * ware.menge)); + break; + + case 4: + case_4: + if(journey_minutes < welt->get_einstellungen()->get_catering_level3_minutes()) + { + goto case_3; + } + + if(journey_minutes > welt->get_einstellungen()->get_catering_level4_minutes()) + { + final_revenue += (welt->get_einstellungen()->get_catering_level4_max_revenue() * ware.menge); + break; + } + + proportion = (journey_minutes - welt->get_einstellungen()->get_catering_level3_max_revenue()) / (welt->get_einstellungen()->get_catering_level4_minutes() - welt->get_einstellungen()->get_catering_level3_minutes()); + final_revenue += (proportion * (welt->get_einstellungen()->get_catering_level4_max_revenue() * ware.menge)); + break; + + case 5: + case_5: + default: + if(journey_minutes < welt->get_einstellungen()->get_catering_level4_minutes()) + { + goto case_4; + } + + if(journey_minutes > welt->get_einstellungen()->get_catering_level5_minutes()) + { + final_revenue += (welt->get_einstellungen()->get_catering_level5_max_revenue() * ware.menge); + break; + } + + proportion = (journey_minutes - welt->get_einstellungen()->get_catering_level4_max_revenue()) / (welt->get_einstellungen()->get_catering_level5_minutes() - welt->get_einstellungen()->get_catering_level4_minutes()); + final_revenue += (proportion * (welt->get_einstellungen()->get_catering_level5_max_revenue() * ware.menge)); + break; + }; + } } final_revenue = (final_revenue + 1500ll) / 3000ll; From 70dac481afe7993c8b55b1a11e6dab9050e9ad79 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 30 Mar 2009 20:14:47 +0100 Subject: [PATCH 45/61] Correct a compile problem in makeobj and use average speeds for lines and convoys --- besch/writer/root_writer.cc | 2 ++ simconvoi.cc | 53 ++++++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/besch/writer/root_writer.cc b/besch/writer/root_writer.cc index 656fc0c89fc..f628200a68f 100644 --- a/besch/writer/root_writer.cc +++ b/besch/writer/root_writer.cc @@ -1,3 +1,5 @@ +#include <stdlib.h> + #include "../../utils/cstring_t.h" #include "../../dataobj/tabfile.h" #include "../../utils/searchfolder.h" diff --git a/simconvoi.cc b/simconvoi.cc index 67f6d717dbf..1880c85a98e 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -2837,13 +2837,30 @@ void convoi_t::laden() //"load" (Babelfish) void convoi_t::calc_revenue(ware_t& ware) { float average_speed; - if(financial_history[1][CONVOI_AVERAGE_SPEED] < 1) + + if(!line.is_bound()) { - average_speed = financial_history[0][CONVOI_AVERAGE_SPEED]; + // No line - must use convoy + if(financial_history[1][CONVOI_AVERAGE_SPEED] < 1) + { + average_speed = financial_history[0][CONVOI_AVERAGE_SPEED]; + } + else + { + average_speed = financial_history[1][CONVOI_AVERAGE_SPEED]; + } } + else - { - average_speed = financial_history[1][CONVOI_AVERAGE_SPEED]; + { + if(line->get_finance_history(1, LINE_AVERAGE_SPEED) < 1) + { + average_speed = line->get_finance_history(0, LINE_AVERAGE_SPEED); + } + else + { + average_speed = line->get_finance_history(1, LINE_AVERAGE_SPEED); + } } // Cannot not charge for journey if the journey distance is more than a certain proportion of the straight line distance. @@ -2881,7 +2898,32 @@ void convoi_t::calc_revenue(ware_t& ware) { //Passengers care about their comfort const uint8 tolerable_comfort = calc_tolerable_comfort(journey_minutes); - const uint8 comfort = get_comfort(); + uint8 comfort = 100; + if(line.is_bound()) + { + if(line->get_finance_history(1, LINE_COMFORT) < 1) + { + comfort = line->get_finance_history(0, LINE_COMFORT); + } + else + { + comfort = line->get_finance_history(1, LINE_COMFORT); + } + } + else + { + // No line - must use convoy + if(financial_history[1][CONVOI_COMFORT] < 1) + { + comfort = financial_history[0][CONVOI_COMFORT]; + } + else + { + comfort = financial_history[1][CONVOI_COMFORT]; + } + } + + if(comfort > tolerable_comfort) { // Apply luxury bonus @@ -3005,7 +3047,6 @@ void convoi_t::calc_revenue(ware_t& ware) break; case 5: - case_5: default: if(journey_minutes < welt->get_einstellungen()->get_catering_level4_minutes()) { From f4a2b34979abaa32c59ca3372d2906ba72a9d341 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Wed, 1 Apr 2009 20:40:02 +0100 Subject: [PATCH 46/61] Insignificant comment and code layout changes. --- gui/stadt_info.cc | 1 - simcity.cc | 6 ++-- simconvoi.cc | 1 - simhalt.cc | 73 +++++++++++++++++++++++++++++++---------------- 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/gui/stadt_info.cc b/gui/stadt_info.cc index f83981d7006..d6aeaf945a9 100644 --- a/gui/stadt_info.cc +++ b/gui/stadt_info.cc @@ -188,7 +188,6 @@ void stadt_info_t::zeichnen(koord pos, koord gr) } pax_destinations_last_change = current_pax_destinations; - //TODO: Check whether this needs changing given that max_train_length has now increased. display_array_wh(pos.x + 140, pos.y + 24, PAX_DESTINATIONS_SIZE, PAX_DESTINATIONS_SIZE, pax_dest_old); display_array_wh(pos.x + 140 + PAX_DESTINATIONS_SIZE + 4, pos.y + 24, PAX_DESTINATIONS_SIZE, PAX_DESTINATIONS_SIZE, pax_dest_new); } diff --git a/simcity.cc b/simcity.cc index ee0f492aafa..6bd4d1abf79 100644 --- a/simcity.cc +++ b/simcity.cc @@ -1833,13 +1833,13 @@ void stadt_t::step_passagiere() halthandle_t best_destination[3]; uint8 best_journey_steps = 255; - for(int i = start_halts.get_count() - 1; i >= 0; i--) + ITERATE(start_halts,i) { if(start_halts.get_count() < 1) { break; } - halthandle_t current_halt = *start_halts.get_element(i); + halthandle_t current_halt = *start_halts[i]; route_result = current_halt->suche_route( pax, will_return ? &return_zwischenziel : NULL, welt->get_einstellungen()->is_no_routing_over_overcrowding() ); if(!pax.get_ziel().is_bound()) { @@ -1851,7 +1851,7 @@ void stadt_t::step_passagiere() halthandle_t tmp[3]; tmp[0] = pax.get_ziel(); tmp[1] = pax.get_zwischenziel(); - tmp[2] = *start_halts.get_element(i); + tmp[2] = current_halt; // Will fail if there is another journey with the same number of steps, // but this does not matter, since they both count as the same. uint8 tmp2 = pax.get_journey_steps(); diff --git a/simconvoi.cc b/simconvoi.cc index 1880c85a98e..b87f4b33643 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -2923,7 +2923,6 @@ void convoi_t::calc_revenue(ware_t& ware) } } - if(comfort > tolerable_comfort) { // Apply luxury bonus diff --git a/simhalt.cc b/simhalt.cc index 10fba242a3b..f57a7ea8a0e 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -1005,32 +1005,39 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov const halthandle_t *halt_list = plan->get_haltlist(); // but we can only use a subset of these vector_tpl<halthandle_t> ziel_list(plan->get_haltlist_count()); - for( unsigned h=0; h<plan->get_haltlist_count(); h++ ) { + for( unsigned h=0; h<plan->get_haltlist_count(); h++ ) + { halthandle_t halt = halt_list[h]; - if( halt->is_enabled(warentyp) ) { + if( halt->is_enabled(warentyp) ) + { ziel_list.append(halt); } - else { + else + { //DBG_MESSAGE("suche_route()","halt %s near (%i,%i) does not accept %s!",halt->get_name(),ziel.x,ziel.y,warentyp->get_name()); } } - if( ziel_list.empty() ) { + if( ziel_list.empty() ) + { //no target station found ware.set_ziel( halthandle_t() ); ware.set_zwischenziel( halthandle_t() ); // printf("keine route zu %d,%d nach %d steps\n", ziel.x, ziel.y, step); - if( next_to_ziel != NULL ) { + if( next_to_ziel != NULL ) + { *next_to_ziel = koord::invalid; } return NO_ROUTE; } // check, if the shortest connection is not right to us ... - if( ziel_list.is_contained(self) ) { + if( ziel_list.is_contained(self) ) + { ware.set_ziel( self ); ware.set_zwischenziel( halthandle_t() ); - if( next_to_ziel != NULL ) { + if( next_to_ziel != NULL ) + { *next_to_ziel = koord::invalid; } } @@ -1042,9 +1049,11 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov /* Need to clean up? * Otherwise we just incease the mark => less time for cleanups */ - if( current_mark == 0xFFFFFFFFu ) { + if( current_mark == 0xFFFFFFFFu ) + { slist_iterator_tpl<halthandle_t > halt_iter (alle_haltestellen); - while( halt_iter.next() ) { + while( halt_iter.next() ) + { halt_iter.get_current()->marke = 0; } current_mark = 0; @@ -1053,6 +1062,7 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov // die Berechnung erfolgt durch eine Breitensuche fuer Graphen // Warteschlange fuer Breitensuche + // "The calculation is performed by a wide search for graphs queued for Beam Search" (Google) const uint16 max_transfers = welt->get_einstellungen()->get_max_transfers(); #ifdef USE_ROUTE_SLIST_TPL slist_tpl<HNode *> queue; @@ -1064,11 +1074,11 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov HNode *tmp; nodes[0].halt = self; - nodes[0].link = 0; - nodes[0].depth = 0; + nodes[0].link = NULL; + nodes[0].depth = NULL; #ifdef USE_ROUTE_SLIST_TPL - queue.insert( &nodes[0] ); // init queue mit erstem feld + queue.insert( &nodes[0] ); // init queue mit erstem feld "with the first field" (Google) #endif self->marke = current_mark; @@ -1084,21 +1094,24 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov const halthandle_t halt = tmp->halt; // we end this loop always with this jump (if sucessful) - if(ziel_list.is_contained(halt)) { + if(ziel_list.is_contained(halt)) + { goto found; } // Hajo: check for max transfers -> don't add more stations // to queue if the limit is reached - if(tmp->depth < max_transfers && step<64000u ) { + if(tmp->depth < max_transfers && step<64000u ) + { const vector_tpl<halthandle_t> *wz = halt->get_warenziele(ware_catg_index); - for( uint32 i=0; i<wz->get_count(); i++ ) { + for( uint32 i=0; i<wz->get_count(); i++ ) + { // since these are precalculated, they should be always pointing to a valid ground // (if not, we were just under construction, and will be fine after 16 steps) const halthandle_t &tmp_halt = (*wz)[i]; - if(tmp_halt.is_bound() && tmp_halt->marke!=current_mark) { - + if(tmp_halt.is_bound() && tmp_halt->marke!=current_mark) + { HNode *node = &nodes[step++]; node->halt = tmp_halt; node->depth = tmp->depth + 1; @@ -1124,27 +1137,36 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov found: - if(tmp) { + if(tmp) + { // ziel gefunden + // "target found" (Google) ware.set_ziel( tmp->halt ); - if(tmp->link == NULL) { + if(tmp->link == NULL) + { // kein zwischenziel + // "no between target" (Google) ware.set_zwischenziel(ware.get_ziel()); - if(next_to_ziel!=NULL) { + if(next_to_ziel!=NULL) + { // for reverse route the next hop, but not hop => enter start *next_to_ziel = self->get_basis_pos(); } } - else { - if(next_to_ziel!=NULL) { + else + { + if(next_to_ziel!=NULL) + { // for reverse route the next hop *next_to_ziel = tmp->link->halt->get_basis_pos(); } // find the intermediate stops - while(tmp->link->link) { + while(tmp->link->link) + { tmp = tmp->link; - if( avoid_overcrowding && tmp->halt->is_overcrowded(ware_catg_index) ) { + if( avoid_overcrowding && tmp->halt->is_overcrowded(ware_catg_index) ) + { return ROUTE_OVERCROWDED; } } @@ -1152,7 +1174,8 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov } return ROUTE_OK; } - else { + else + { // no suitable target station found ware.set_ziel( halthandle_t() ); ware.set_zwischenziel( halthandle_t() ); From bc67b58a39d89294d732418fb16390a2279faa69 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Thu, 2 Apr 2009 20:53:32 +0100 Subject: [PATCH 47/61] Added means for recording the waiting time of goods at stations. --- simcity.cc | 5 ++- simfab.cc | 2 ++ simhalt.cc | 74 +++++++++++++++++++++++++++++-------------- simware.cc | 5 +++ simware.h | 5 +++ vehicle/simvehikel.cc | 1 - 6 files changed, 67 insertions(+), 25 deletions(-) diff --git a/simcity.cc b/simcity.cc index 6bd4d1abf79..4c288505e2c 100644 --- a/simcity.cc +++ b/simcity.cc @@ -1810,7 +1810,8 @@ void stadt_t::step_passagiere() } // check, if they can walk there? - if (can_walk_ziel) { + if (can_walk_ziel) + { // so we have happy passengers start_halt->add_pax_happy(pax_left_to_do); merke_passagier_ziel(destinations[0].location, COL_YELLOW); @@ -1872,6 +1873,7 @@ void stadt_t::step_passagiere() pax.set_ziel(best_destination[0]); pax.set_zwischenziel(best_destination[1]); pax.set_journey_steps(best_journey_steps); + pax.arrival_time = welt->get_zeit_ms(); start_halt = best_destination[2]; pax.set_origin(start_halt); @@ -2086,6 +2088,7 @@ void stadt_t::step_passagiere() return_pax.set_ziel(start_halt); return_pax.set_zwischenziel(welt->lookup(return_zwischenziel)->get_halt()); return_pax.set_journey_steps(best_journey_steps); + return_pax.arrival_time = welt->get_zeit_ms(); ret_halt->starte_mit_route(return_pax); ret_halt->add_pax_happy(pax_left_to_do); diff --git a/simfab.cc b/simfab.cc index f08acbd7e28..0b18c1a10a1 100644 --- a/simfab.cc +++ b/simfab.cc @@ -1076,6 +1076,7 @@ void fabrik_t::verteile_waren(const uint32 produkt) ware_t ware(ausgang[produkt].get_typ(), halt); ware.menge = menge; ware.set_zielpos( lieferziel ); + ware.arrival_time = welt->get_zeit_ms(); unsigned w; // find the index in the target factory @@ -1154,6 +1155,7 @@ void fabrik_t::verteile_waren(const uint32 produkt) if(amount > most_waiting.menge) { most_waiting.set_zielpos( lieferziele[n] ); most_waiting.menge = amount; + most_waiting.arrival_time = welt->get_zeit_ms(); } } diff --git a/simhalt.cc b/simhalt.cc index f57a7ea8a0e..6853d415c7a 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -1084,7 +1084,8 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov const uint32 max_hops = welt->get_einstellungen()->get_max_hops(); // here the normal routing with overcrowded stops is done - do { + do + { #ifdef USE_ROUTE_SLIST_TPL tmp = queue.remove_first(); #else @@ -1106,7 +1107,6 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov const vector_tpl<halthandle_t> *wz = halt->get_warenziele(ware_catg_index); for( uint32 i=0; i<wz->get_count(); i++ ) { - // since these are precalculated, they should be always pointing to a valid ground // (if not, we were just under construction, and will be fine after 16 steps) const halthandle_t &tmp_halt = (*wz)[i]; @@ -1456,16 +1456,23 @@ bool haltestelle_t::vereinige_waren(const ware_t &ware) //"unite were" (Google) */ // NEW SYSTEM - // Checks adds a great deal more checks. + // Adds more checks. // @author: jamespetts if(ware.can_merge_with(tmp)) { - //Note: the below if statement is part of the new system of avoiding overcrowded routes. - if( ware.get_zwischenziel().is_bound() && ware.get_zwischenziel()!=self ) { + if( ware.get_zwischenziel().is_bound() && ware.get_zwischenziel()!=self ) + { // update route if there is newer route tmp.set_zwischenziel( ware.get_zwischenziel() ); } + // Merge waiting times. + if(tmp.menge > 0 && ware.menge > 0) + { + //The waiting time for ware will always be zero. + tmp.arrival_time = welt->get_zeit_ms() - ((welt->get_zeit_ms() - tmp.arrival_time) * tmp.menge) / (tmp.menge + ware.menge); + } + tmp.menge += ware.menge; resort_freight_info = true; return true; @@ -1481,17 +1488,23 @@ bool haltestelle_t::vereinige_waren(const ware_t &ware) //"unite were" (Google) // take care of all allocation neccessary void haltestelle_t::add_ware_to_halt(ware_t ware) { + //@author: jamespetts + ware.arrival_time = welt->get_zeit_ms(); + // now we have to add the ware to the stop vector_tpl<ware_t> * warray = waren[ware.get_besch()->get_catg_index()]; - if(warray==NULL) { + if(warray==NULL) + { // this type was not stored here before ... warray = new vector_tpl<ware_t>(4); waren[ware.get_besch()->get_catg_index()] = warray; } // the ware will be put into the first entry with menge==0 resort_freight_info = true; - for(unsigned i=0; i<warray->get_count(); i++ ) { - if((*warray)[i].menge==0) { + ITERATE_PTR(warray,i) + { + if((*warray)[i].menge==0) + { (*warray)[i] = ware; return; } @@ -1549,23 +1562,29 @@ uint32 haltestelle_t::starte_mit_route(ware_t ware) uint32 haltestelle_t::liefere_an(ware_t ware) { // no valid next stops? - if(!ware.get_ziel().is_bound() || !ware.get_zwischenziel().is_bound()) { + if(!ware.get_ziel().is_bound() || !ware.get_zwischenziel().is_bound()) + { // write a log entry and discard the goods dbg->warning("haltestelle_t::liefere_an()","%d %s delivered to %s have no longer a route to their destination!", ware.menge, translator::translate(ware.get_name()), get_name() ); return ware.menge; } // did we arrived? - if(welt->lookup(ware.get_zielpos())->is_connected(self)) { - if(ware.is_freight()) { + if(welt->lookup(ware.get_zielpos())->is_connected(self)) + { + if(ware.is_freight()) + { // muss an fabrik geliefert werden liefere_an_fabrik(ware); } - else if(ware.get_besch()==warenbauer_t::passagiere) { + else if(ware.get_besch()==warenbauer_t::passagiere) + { // arriving passenger may create pedestrians - if(welt->get_einstellungen()->get_show_pax()) { + if(welt->get_einstellungen()->get_show_pax()) + { int menge = ware.menge; - for (slist_tpl<tile_t>::const_iterator i = tiles.begin(), end = tiles.end(); menge > 0 && i != end; ++i) { + for (slist_tpl<tile_t>::const_iterator i = tiles.begin(), end = tiles.end(); menge > 0 && i != end; ++i) + { grund_t* gr = i->grund; menge = erzeuge_fussgaenger(welt, gr->get_pos(), menge); } @@ -1576,12 +1595,14 @@ dbg->warning("haltestelle_t::liefere_an()","%d %s delivered to %s have no longer } // do we have already something going in this direction here? - if( vereinige_waren(ware) ) { + if( vereinige_waren(ware) ) + { return ware.menge; } // not near enough => we need to do a rerouting - if( suche_route( ware, NULL, false )==NO_ROUTE ) { + if( suche_route( ware, NULL, false )==NO_ROUTE ) + { // target no longer there => delete INT_CHECK("simhalt 1364"); @@ -1591,7 +1612,8 @@ dbg->warning("haltestelle_t::liefere_an()","%d %s delivered to %s have no longer } #if 1 // passt das zu bereits wartender ware ? - if(vereinige_waren(ware)) { + if(vereinige_waren(ware)) + { // dann sind wir schon fertig; return ware.menge; } @@ -2084,19 +2106,25 @@ void haltestelle_t::laden_abschliessen() } // fix good destination coordinates - for(unsigned i=0; i<warenbauer_t::get_max_catg_index(); i++) { + for(unsigned i=0; i<warenbauer_t::get_max_catg_index(); i++) + { if(waren[i]) { vector_tpl<ware_t> * warray = waren[i]; - for(unsigned j=0; j<warray->get_count(); j++) { + for(unsigned j=0; j<warray->get_count(); j++) + { (*warray)[j].laden_abschliessen(welt); } // merge identical entries (should only happen with old games) - for(unsigned j=0; j<warray->get_count(); j++) { - if( (*warray)[j].menge==0 ) { + for(unsigned j=0; j<warray->get_count(); j++) + { + if( (*warray)[j].menge==0 ) + { continue; } - for(unsigned k=j+1; k<warray->get_count(); k++) { - if( (*warray)[k].menge>0 && (*warray)[j].same_destination( (*warray)[k] ) ) { + for(unsigned k=j+1; k<warray->get_count(); k++) + { + if( (*warray)[k].menge > 0 && (*warray)[j].can_merge_with( (*warray)[k] ) ) + { (*warray)[j].menge += (*warray)[k].menge; (*warray)[k].menge = 0; } diff --git a/simware.cc b/simware.cc index 011262a2bb9..88dfd2bbadd 100644 --- a/simware.cc +++ b/simware.cc @@ -33,6 +33,7 @@ ware_t::ware_t() : ziel(), zwischenziel(), zielpos(-1, -1) index = 0; accumulated_distance = 0; journey_steps = 0; + arrival_time = 0; } @@ -43,6 +44,7 @@ ware_t::ware_t(const ware_besch_t *wtyp) : ziel(), zwischenziel(), zielpos(-1, - index = wtyp->get_index(); accumulated_distance = 0; journey_steps = 0; + arrival_time = 0; } // Constructor for new revenue system: packet of cargo keeps track of its origin. @@ -54,6 +56,7 @@ ware_t::ware_t(const ware_besch_t *wtyp, halthandle_t o) : ziel(), zwischenziel( origin = o; accumulated_distance = 0; journey_steps = 0; + arrival_time = 0; } @@ -165,11 +168,13 @@ ware_t::rdwr(karte_t *welt,loadsave_t *file) { file->rdwr_long(accumulated_distance, ""); file->rdwr_byte(journey_steps, ""); + file->rdwr_longlong(arrival_time, ""); } else { accumulated_distance = 0; journey_steps = 0; + arrival_time = 0; } } diff --git a/simware.h b/simware.h index 1494d6f1b4b..fda52d41b26 100644 --- a/simware.h +++ b/simware.h @@ -50,6 +50,7 @@ class ware_t //@author: jamespetts //The number of remaining steps on this packet's journey. + //TODO: Remove this variable when the new system is implemented. uint8 journey_steps; // @author: jamespetts @@ -135,6 +136,10 @@ class ware_t inline bool same_destination(const ware_t &w) const { return index==w.get_index() && ziel==w.get_ziel() && (index<2 || zielpos==w.get_zielpos()); } + + // The time at which this packet arrived at the current station + // @author: jamespetts + sint64 arrival_time; }; #endif diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index f1112afa1db..65690720cbe 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -1683,7 +1683,6 @@ vehikel_t::rauche() if(cnv->get_catering_level(ware.get_besch()->get_catg_index()) > 0) { float catering_bonus = 1; - //TODO: Add code for calculating catering bonus value *= catering_bonus; } From eab59ecabb323c297b074e12eee706c56d773f99 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 6 Apr 2009 01:30:14 +0100 Subject: [PATCH 48/61] *Very* early implementation of new pathfinding algorithm and logic. Uploaded as a backup. *UNTESTED*. Will probably not compile. --- Simutrans-Experimental.vcproj | 4 + dataobj/einstellungen.cc | 28 +- dataobj/einstellungen.h | 24 +- gui/colors.cc | 4 +- gui/components/gui_convoy_assembler.cc | 2 +- player/ai.cc | 11 +- simcity.cc | 134 +++++- simconvoi.cc | 124 ++++- simfab.cc | 8 +- simhalt.cc | 599 +++++++++++++++++++++++-- simhalt.h | 195 +++++++- simware.h | 25 +- simworld.cc | 9 + simworld.h | 6 + tpl/inthashtable_tpl.h | 2 +- tpl/ptrhashtable_tpl.h | 2 +- tpl/vector_tpl.h | 5 + vehicle/simvehikel.cc | 1 + 18 files changed, 1073 insertions(+), 110 deletions(-) diff --git a/Simutrans-Experimental.vcproj b/Simutrans-Experimental.vcproj index 9576d9f78bf..aa1abc80e88 100644 --- a/Simutrans-Experimental.vcproj +++ b/Simutrans-Experimental.vcproj @@ -1876,6 +1876,10 @@ RelativePath=".\tpl\ptrhashtable_tpl.h" > </File> + <File + RelativePath=".\tpl\quickstone_hashtable_tpl.h" + > + </File> <File RelativePath=".\tpl\quickstone_tpl.h" > diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index 83415d95fc6..243cbcfa621 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -101,6 +101,14 @@ einstellungen_t::einstellungen_t() : max_hops = 300; no_routing_over_overcrowding = false; + //Two and a half hours (9 * 18 = 162; 162 approx 2:30h) + passenger_max_wait = 2700; + + // 4 is faster; 2 is more accurate. + // Not recommended to use anything other than 2 or 4 + // @author: jamespetts + max_rerouting_interval_months = 4; + /* multiplier for steps on diagonal: * 1024: TT-like, faktor 2, vehicle will be too long and too fast * 724: correct one, faktor sqrt(2) @@ -257,10 +265,6 @@ einstellungen_t::einstellungen_t() : // @author: jamespetts global_power_factor = 1.0; - // this will pay for distance to next change station - - pay_for_total_distance = 0; - avoid_overcrowding = false; } @@ -526,7 +530,13 @@ void einstellungen_t::rdwr(loadsave_t *file) if(file->get_version()>101000) { file->rdwr_bool( seperate_halt_capacities, "" ); - file->rdwr_byte( pay_for_total_distance, "" ); + if(file->get_experimental_version() < 2) + { + // Was pay for total distance. + // Now depracated. + uint8 dummy; + file->rdwr_byte( dummy, "" ); + } file->rdwr_short(starting_month, ""); @@ -547,7 +557,7 @@ void einstellungen_t::rdwr(loadsave_t *file) { file->rdwr_short(min_bonus_max_distance, ""); file->rdwr_short(max_bonus_min_distance, ""); - if(file->get_experimental_version() <= 1) + if(file->get_experimental_version() == 1) { uint16 dummy; file->rdwr_short(dummy, ""); @@ -683,6 +693,8 @@ void einstellungen_t::rdwr(loadsave_t *file) uint16 global_power_factor_percent = global_power_factor * 100; file->rdwr_short(global_power_factor_percent, ""); global_power_factor = (float)global_power_factor_percent / 100; + file->rdwr_short(passenger_max_wait, ""); + file->rdwr_byte(max_rerouting_interval_months, ""); } } @@ -749,10 +761,10 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s max_transfers = contents.get_int("max_transfers", max_transfers ); passenger_factor = contents.get_int("passenger_factor", passenger_factor ); /* this can manipulate the passenger generation */ seperate_halt_capacities = contents.get_int("seperate_halt_capacities", seperate_halt_capacities ) != 0; - pay_for_total_distance = contents.get_int("pay_for_total_distance", pay_for_total_distance ); avoid_overcrowding = contents.get_int("avoid_overcrowding", avoid_overcrowding )!=0; no_routing_over_overcrowding = contents.get_int("no_routing_over_overcrowded", no_routing_over_overcrowding )!=0; - + passenger_max_wait = contents.get_int("passenger_max_wait", passenger_max_wait); + max_rerouting_interval_months = contents.get_int("max_rerouting_interval_months", max_rerouting_interval_months); fussgaenger = contents.get_int("random_pedestrians", fussgaenger ) != 0; show_pax = contents.get_int("stop_pedestrians", show_pax ) != 0; diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index f34f59553a9..399f3a27546 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -138,16 +138,6 @@ class einstellungen_t // true, if the different caacities (passengers/mail/freight) are counted seperately bool seperate_halt_capacities; - /** - * payment is only for the distance that got shorter between target and start - * three modes: - * 0 = pay for travelled manhattan distance - * 1 = pay for distance difference to next transfer stop - * 2 = pay for distance to destination - * 0 allows chaeting, but the income with 1 or two are much lower - */ - uint8 pay_for_total_distance; - //Cornering settings //@author: jamespetts @@ -168,6 +158,13 @@ class einstellungen_t /* if set, goods will not routed over overcroded stations but rather try detours (if possible) */ bool no_routing_over_overcrowding; + // The longest time that a passenger is + // prepared to wait for transport. + // @author: jamespetts + uint16 passenger_max_wait; + + uint8 max_rerouting_interval_months; + //@author: jamespetts // Revenue calibration settings uint16 min_bonus_max_distance; @@ -500,9 +497,6 @@ class einstellungen_t uint8 get_max_direction_steps (waytype_t waytype) const { return max_direction_steps[waytype]; } uint8 get_curve_friction_factor (waytype_t waytype) const { return curve_friction_factor[waytype]; } - bool is_pay_for_total_distance() const { return pay_for_total_distance; } - void set_pay_for_total_distance( bool b ) { pay_for_total_distance = b; } - uint16 get_factory_max_years_obsolete() const { return factory_max_years_obsolete; } uint8 get_interest_rate_percent() const { return interest_rate_percent; } @@ -521,6 +515,10 @@ class einstellungen_t // do not allow routes over overcrowded destinations bool is_no_routing_over_overcrowding() const { return no_routing_over_overcrowding; } + uint16 get_passenger_max_wait() const { return passenger_max_wait; } + + uint8 get_max_rerouting_interval_months() const { return max_rerouting_interval_months; } + sint16 get_river_number() const { return river_number; } void set_river_number( sint16 n ) { river_number = n; } sint16 get_min_river_length() const { return min_river_length; } diff --git a/gui/colors.cc b/gui/colors.cc index d9a15457dd6..5ccf6f2e018 100644 --- a/gui/colors.cc +++ b/gui/colors.cc @@ -81,7 +81,7 @@ color_gui_t::color_gui_t(karte_t *welt) : // scrollspeed scrollspeed.set_pos( koord(RIGHT_WIDTH-10-40,SCROLL_SPEED) ); scrollspeed.set_groesse( koord( 40, BUTTON_HEIGHT-1 ) ); - scrollspeed.set_value( welt->get_einstellungen()->get_verkehr_level() ); + scrollspeed.set_value( abs(umgebung_t::scroll_multi) ); scrollspeed.set_limits( 1, 9 ); scrollspeed.add_listener(this); add_komponente(&scrollspeed); @@ -89,7 +89,7 @@ color_gui_t::color_gui_t(karte_t *welt) : // traffic density traffic_density.set_pos( koord(RIGHT_WIDTH-10-50,DENS_TRAFFIC) ); traffic_density.set_groesse( koord( 50, BUTTON_HEIGHT-1 ) ); - traffic_density.set_value( abs(umgebung_t::scroll_multi) ); + traffic_density.set_value( welt->get_einstellungen()->get_verkehr_level() ); traffic_density.set_limits( 0, 16 ); traffic_density.add_listener(this); add_komponente(&traffic_density); diff --git a/gui/components/gui_convoy_assembler.cc b/gui/components/gui_convoy_assembler.cc index d00b577b580..a4a60033449 100644 --- a/gui/components/gui_convoy_assembler.cc +++ b/gui/components/gui_convoy_assembler.cc @@ -472,7 +472,7 @@ void gui_convoy_assembler_t::zeichnen(koord parent_pos) } max_speed = min(min_top_speed, (uint32) sqrt((((double)total_power/total_min_weight)-1)*2500)); min_speed = min(min_top_speed, (uint32) sqrt((((double)total_power/total_max_weight)-1)*2500)); - uint8 tile_length; + uint16 tile_length; if(depot_frame != NULL) { tile_length = depot_frame->get_convoy()->get_tile_length(); diff --git a/player/ai.cc b/player/ai.cc index d35bbbb63a5..fd4cd076c88 100755 --- a/player/ai.cc +++ b/player/ai.cc @@ -115,8 +115,15 @@ bool ai_t::is_connected( const koord start_pos, const koord dest_pos, const ware ware_t ware(wtyp); ware.set_zielpos(dest_pos); ware.menge = 1; - for (uint16 hh = 0; hh<start_plan->get_haltlist_count(); hh++) { - if( start_list[hh]->suche_route( ware, NULL, false ) != haltestelle_t::NO_ROUTE ) { + for (uint16 hh = 0; hh<start_plan->get_haltlist_count(); hh++) + { +#ifdef NEW_PATHING + if(start_list[hh]->find_route(ware) < 65535) + { +#else + if( start_list[hh]->suche_route( ware, NULL, false ) != haltestelle_t::NO_ROUTE ) + { +#endif // ok, already connected return true; } diff --git a/simcity.cc b/simcity.cc index 4c288505e2c..c03a9daede6 100644 --- a/simcity.cc +++ b/simcity.cc @@ -1721,12 +1721,20 @@ void stadt_t::step_passagiere() } int current_destination = 0; - //bool route_good = false; +#ifdef NEW_PATHING + bool route_good = false; +#else route_result = haltestelle_t::NO_ROUTE; +#endif bool can_walk_ziel = false; +#ifdef NEW_PATHING + while(route_good && !can_walk_ziel && current_destination < destination_count) + { +#else while(route_result != haltestelle_t::ROUTE_OK && !can_walk_ziel && current_destination < destination_count) { +#endif #ifdef DESTINATION_CITYCARS //citycars with destination @@ -1778,8 +1786,11 @@ void stadt_t::step_passagiere() halthandle_t current_halt = *start_halts.get_element(0); current_halt->add_pax_no_route(pax_left_to_do); } - //route_good = false; +#ifdef NEW_PATHING + route_good = false; +#else route_result = haltestelle_t::NO_ROUTE; +#endif if(has_private_car) { @@ -1793,8 +1804,11 @@ void stadt_t::step_passagiere() //@author: jamespetts set_private_car_trip(pax_left_to_do, destinations[current_destination].town); - //route_good = true; +#ifdef NEW_PATHING + route_good = true; +#else route_result = haltestelle_t::ROUTE_OK; +#endif #ifdef DESTINATION_CITYCARS //citycars with destinations @@ -1817,8 +1831,11 @@ void stadt_t::step_passagiere() merke_passagier_ziel(destinations[0].location, COL_YELLOW); city_history_year[0][history_type] += pax_left_to_do; city_history_month[0][history_type] += pax_left_to_do; - //route_good = true; +#ifdef NEW_PATHING + route_good = true; +#else route_result = haltestelle_t::ROUTE_OK; +#endif current_destination ++; continue; } @@ -1831,8 +1848,13 @@ void stadt_t::step_passagiere() // now, finally search a route; this consumes most of the time koord return_zwischenziel = koord::invalid; // for people going back ... +#ifdef NEW_PATHING + uint16 best_journey_time = 65535; + uint8 best_start_halt = 0; +#else halthandle_t best_destination[3]; uint8 best_journey_steps = 255; +#endif ITERATE(start_halts,i) { @@ -1841,14 +1863,25 @@ void stadt_t::step_passagiere() break; } halthandle_t current_halt = *start_halts[i]; +#ifdef NEW_PATHING + uint16 current_journey_time = current_halt->find_route(ware, best_journey_time); + if(current_journey_time < best_journey_time) + { + best_journey_time = current_journey_time; + best_start_halt = i; + } +#else route_result = current_halt->suche_route( pax, will_return ? &return_zwischenziel : NULL, welt->get_einstellungen()->is_no_routing_over_overcrowding() ); +#endif if(!pax.get_ziel().is_bound()) { //Only continue processing if there is a route. continue; } - //route_good = true; +#ifdef NEW_PATHING + route_good = true; +#else halthandle_t tmp[3]; tmp[0] = pax.get_ziel(); tmp[1] = pax.get_zwischenziel(); @@ -1865,20 +1898,44 @@ void stadt_t::step_passagiere() } } - //TODO: Improve means of selecting the best route here. - +#endif +#ifdef NEW_PATHING + if(route_good) + { +#else if(route_result == haltestelle_t::ROUTE_OK) { //Only add passengers to the start halt (etc.) if a route was found. pax.set_ziel(best_destination[0]); pax.set_zwischenziel(best_destination[1]); pax.set_journey_steps(best_journey_steps); +#endif pax.arrival_time = welt->get_zeit_ms(); +#ifndef NEW_PATHING start_halt = best_destination[2]; +#else + // All passengers will use the quickest route. + // TODO: Consider whether to randomise a little. + start_halt = start_halts[best_start_halt]; +#endif +#ifdef NEW_PATHING + if(start_halt == pax.get_ziel()) + { +#else + if(start_halt == best_destination[0]) + { +#endif + // Without this, where there are overlapping stops, passengers + // for nearby destinations accumulate at a stop, destined for + // that same stop, and never leave. + can_walk_ziel = true; + break; + } pax.set_origin(start_halt); // Now, decide whether passengers would prefer to use their private cars, // even though they can travel by public transport. + uint16 distance = accurate_distance(destinations[current_destination].location, pos); if(has_private_car) { //Weighted random. @@ -1894,7 +1951,8 @@ void stadt_t::step_passagiere() sint16 car_preference = welt->get_einstellungen()->get_base_car_preference_percent(); //First, adjust for distance. For very long-distance journies, cars are less popular. - uint16 distance = abs(destinations[current_destination].location.x - pos.x) + abs(destinations[current_destination].location.x - pos.y); + + //uint16 distance = abs(destinations[current_destination].location.x - pos.x) + abs(destinations[current_destination].location.x - pos.y); if(distance > (midrange_passengers_max_distance * 3)) { if(distance >= longdistance_passengers_max_distance) @@ -1927,7 +1985,22 @@ void stadt_t::step_passagiere() car_preference -= congestion_factor; // Thirdly adjust for service quality of the public transport. +#ifdef NEW_PATHING + // Compare the average speed, including waiting times, with the speed bonus speed for + // *road* transport. + + // This is the speed bonus calculation, without reference to price. + const uint16 average_speed = (60 * distance) / (best_journey_time * (1.0 - welt->get_einstellungen()->get_journey_time_multiplier()); + const sint32 ref_speed = welt->get_average_speed(road_wt); + const uint16 speed_bonus_rating = calc_adjusted_speed_bonus(goods->get_speed_bonus(), distance); + const sint32 speed_base = (100 * average_speed) / ref_speed - 100; + const float base_bonus = (float)speed_base * ((float)speed_bonus_rating / 100.0); + //base_bonus should be 1 if the average speed is the same as the bonus speed. + //TODO: Check whether these calculations are correct. + private_car_chance *= base_bonus; +#else + //For some reason, the journey steps seem to be multiplied by 7. uint8 hops = best_journey_steps / 7; @@ -1980,9 +2053,11 @@ void stadt_t::step_passagiere() }; private_car_chance *= hop_factor; +#endif //Secondly, the number of unhappy passengers at the start station compared with the number of happy passengers. - float unhappy_total = start_halt->get_pax_unhappy() - start_halt->get_pax_happy(); + float unhappy_factor = start_halt->get_unhappy_proportion; + /*float unhappy_total = start_halt->get_pax_unhappy() - start_halt->get_pax_happy(); float unhappy_factor; if(unhappy_total > 0) { @@ -1991,7 +2066,7 @@ void stadt_t::step_passagiere() else { unhappy_factor = 0.0; - } + }*/ if(unhappy_factor > 0.8) { @@ -2028,6 +2103,7 @@ void stadt_t::step_passagiere() if(start_halts.get_count() > 0) { start_halt = *start_halts.get_element(0); //If there is no route, it does not matter where passengers express their unhappiness. +#ifndef NEW_PATHING if( route_result == haltestelle_t::ROUTE_OVERCROWDED ) { merke_passagier_ziel(destinations[current_destination].location, COL_ORANGE ); @@ -2039,38 +2115,51 @@ void stadt_t::step_passagiere() } else { +#endif start_halt->add_pax_no_route(pax_left_to_do); merke_passagier_ziel(destinations[current_destination].location, COL_DARK_ORANGE); +#ifndef NEW_PATHING } +#endif } + if(has_private_car) { //Must use private car, since there is no suitable route. set_private_car_trip(num_pax, destinations[current_destination].town); - #ifdef DESTINATION_CITYCARS +#ifdef DESTINATION_CITYCARS //citycars with destination if(start_halt.is_bound()) { erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, destinations[current_destination].location); } - #endif +#endif } } // send them also back - if (will_return != no_return && route_result == haltestelle_t::ROUTE_OK) { +#ifdef NEW_PATHING + if(will_return != no_return && route_good) + { +#else + if (will_return != no_return && route_result == haltestelle_t::ROUTE_OK) + { +#endif // this comes most of the times for free and balances also the amounts! halthandle_t ret_halt = pax.get_ziel(); - if (will_return != town_return) { + if (will_return != town_return) + { // restore normal mail amount => more mail from attractions and factories than going to them pax.menge = pax_left_to_do; } // we just have to ensure, the ware can be delivered at this station bool found = false; - for (uint i = 0; i < plan->get_haltlist_count(); i++) { + for (uint i = 0; i < plan->get_haltlist_count(); i++) + { halthandle_t test_halt = halt_list[i]; - if (test_halt->is_enabled(wtyp) && (start_halt==test_halt || test_halt->get_warenziele(wtyp->get_catg_index())->is_contained(start_halt))) { + if (test_halt->is_enabled(wtyp) && (start_halt==test_halt || test_halt->get_warenziele(wtyp->get_catg_index())->is_contained(start_halt))) + { found = true; start_halt = test_halt; break; @@ -2079,9 +2168,11 @@ void stadt_t::step_passagiere() // now try to add them to the target halt uint32 max_ware = ret_halt->get_capacity(wtyp->get_index()); - if( !ret_halt->is_overcrowded(wtyp->get_catg_index()) ) { + if( !ret_halt->is_overcrowded(wtyp->get_catg_index()) ) + { // prissi: not overcrowded and can recieve => add them - if (found) { + if (found) + { ware_t return_pax(wtyp, ret_halt); return_pax.menge = pax_left_to_do; return_pax.set_zielpos(k); @@ -2092,7 +2183,9 @@ void stadt_t::step_passagiere() ret_halt->starte_mit_route(return_pax); ret_halt->add_pax_happy(pax_left_to_do); - } else { + } + else + { // no route back ret_halt->add_pax_no_route(pax_left_to_do); if(has_private_car) @@ -2103,7 +2196,8 @@ void stadt_t::step_passagiere() } } - else { + else + { // return halt crowded ret_halt->add_pax_unhappy(pax_left_to_do); if(has_private_car) diff --git a/simconvoi.cc b/simconvoi.cc index 852325853e2..764506616e8 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -226,11 +226,24 @@ DBG_MESSAGE("convoi_t::~convoi_t()", "destroying %d, %p", self.get_id(), this); // force asynchronous recalculation if(fpl) { - if(!fpl->ist_abgeschlossen()) { + if(!fpl->ist_abgeschlossen()) { //"is completed" (Google) destroy_win((long)fpl); } - if(fpl->get_count()>0 && !line.is_bound() ) { - welt->set_schedule_counter(); + +#ifdef NEW_PATHING + if(fpl->get_count()>0 && !line.is_bound() ) + { + // New method - recalculate as necessary + ITERATE(fpl, j) + { + halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale); + } +#else + // Old method - brute force + welt->set_schedule_counter(); +#endif } delete fpl; } @@ -1283,8 +1296,22 @@ void convoi_t::start() // might have changed the vehicles in this car ... line->recalc_catg_index(); } - else { + else + { +#ifdef NEW_PATHING + + // New method - recalculate as necessary + ITERATE(fpl, j) + { + halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale); + } + +#else + // Old method - brute force welt->set_schedule_counter(); +#endif } DBG_MESSAGE("convoi_t::start()","Convoi %s wechselt von INITIAL nach ROUTING_1", name_and_id); @@ -1527,14 +1554,38 @@ bool convoi_t::set_schedule(schedule_t * f) DBG_DEBUG("convoi_t::set_fahrplan()", "new=%p, old=%p", f, fpl); - if(f == NULL) { + if(f == NULL) + { return false; } +#ifdef NEW_PATHING + if(!line.is_bound() && old_state != INITIAL) + { + // New method - recalculate as necessary + ITERATE(fpl, j) + { + halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale); + } + + ITERATE(f, k) + { + halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale); + } + } +#endif + // happens to be identical? - if(fpl!=f) { + if(fpl != f) + { // destroy a possibly open schedule window - if(fpl && !fpl->ist_abgeschlossen()) { + if(fpl && !fpl->ist_abgeschlossen()) + { + //"is completed" (Google) destroy_win((long)fpl); delete fpl; } @@ -1542,17 +1593,24 @@ bool convoi_t::set_schedule(schedule_t * f) } // remove wrong freight - for(unsigned i=0; i<anz_vehikel; i++) { + for(unsigned i=0; i<anz_vehikel; i++) + { fahr[i]->remove_stale_freight(); } // ok, now we have a schedule - if(old_state!=INITIAL) { + if(old_state != INITIAL) + { state = FAHRPLANEINGABE; - if( !line.is_bound() ) { + +#ifndef NEW_PATHING + // Old method - brute force + if( !line.is_bound() ) + { // asynchronous recalculation of routes welt->set_schedule_counter(); } +#endif } return true; } @@ -2736,9 +2794,12 @@ void convoi_t::laden() //"load" (Babelfish) { //Calculate average speed //@author: jamespetts - const double journey_time = (welt->get_zeit_ms() - last_departure_time) / 4096; + const double journey_time = (welt->get_zeit_ms() - last_departure_time) / 4096.0; const uint32 journey_distance = accurate_distance(fahr[0]->get_pos().get_2d(), fahr[0]->last_stop_pos); + //const uint16 TEST_speed = (1 / journey_time) * 20; + //const uint16 TEST_minutes = (((float)1 / TEST_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 60); const uint16 average_speed = (journey_distance / journey_time) * 20; + //const uint16 TEST_actual_minutes = (((float)journey_distance / average_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 60); book(average_speed, CONVOI_AVERAGE_SPEED); last_departure_time = welt->get_zeit_ms(); @@ -3235,15 +3296,6 @@ void convoi_t::hat_gehalten(koord k, halthandle_t halt) //"has held" (Google) for(uint8 i=0; i < anz_vehikel ; i++) { vehikel_t* v = fahr[i]; - - // Run this routine twice: first, load all vehicles to their non-overcrowded capacity. - // Then, allow them to run to their overcrowded capacity. - if(!second_run && i >= anz_vehikel - 1) - { - //Reset counter for one more go - second_run = true; - i = 0; - } station_lenght -= v->get_besch()->get_length(); if(station_lenght<0) @@ -3268,6 +3320,15 @@ void convoi_t::hat_gehalten(koord k, halthandle_t halt) //"has held" (Google) } + // Run this routine twice: first, load all vehicles to their non-overcrowded capacity. + // Then, allow them to run to their overcrowded capacity. + if(!second_run && i >= anz_vehikel - 1) + { + //Reset counter for one more go + second_run = true; + i = 0; + } + } // any loading went on? @@ -3430,14 +3491,35 @@ void convoi_t::set_line(linehandle_t org_line) if(line.is_bound()) { unset_line(); } - else if(fpl && fpl->get_count()>0) { + else if(fpl && fpl->get_count()>0) + { // since this schedule is no longer served + +#ifdef NEW_PATHING + // New method - recalculate on demand + ITERATE(fpl, j) + { + halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale); + } +#else + // Old method - brute force welt->set_schedule_counter(); +#endif } line = org_line; line_id = org_line->get_line_id(); schedule_t *new_fpl= org_line->get_schedule()->copy(); set_schedule(new_fpl); + + ITERATE(new_fpl, j) + { + halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale); + } + line->add_convoy(self); } diff --git a/simfab.cc b/simfab.cc index 0b18c1a10a1..e8275455853 100644 --- a/simfab.cc +++ b/simfab.cc @@ -1087,7 +1087,13 @@ void fabrik_t::verteile_waren(const uint32 produkt) // Station can only store up to a maximum amount of goods per square const sint32 halt_left = (sint32)halt->get_capacity(2) - (sint32)halt->get_ware_summe(ware.get_besch()); // ok, still enough space - if( halt->suche_route( ware, NULL, welt->get_einstellungen()->is_no_routing_over_overcrowding() )==haltestelle_t::ROUTE_OK ) { +#ifdef NEW_PATHING + if(halt->find_route(ware) < 65535) + { +#else + if( halt->suche_route( ware, NULL, welt->get_einstellungen()->is_no_routing_over_overcrowding() )==haltestelle_t::ROUTE_OK ) + { +#endif // if only overflown factories found => deliver to first // else deliver to non-overflown factory diff --git a/simhalt.cc b/simhalt.cc index 6853d415c7a..173dab365c9 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -60,6 +60,7 @@ #include "vehicle/simpeople.h" + #ifdef LAGER_NOT_IN_USE #include "dings/lagerhaus.h" #endif @@ -259,6 +260,10 @@ haltestelle_t::haltestelle_t(karte_t* wl, loadsave_t* file) sortierung = freight_list_sorter_t::by_name; resort_freight_info = true; + connexions_timestamp = 0; + paths_timestamp = 0; + reschedule = false; + rdwr(file); alle_haltestellen.insert(self); @@ -300,12 +305,9 @@ haltestelle_t::haltestelle_t(karte_t* wl, koord k, spieler_t* sp) welt->access(k)->set_halt(self); } - // TODO: Add load/save parameters for: - // (1) origin; - // (2) last transfer; - // (3) origin departure time; and - // (4) last transfer departure time. - // Then, reversion the save game file format. + connexions_timestamp = 0; + paths_timestamp = 0; + reschedule = false; } @@ -708,14 +710,34 @@ void haltestelle_t::step() { // DBG_MESSAGE("haltestelle_t::step()","%s (cnt %i)",get_name(),reroute_counter); - if(rebuilt_destination_counter!=welt->get_schedule_counter()) { - // schedule has changed ... + if(rebuilt_destination_counter != welt->get_schedule_counter()) + { +#ifndef NEW_PATHING + // Old routing system - + // recalculate straight away rebuild_destinations(); +#else + + // New routing system - + // recalculate on demand + reschedule = true; + + // Note: setting reschedule to true here + // is inefficient, as it means that all halts + // will need to be recalculated. Where possible, + // it is best to set reschedule to true + // individually depending on which halts are + // affected by rescheduling. +#endif } - else { + + else + { // all new connection updated => recalc routes - if(reroute_counter!=welt->get_schedule_counter()) { + if(reroute_counter != welt->get_schedule_counter()) + { reroute_goods(); + // DBG_MESSAGE("haltestelle_t::step()","rerouting goods at %s",get_name()); } } @@ -760,6 +782,8 @@ void haltestelle_t::neuer_monat() */ void haltestelle_t::reroute_goods() { + //TODO: Update this to use the new routing method. + // reroute only on demand reroute_counter = welt->get_schedule_counter(); @@ -790,7 +814,14 @@ void haltestelle_t::reroute_goods() } // check if this good can still reach its destination - if( suche_route( ware, NULL, false )==NO_ROUTE ) { + +#ifdef NEW_PATHING + if(find_route(ware) == 65535) + { +#else + if( suche_route( ware, NULL, false )==NO_ROUTE ) + { +#endif // remove invalid destinations continue; } @@ -889,7 +920,87 @@ void haltestelle_t::hat_gehalten(const ware_besch_t *type, const schedule_t *fpl } } +#ifdef NEW_PATHING +void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fpl, const convoihandle_t cnv, const linehandle_t line) +{ + if(type != warenbauer_t::nichts) + { + ITERATE_PTR(fpl,i) + { + // Hajo: Haltestelle selbst wird nicht in Zielliste aufgenommen + //"Station itself is not in target list" (Google) + halthandle_t halt = get_halt(welt, fpl->eintrag[i].pos); + // not existing, or own, or not enabled => ignore + if(!halt.is_bound() || halt == self || !halt->is_enabled(type)) + { + continue; + } + // Check the journey times to the connexion + connexion new_connexion; + new_connexion.waiting_time = get_average_waiting_time(halt, type->get_catg_index()); + + // Check the average speed. + uint16 average_speed; + if(line.is_bound()) + { + average_speed = line->get_finance_history(1, LINE_AVERAGE_SPEED) > 0 ? cnv->get_finance_history(1, LINE_AVERAGE_SPEED) : cnv->get_finance_history(0, LINE_AVERAGE_SPEED); + // If the average speed is not initialised, take a guess to prevent perverse outcomes and possible deadlocks. + average_speed = average_speed > 0 ? average_speed : line->get_convoy(0)->get_min_top_speed() / 2; + } + else if(cnv.is_bound()) + { + average_speed = cnv->get_finance_history(1, CONVOI_AVERAGE_SPEED) > 0 ? cnv->get_finance_history(1, CONVOI_AVERAGE_SPEED) : cnv->get_finance_history(0, CONVOI_AVERAGE_SPEED); + // If the average speed is not initialised, take a guess to prevent perverse outcomes and possible deadlocks. + average_speed = average_speed > 0 ? average_speed : cnv->get_min_top_speed() / 2; + } + else + { + // This should never be reached. + assert(false); + continue; + } + + const uint32 journey_distance = accurate_distance(halt->get_basis_pos(), get_basis_pos()); + new_connexion.journey_time = (((float)journey_distance / average_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 60); + new_connexion.best_convoy = cnv; + new_connexion.best_line = line; + + // Check whether this is the best connexion so far, and, if so, add it. + if(!connexions[type->get_catg_index()].put(halt, new_connexion)) + { + // The key exists in the hashtable already - check whether this entry is better. + const connexion existing_connexion = connexions[type->get_catg_index()].get(halt); + if(existing_connexion.journey_time > new_connexion.journey_time) + { + // The new connexion is better - replace it. + connexions[type->get_catg_index()].set(halt, new_connexion); + } + //TODO: Consider whether to add code for comfort here, too. + + if( waren[type->get_catg_index()] == NULL ) + { + // indicates that this can route those goods + waren[type->get_catg_index()] = new vector_tpl<ware_t>(0); + } + } + } + } +} + +linehandle_t haltestelle_t::get_preferred_line(halthandle_t transfer, uint8 category) const +{ + linehandle_t best_line = connexions[category].get(transfer).best_line; + return linehandle_t; +} + +convoihandle_t haltestelle_t::get_preferred_convoi(halthandle_t transfer, uint8 category) const +{ + convoihandle_t best_convoy = connexions[category].get(transfer).best_convoy; + return best_convoy; +} + +#else /** * Rebuilds the list of reachable destinations @@ -964,7 +1075,298 @@ void haltestelle_t::rebuild_destinations() } } } +#endif + +#ifdef NEW_PATHING + +//@author: jamespetts (although much is taken from the original rebuild_destinations()) +void haltestelle_t::rebuild_connexions(uint8 category) +{ + connexions[category].clear(); + connexions_timestamp = welt->get_base_pathing_counter(); + if(connexions_timestamp == 0 || reschedule) + { + // Spread the load of rebuilding this with pathing - advance by half the interval. + connexions_timestamp += (welt->get_einstellungen()->get_max_rerouting_interval_months() / 2); + } + + reschedule = false; + + rebuilt_destination_counter = welt->get_schedule_counter(); + resort_freight_info = true; // might result in error in routing + + const bool i_am_public = get_besitzer() == welt->get_spieler(1); + + // first all single convois without lines + vector_tpl<uint8> add_catg_index(4); + for (vector_tpl<convoihandle_t>::const_iterator i = welt->convois_begin(), end = welt->convois_end(); i != end; ++i) + { + convoihandle_t cnv = *i; + if(cnv->get_line().is_bound()) + { + // Deal with lines later. + continue; + } + + if(i_am_public || cnv->get_besitzer() == get_besitzer()) + { + INT_CHECK("simhalt.cc 612"); + + schedule_t *fpl = cnv->get_schedule(); + if(fpl != NULL) + { + const linehandle_t dummy; + ITERATE_PTR(fpl, i) + { + // Hajo: Hält dieser convoi hier? + // "If this Convoi here?" (Google) + if (get_halt(welt, fpl->eintrag[i].pos) == self) + { + // what goods can this convoy transport? + add_catg_index.clear(); + for(uint i = 0; i < cnv->get_vehikel_anzahl(); i++) + { + // Only consider vehicles that really transport something + // this helps against routing errors through passenger + // trains pulling only freight wagons + const ware_besch_t *ware = cnv->get_vehikel(i)->get_fracht_typ(); + + if (cnv->get_vehikel(i)->get_fracht_max() == 0 || ware->get_catg_index() != category) + { + continue; + } + + if(ware != warenbauer_t::nichts && !add_catg_index.is_contained(ware->get_catg_index())) + { + // now add the freights + add_connexion(ware, fpl, cnv, dummy); + add_catg_index.append_unique(category); + } + } + } + } + } + } + } + // now for the lines + ITERATE(registered_lines,i) + { + const linehandle_t line = registered_lines[i]; + schedule_t *fpl = line->get_schedule(); + assert(fpl); + // ok, now add line to the connections + if(line->count_convoys( )> 0 && (i_am_public || line->get_convoy(0)->get_besitzer() == get_besitzer())) + { + const convoihandle_t dummy; + add_connexion(warenbauer_t::get_info_catg_index(line->get_goods_catg_index()[category]), fpl, dummy, line); + } + } +} + +//@author: jamespetts +void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) +{ + // Use Dijkstra's Algorithm to find all the best routes from here at once + // http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm + + // Only recalculate when necessary (i.e., on schedule change, or + // after a certain period of time has elapse), and in any event + // not until a destination from this halt is requested, to prevent + // the game pausing and becoming unresponsive whilst everything is + // re-calculated all at the same time. + + if((category == 0 && !get_pax_enabled()) || (category == 1 && !get_post_enabled()) || (category > 1 && !get_ware_enabled())) + { + // Cannot route from this station: do not try. + return; + } + + if(reschedule || connexions_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) + { + // Connexions are stale. Recalculate. + rebuild_connexions(category); + // Not clearing the open list would be faster, but could give anomalous results. + // Thus, if connexions are stale, all new paths will be recalculated from scratch. + open_list.clear(); + } + if(paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) + { + // List is stale. Recalculate. + // If this is false, then this is only being called to finish calculating + // paths that have not yet been calculated. + open_list.clear(); + // Reset the timestamp. + paths_timestamp = welt->get_base_pathing_counter(); + } + + uint16 iterations = 0; + + path_node* starting_node; + starting_node->halt = self; + starting_node->link = NULL; + starting_node->journey_time = 0; // Takes 0 time to stay in the same place + + open_list.insert(starting_node); + + const uint16 max_transfers = welt->get_einstellungen()->get_max_transfers(); + + do + { + iterations ++; + path_node* current_node = open_list.pop(); + if(current_node->halt == goal) + { + // Abort the search early if the goal stop is found. + // Because the open list is stored on the heap, the search + // can be resumed where it left off if another goal, as yet + // not found, is searched for, unless the index is stale. + return; + } + quickstone_hashtable_tpl<haltestelle_t, connexion> current_connexions = current_node->halt->get_connexions(category); + quickstone_hashtable_iterator_tpl<haltestelle_t, connexion> iter(current_connexions); + while(iter.next()) + { + path_node* new_node; + new_node->halt = iter.get_current_key(); + new_node->link = current_node; + connexion current_connexion = iter.get_current_value(); + new_node->journey_time = current_connexion.journey_time + current_connexion.waiting_time + current_node->journey_time; + open_list.insert(new_node); + } + + path new_path; + new_path.journey_time = current_node->journey_time; + + // Add only if not already contained. + if(paths[category].put(current_node->halt, new_path)) + { + // Track the path back to get the next transfer from this halt + path_node* track_node = current_node; + while(track_node->link->halt != self) + { + track_node = track_node->link; + } + paths[category].access(current_node->halt)->next_transfer = track_node->halt; + } + } + while(iterations <= max_transfers && open_list.get_count() > 0); + search_complete = true; + +} + +haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category) +{ + path destination_path; + + if(reschedule || paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) + { + // If the paths hashtable is stale, clear it. + // This will mean that all the paths will need to be recalculated. + // Must always recalculate if the schedules change. + paths[category].clear(); + } + + destination_path = paths[category].get(goal); + if(!destination_path.next_transfer.is_bound() && !search_complete) + { + // The pathfinding is incomplete or stale - recalculate + // If the next transfer is not bound even though the search + // is complete, then there is no admissible path to the goal. + calculate_paths(goal, category); + destination_path = paths[category].get(goal); + } + return destination_path; +} + +quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion> haltestelle_t::get_connexions(uint8 c) +{ + if(reschedule || paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) + { + // Rebuild the connexions if they are stale. + rebuild_connexions(c); + } + + return connexions[c]; +} + +void haltestelle_t::force_paths_stale() +{ + if(paths_timestamp > welt->get_einstellungen()->get_max_rerouting_interval_months()) + { + paths_timestamp -= welt->get_einstellungen()->get_max_rerouting_interval_months(); + } + else + { + // Prevent overflows. + paths_timestamp = 0; + } +} + +uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_time) +{ + uint16 journey_time = previous_journey_time; + const ware_besch_t * warentyp = ware.get_besch(); + const uint8 ware_catg_index = warentyp->get_catg_index(); + const koord ziel = ware.get_zielpos(); + + // since also the factory halt list is added to the ground, we can use just this ... + const planquadrat_t *plan = welt->lookup(ziel); + const halthandle_t *halt_list = plan->get_haltlist(); + // but we can only use a subset of these + vector_tpl<halthandle_t> ziel_list(plan->get_haltlist_count()); + + for(uint16 h = 0; h < plan->get_haltlist_count(); h++) + { + halthandle_t halt = halt_list[h]; + if(halt->is_enabled(warentyp)) + { + ziel_list.append(halt); + } + } + + if( ziel_list.empty() ) + { + //no target station found + ware.set_ziel(halthandle_t()); + ware.set_zwischenziel(halthandle_t()); + return 65535; + } + + // check, if the shortest connection is not right to us ... + if(ziel_list.is_contained(self)) + { + ware.set_ziel(self); + ware.set_zwischenziel( halthandle_t()); + return 0; + } + + uint16 best_destination; + + // Now, find the best route from here. + ITERATE(zeil_list,i) + { + path test_path = get_path_to(zeil_list[i], ware.get_catg()); + if(test_path.journey_time < journey_time) + { + journey_time = test_path.journey_time; + best_destination = i; + } + } + + if(journey_time < previous_journey_time) + { + // If we are comparing this with other routes from different start halts, + // only set the details if it is the best route so far. + ware.set_ziel(zeil_list[best_destination]); + path final_path = get_path_to(zeil_list[best_destination], ware.get_catg(); + ware.set_zwischenziel(final_path.next_transfer); + return final_path.journey_time; + } + + return journey_time; +} +#else /* HNode is used for route search */ @@ -985,7 +1387,7 @@ struct HNode { * later games. So all changes should be done with this in mind! * * If no route is found, ziel and zwischenziel are unbound handles. - * If next_to_ziel in not NULL, it will get the koordinate of the stop + * If next_to_ziel is not NULL, it will get the koordinate of the stop * previous to target. Can be used to create passengers/mail back the * same route back * @@ -1186,7 +1588,7 @@ int haltestelle_t::suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_ov } } - +#endif /** * Found route and station uncrowded @@ -1283,7 +1685,7 @@ bool haltestelle_t::recall_ware( ware_t& w, uint32 menge ) // will load something compatible with wtyp into the car which schedule is fpl -ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t *fpl) //"hole from" (Google) +ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t *fpl, convoihandle_t cnv) //"hole from" (Google) { // prissi: first iterate over the next stop, then over the ware // might be a little slower, but ensures that passengers to nearest stop are served first @@ -1291,7 +1693,8 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t const uint8 count = fpl->get_count(); vector_tpl<ware_t> *warray = waren[wtyp->get_catg_index()]; - if(warray!=NULL) { + if(warray!=NULL) + { // da wir schon an der aktuellem haltestelle halten // startet die schleife ab 1, d.h. dem naechsten halt @@ -1299,36 +1702,90 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t // because we have to keep the current haltestelle // loop starts from 1, i.e. the next stop (Google) - for( uint8 i=1; i<count; i++ ) { + for( uint8 i=1; i<count; i++ ) + { const uint8 wrap_i = (i + fpl->get_aktuell()) % count; const halthandle_t plan_halt = get_halt(welt, fpl->eintrag[wrap_i].pos); //eintrag = "entry" (Google) - if(plan_halt == self) { + if(plan_halt == self) + { // we will come later here again ... break; } - else if( plan_halt.is_bound() && warray->get_count()>0 ) { + else if( plan_halt.is_bound() && warray->get_count()>0 ) + { // The random offset will ensure that all goods have an equal chance to be loaded. sint32 offset = simrand(warray->get_count()); - for( uint32 i=0; i<warray->get_count(); i++ ) { + for( uint32 i=0; i<warray->get_count(); i++ ) + { ware_t &tmp = (*warray)[ i+offset ]; // prevent overflow (faster than division) - if( i+offset+1>=warray->get_count() ) { + if( i+offset+1>=warray->get_count() ) + { offset -= warray->get_count(); } // skip empty entries - if(tmp.menge==0) { + if(tmp.menge == 0) + { continue; } + + // Checks to see whether the freight has been waiting too long. + // If so, discard it. + if(tmp.get_besch()->get_speed_bonus() > 0) + { + //Only consider for discarding if the goods care about their timings. + const uint16 max_minutes = welt->get_einstellungen()->get_passenger_max_wait() / tmp.get_besch()->get_speed_bonus(); + const sint64 waiting_ticks = welt->get_zeit_ms() - tmp.arrival_time; + const uint16 waiting_minutes = get_waiting_minutes(welt->get_zeit_ms() - tmp.arrival_time); + if(waiting_minutes > max_minutes) + { + // Waiting too long: discard + if(tmp.get_catg() == 1) + { + // Passengers - use unhappy graph. + add_pax_unhappy(tmp.menge); + } + + // The goods/passengers leave. + tmp.menge = 0; + } +#ifdef NEW_PATHING + // Skip if the goods have recently arrived, and this is not their preferred line/convoy + // After waiting some time (1/3rd of their maximum wait), they will board anything. + if(cnv.is_bound() && waiting_minutes <= max_minutes / 3) + { + if(cnv->get_line().is_bound()) + { + linehandle_t best_line = halt->get_preferred_line(ware.get_zwischenziel(), ware.get_catg(); + if(!best_line.is_bound() && best_line == cnv->get_line()) + { + continue; + } + } + else + { + convoihandle_t best_convoy = halt->get_preferred_convoy(ware.get_zwischenziel(), ware.get_catg(); + if(!best_convoy.is_bound() && best_convoy == cnv) + { + continue; + } + } + } +#endif + } // compatible car and right target stop? - if( tmp.get_zwischenziel() == plan_halt ) { + if( tmp.get_zwischenziel() == plan_halt ) + { - if( plan_halt->is_overcrowded(wtyp->get_catg_index()) ) { - if( welt->get_einstellungen()->is_avoid_overcrowding() && !(tmp.get_ziel()==plan_halt) ) { + if( plan_halt->is_overcrowded(wtyp->get_catg_index()) ) + { + if( welt->get_einstellungen()->is_avoid_overcrowding() && !(tmp.get_ziel()==plan_halt) ) + { // do not go for transfer to overcrowded transfer stop continue; } @@ -1336,16 +1793,21 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t // not too much? ware_t neu(tmp); - if( tmp.menge > maxi ) { + if( tmp.menge > maxi ) + { // not all can be loaded neu.menge = maxi; tmp.menge -= maxi; } - else { + else + { // leave an empty entry => joining will more often work tmp.menge = 0; } + book(neu.menge, HALT_DEPARTED); + const uint16 waiting_minutes = get_waiting_minutes(welt->get_zeit_ms() - neu.arrival_time); + add_waiting_time(waiting_minutes, neu.get_zwischenziel(), neu.get_catg()); resort_freight_info = true; return neu; } @@ -1360,7 +1822,15 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t return ware_t (wtyp); } +inline uint16 haltestelle_t::get_waiting_minutes(uint32 waiting_ticks) const +{ + // Waiting time is reduced (2* ...) instead of (3 * ...) because, in real life, people + // can organise their journies according to timetables, so waiting is more efficient. + return (2 * welt->get_einstellungen()->get_journey_time_multiplier() * waiting_ticks) / 4096.0; + //Old method (both are functionally equivalent, except for reduction in time. Would be fully equivalent if above was 3 * ...): + //return ((float)1 / (1 / (waiting_ticks / 4096.0) * 20) * welt->get_einstellungen()->get_journey_time_multiplier() * 60); +} uint32 haltestelle_t::get_ware_summe(const ware_besch_t *wtyp) const { @@ -1532,9 +2002,16 @@ uint32 haltestelle_t::starte_mit_route(ware_t ware) } // no valid next stops? Or we are the next stop? - if(ware.get_zwischenziel()==self) { + if(ware.get_zwischenziel() == self) + { dbg->error("haltestelle_t::starte_mit_route()","route cannot contain us as first transfer stop => recalc route!"); - if( suche_route( ware, NULL, false )==NO_ROUTE ) { +#ifdef NEW_PATHING + if(find_route(ware) == 65535) + { +#else + if( suche_route( ware, NULL, false )==NO_ROUTE ) + { +#endif // no route found? dbg->error("haltestelle_t::starte_mit_route()","no route found!"); return ware.menge; @@ -1600,9 +2077,14 @@ dbg->warning("haltestelle_t::liefere_an()","%d %s delivered to %s have no longer return ware.menge; } +#ifdef NEW_PATHING + if(find_route(ware) == 65535) + { +#else // not near enough => we need to do a rerouting if( suche_route( ware, NULL, false )==NO_ROUTE ) { +#endif // target no longer there => delete INT_CHECK("simhalt 1364"); @@ -2071,7 +2553,7 @@ void haltestelle_t::rdwr(loadsave_t *file) for(int i = 0; i < count; i++) { // add to internal storage (use this function, since the old categories were different) ware_t ware(welt,file); - if( ware.menge ) { + if( ware.menge > 0 ) { add_ware_to_halt(ware); } } @@ -2095,10 +2577,69 @@ void haltestelle_t::rdwr(loadsave_t *file) file->rdwr_longlong(financial_history[k][j], " "); } } + + if(file->get_experimental_version() >= 2) + { + for(uint8 i = 0; i < warenbauer_t::get_max_catg_index(); i ++) + { + if(file->is_saving()) + { + uint16 halts_count; + halts_count = waiting_times[i].get_count(); + file->rdwr_short(halts_count, ""); + + quickstone_hashtable_iterator_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>> iter(waiting_times[i]); + + iter.begin(); + while(iter.next()) + { + // Store the coordinates of the key halt + iter.get_current_key()->get_basis_pos().rdwr(file); + uint8 waiting_time_count = iter.get_current_value().get_count(); + file->rdwr_byte(waiting_time_count, ""); + ITERATE(iter.get_current_value(),i) + { + // Store each waiting time + uint16 current_time = iter.access_current_value().get_element(i); + file->rdwr_short(current_time, ""); + } + } + } + else + { + uint16 halts_count; + file->rdwr_short(halts_count, ""); + for(uint16 i = 0; i < halts_count; i ++) + { + koord halt_position; + halt_position.rdwr(file); + halthandle_t current_halt = welt->lookup(halt_position)->get_halt(); + fixed_list_tpl<uint16, 16> list; + uint8 waiting_time_count; + file->rdwr_byte(waiting_time_count, ""); + for(uint8 j = 0; j < waiting_time_count; j ++) + { + uint16 current_time; + file->rdwr_short(current_time, ""); + list.add_to_tail(current_time); + } + waiting_times[i].put(current_halt, list); + } + } + } + } + + if(file->get_experimental_version() >= 2) + { + file->rdwr_short(connexions_timestamp, ""); + file->rdwr_short(paths_timestamp, ""); + file->rdwr_bool(reschedule, ""); + } } +//"Load lock" (Google) void haltestelle_t::laden_abschliessen() { if(besitzer_p==NULL) { diff --git a/simhalt.h b/simhalt.h index 46d5c1be4c3..0a22c7bd1ad 100644 --- a/simhalt.h +++ b/simhalt.h @@ -23,8 +23,11 @@ #include "tpl/slist_tpl.h" #include "tpl/vector_tpl.h" +#include "tpl/quickstone_hashtable_tpl.h" +#include "tpl/fixed_list_tpl.h" +#include "tpl/HOT_queue2_tpl.h" - +#define NEW_PATHING #define MAX_HALT_COST 7 // Total number of cost items #define MAX_MONTHS 12 // Max history @@ -178,13 +181,76 @@ class haltestelle_t convoihandle_t reservation; }; +#ifdef NEW_PATHING + + // Data on direct connexions from one station to the next. + // @author: jamespetts + struct connexion + { + // Times in minutes + uint16 journey_time; + uint16 waiting_time; + + // Convoy only used if line not used + // (i.e., if the best route involves using a convoi without a line) + linehandle_t best_line; + convoihandle_t best_convoy; + + // Necessary for sorting + bool operator ==(const connexion& c) { return (journey_time + waiting_time) == (c.journey_time + c.waiting_time); } + bool operator !=(const connexion& c) { return (journey_time + waiting_time) != (c.journey_time + c.waiting_time); } + bool operator >(const connexion& c) { return (journey_time + waiting_time) > (c.journey_time + c.waiting_time); } + bool operator <(const connexion& c) { return (journey_time + waiting_time) < (c.journey_time + c.waiting_time); } + + // TODO: Consider whether to add comfort + }; + + struct path_node + { + halthandle_t halt; + uint16 journey_time; + path_node* link; + + // Necessary for sorting + bool operator ==(const path_node& p) { return journey_time == p.journey_time; } + bool operator !=(const path_node& p) { return journey_time != p.journey_time; } + bool operator >(const path_node& p) { return journey_time > p.journey_time; } + bool operator <(const path_node& p) { return journey_time < p.journey_time; } + bool operator <=(const path_node& p) { return journey_time <= p.journey_time; } + bool operator >=(const path_node& p) { return journey_time < p.journey_time; } + + // Necessary to work with the HOT queue. + uint32 get_distance() { return journey_time; } + }; + + // Data on paths to ultimate destinations + // @author: jamespetts + struct path + { + halthandle_t next_transfer; + uint16 journey_time; + + //TODO: Consider whether to add comfort + }; +#endif + + private: slist_tpl<tile_t> tiles; koord init_pos; // for halt without grounds, created during game initialisation - // List with all reachable destinations +#ifdef NEW_PATHING + // Table of all direct connexions to this halt, with routing information. + // Array: one entry per goods type. + quickstone_hashtable_tpl<haltestelle_t, connexion> connexions[8]; + + quickstone_hashtable_tpl<haltestelle_t, path> paths[8]; + +#else + // List with all reachable destinations (old method) vector_tpl<halthandle_t>* warenziele; +#endif // loest warte_menge ab // "solves wait mixes off" (Babelfish); "solves warte volume from" (Google) @@ -277,6 +343,31 @@ class haltestelle_t haltestelle_t(karte_t *welt, koord pos, spieler_t *sp); ~haltestelle_t(); + // Record of waiting times. Takes a list of the last 16 waiting times per type of goods. + // Getter method will need to average the waiting times. + // @author: jamespetts + quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>> waiting_times[8]; + +#ifdef NEW_PATHING + // Used for pathfinding. The list is stored on the heap so that it can be re-used + // if searching is aborted part-way through. + // @author: jamespetts + HOT_queue_tpl<path_node*> open_list; + + // Whether the search for the destination has completed: if so, the search will not + // re-run unless the results are stale. + bool search_complete; + + // When the connexions were last recalculated. Needed for checking whether they need to + // be recalculated again. + // @author: jamespetts + uint16 connexions_timestamp; + + // Likewise for paths + // @author: jamespetts + uint16 paths_timestamp; +#endif + public: /** * Called every 255 steps @@ -321,6 +412,17 @@ class haltestelle_t uint8 get_rebuild_destination_counter() const { return rebuilt_destination_counter; } + // New routing method: finds shortest route in *time*, not necessarily distance + // @ author: jamespetts + + // Direct connexions from this station. Replaces rebuild_destinations() + void rebuild_connexions(uint8 category); + + // Ultimate paths from this station. Packets searching for a path need only + // grab a pre-calculated path from the hashtable generated by this method. + void calculate_paths(halthandle_t goal, uint8 category); + + void rotate90( const sint16 y_size ); spieler_t *get_besitzer() const {return besitzer_p;} @@ -352,6 +454,7 @@ class haltestelle_t karte_t* get_welt() const { return welt; } +#ifndef NEW_PATHING /** * Kann die Ware nicht zum Ziel geroutet werden (keine Route), dann werden * Ziel und Zwischenziel auf koord::invalid gesetzt. @@ -366,6 +469,12 @@ class haltestelle_t * @author prissi */ int suche_route( ware_t &ware, koord *next_to_ziel, bool avoid_overcrowding ); +#else + // @author: jamespetts, although much is borrowed from suche_route + // Returns the journey time of the best possible route from this halt. Time == 65535 when there is no route. + uint16 find_route(ware_t &ware, uint16 journey_time); + uint16 find_route(ware_t &ware) { return find_route(ware, 65535); } +#endif int get_pax_enabled() const { return enables & PAX; } int get_post_enabled() const { return enables & POST; } @@ -470,7 +579,7 @@ class haltestelle_t * @return collected volume (Google) * @author Hj. Malthaner */ - ware_t hole_ab(const ware_besch_t *warentyp, uint32 menge, schedule_t *fpl); + ware_t hole_ab(const ware_besch_t *warentyp, uint32 menge, schedule_t *fpl, convoihandle_t cnv); /* liefert ware an. Falls die Ware zu wartender Ware dazugenommen * werden kann, kann ware_t gelöscht werden! D.h. man darf ware nach @@ -493,10 +602,18 @@ class haltestelle_t * wird von Fahrzeug aufgerufen, wenn dieses an der Haltestelle * gehalten hat. * @param typ der beförderte warentyp + * + * "of vehicle is called when this at the bus stop has. + * @ param type of product transported" (Google) + * * @author Hj. Malthaner */ void hat_gehalten(const ware_besch_t *warentyp, const schedule_t *fpl); + // Adding method for the new routing system. Equivalent to + // hat_gehalten with the old system. + void add_connexion(const ware_besch_t *type, const schedule_t *fpl, const convoihandle_t cnv, const linehandle_t line); + const grund_t *find_matching_position(waytype_t wt) const; /* checks, if there is an unoccupied loading bay for this kind of thing @@ -614,5 +731,77 @@ class haltestelle_t // Returns the proportion of unhappy people of the total of // happy and unhappy people. float get_unhappy_proportion(uint8 month) const { return financial_history[month][HALT_HAPPY] > 0 ? (float)financial_history[month][HALT_UNHAPPY] / (float)(financial_history[month][HALT_HAPPY] + financial_history[month][HALT_UNHAPPY]) : 0; } + + // Getting and setting average waiting times in minutes + // @author: jamespetts + uint16 get_average_waiting_time(halthandle_t halt, uint8 category) const + { + if(&waiting_times[category].get(halt) != NULL) + { + fixed_list_tpl<uint16, 16> times = waiting_times[category].get(halt); + const uint8 count = times.get_count(); + if(count > 0 && halt.is_bound()) + { + uint16 total_times = 0; + ITERATE(times,i) + { + total_times += times.get_element(i); + } + total_times /= count; + return total_times; + } + + return 0; + } + + return 0; + } + + void add_waiting_time(uint16 time, halthandle_t halt, uint8 category) + { + if(halt.is_bound()) + { + /*fixed_list_tpl<uint16, 16> tmp = *(new fixed_list_tpl<uint16, 16>); + if(!waiting_times[category].put(halt, tmp)) + { + delete &tmp; + }*/ + if(waiting_times[category].access(halt) == NULL) + { + fixed_list_tpl<uint16, 16> *tmp = new fixed_list_tpl<uint16, 16>; + waiting_times[category].put(halt, *tmp); + } + waiting_times[category].access(halt)->add_to_tail(time); + } + } + + inline uint16 get_waiting_minutes(uint32 waiting_ticks) const; + +#ifdef NEW_PATHING + quickstone_hashtable_tpl<haltestelle_t, connexion> get_connexions(uint8 c); + + // Finds the best path from here to the goal halt. + // Looks up the paths in the hashtable - if the table + // is not stale, and the path is in it, use that, or else + // search for a new path. + path get_path_to(halthandle_t goal, uint8 category); + + linehandle_t get_preferred_line(halthandle_t transfer, uint8 category) const; + convoihandle_t get_preferred_convoi(halthandle_t transfer, uint8 category) const; + + // Set to true if a schedule that serves this stop has changed since + // the connexions were last recalculated. Used for spreading the load + // of the recalculating connexions algorithm with the pathfinding + // algorithm. + // @author: jamespetts + bool reschedule; + + // Makes the paths recalculate, even if it would not otherwise be time for + // them to do so. Does this by making sure that the timestamp is lower than + // the counter. + // @author: jamespetts + void force_paths_stale(); +#endif + }; #endif diff --git a/simware.h b/simware.h index fda52d41b26..dfd79045730 100644 --- a/simware.h +++ b/simware.h @@ -105,12 +105,14 @@ class ware_t bool is_mail() const { return index==1; } bool is_freight() const { return index>2; } + // The time at which this packet arrived at the current station + // @author: jamespetts + sint64 arrival_time; + int operator==(const ware_t &w) { return menge == w.menge && zwischenziel == w.zwischenziel && - // No need to repeat the position checking if - // this will be done in can_merge_with. - (index < 3 || zielpos == w.zielpos) && + arrival_time == w.arrival_time && can_merge_with(w); } @@ -118,10 +120,21 @@ class ware_t // of metrics needed for merging. inline bool can_merge_with (const ware_t &w) const { + bool test_index = index == w.index; + bool test_zeil = ziel == w.ziel; + bool test_position = (index < 3 || zielpos == w.zielpos); + bool test_origin = origin == w.origin; + + bool test_total = index == w.index && + ziel == w.ziel && + // Only merge the destination *position* if the load is not freight + (index < 3 || zielpos == w.zielpos) && + origin == w.origin; + return index == w.index && ziel == w.ziel && // Only merge the destination *position* if the load is not freight - (index > 2 || zielpos == w.zielpos) && + (index < 3 || zielpos == w.zielpos) && origin == w.origin; } @@ -136,10 +149,6 @@ class ware_t inline bool same_destination(const ware_t &w) const { return index==w.get_index() && ziel==w.get_ziel() && (index<2 || zielpos==w.get_zielpos()); } - - // The time at which this packet arrived at the current station - // @author: jamespetts - sint64 arrival_time; }; #endif diff --git a/simworld.cc b/simworld.cc index d3590348e2d..1fd344338fb 100644 --- a/simworld.cc +++ b/simworld.cc @@ -1452,6 +1452,8 @@ karte_t::karte_t() : convoi_array(0), ausflugsziele(16), stadt(0), marker(0,0) scenario = NULL; msg = new message_t(this); + + base_pathing_counter = 0; } @@ -2388,6 +2390,8 @@ void karte_t::neuer_monat() cnv->new_month(); } + base_pathing_counter ++; + INT_CHECK("simworld 1701"); @@ -3400,6 +3404,11 @@ DBG_MESSAGE("karte_t::speichern(loadsave_t *file)", "saved players"); // finally a possible scenario scenario->rdwr( file ); + if(file->get_experimental_version() >= 2) + { + file->rdwr_short(base_pathing_counter, ""); + } + if(needs_redraw) { update_map(); } diff --git a/simworld.h b/simworld.h index 86b541b386a..ff91d441d07 100644 --- a/simworld.h +++ b/simworld.h @@ -388,6 +388,10 @@ class karte_t */ void distribute_groundobjs_cities(int new_cities, sint16 old_x, sint16 old_y); + // Used for detecting whether paths/connexions are stale. + // @author: jamespetts + uint16 base_pathing_counter; + public: /* reads height data from 8 or 25 bit bmp or ppm files * @return either pointer to heightfield (use delete [] for it) or NULL @@ -996,6 +1000,8 @@ class karte_t * @author Hansjörg Malthaner */ bool interactive(); + + uint16 get_base_pathing_counter() const { return base_pathing_counter; } }; #endif diff --git a/tpl/inthashtable_tpl.h b/tpl/inthashtable_tpl.h index 8bcadb1d654..28502d8d6de 100644 --- a/tpl/inthashtable_tpl.h +++ b/tpl/inthashtable_tpl.h @@ -9,7 +9,7 @@ /* - * Define the key characteristica for hashing integer types + * Define the key characteristics for hashing integer types */ template<class key_t> class inthash_tpl { diff --git a/tpl/ptrhashtable_tpl.h b/tpl/ptrhashtable_tpl.h index b84dcb2a0dd..e5a3f54b89b 100644 --- a/tpl/ptrhashtable_tpl.h +++ b/tpl/ptrhashtable_tpl.h @@ -9,7 +9,7 @@ #include <stdlib.h> /* - * Define the key characteristica for hashing pointers. For hashing the + * Define the key characteristics for hashing pointers. For hashing the * direct value is used. */ template<class key_t> diff --git a/tpl/vector_tpl.h b/tpl/vector_tpl.h index ffa505d9415..3b0d8137e44 100644 --- a/tpl/vector_tpl.h +++ b/tpl/vector_tpl.h @@ -204,6 +204,11 @@ template<class T> class vector_tpl count--; } + T& get_element(uint e) + { + return (*this)[e]; + } + T& operator [](uint i) { if (i >= count) { diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 43b01fda895..4bff252b25b 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -740,6 +740,7 @@ vehikel_t::unload_freight(halthandle_t halt) cnv->calc_revenue(iter.access_current()); // book delivered goods to destination + if(end_halt==halt) { // pax is always index 1 From c43c4181e2aae31aac9102bf98ed9acfe93d14bd Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 6 Apr 2009 22:28:34 +0100 Subject: [PATCH 49/61] New pathing now compiles. Still *UNTESTED*. --- dataobj/warenziel.cc | 2 + dataobj/warenziel.h | 3 +- gui/halt_detail.cc | 38 +++++++++++++--- gui/halt_list_frame.cc | 7 ++- player/ai_passenger.cc | 63 +++++++++++++++++++++----- simcity.cc | 50 +++++++++++++-------- simconvoi.cc | 28 ++++++------ simconvoi.h | 4 +- simhalt.cc | 93 ++++++++++++++++++++++++++------------- simhalt.h | 19 ++++++-- simplan.cc | 13 +++++- simware.cc | 16 ++++++- simware.h | 6 ++- simworld.cc | 2 + tpl/weighted_vector_tpl.h | 2 +- vehicle/simvehikel.cc | 3 +- 16 files changed, 260 insertions(+), 89 deletions(-) diff --git a/dataobj/warenziel.cc b/dataobj/warenziel.cc index 08389c301de..99e7af731d8 100644 --- a/dataobj/warenziel.cc +++ b/dataobj/warenziel.cc @@ -1,3 +1,4 @@ +#ifndef NEW_PATHING /* * Copyright (c) 1997 - 2001 Hansjörg Malthaner * @@ -41,3 +42,4 @@ warenziel_t::rdwr(loadsave_t *file) catg_index = warenbauer_t::get_info(tn)->get_catg_index(); } } +#endif diff --git a/dataobj/warenziel.h b/dataobj/warenziel.h index be426066fd0..e5200b0c70c 100644 --- a/dataobj/warenziel.h +++ b/dataobj/warenziel.h @@ -4,7 +4,7 @@ * This file is part of the Simutrans project under the artistic licence. * (see licence.txt) */ - +#ifndef NEW_PATHING #ifndef dataobj_warenziel_h #define dataobj_warenziel_h @@ -56,3 +56,4 @@ class warenziel_t }; #endif +#endif diff --git a/gui/halt_detail.cc b/gui/halt_detail.cc index 66693539f3c..67b7cb866b1 100644 --- a/gui/halt_detail.cc +++ b/gui/halt_detail.cc @@ -206,22 +206,41 @@ void halt_detail_t::halt_detail_info(cbuffer_t & buf) bool has_stops = false; - for (uint i=0; i<warenbauer_t::get_max_catg_index(); i++){ + for (uint i=0; i<warenbauer_t::get_max_catg_index(); i++) + { + +#ifdef NEW_PATHING + const quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion> *connexions = halt->get_connexions(i); +#else const vector_tpl<halthandle_t> *ziele = halt->get_warenziele(i); - if(!ziele->empty()) { + if(!ziele->empty()) + { +#endif + +#ifdef NEW_PATHING + if(!connexions->empty()) + { buf.append("\n"); offset_y += LINESPACE; - +#endif buf.append(" ·"); const ware_besch_t* info = warenbauer_t::get_info_catg_index(i); // If it is a special freight, we display the name of the good, otherwise the name of the category. buf.append(translator::translate(info->get_catg()==0?info->get_name():info->get_catg_name())); buf.append(":\n"); offset_y += LINESPACE; - +#ifdef NEW_PATHING + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*connexions); + while(iter.next()) + { + halthandle_t a_halt = iter.get_current_key(); + haltestelle_t::connexion cnx = iter.get_current_value(); +#else for( uint32 idx=0; idx < ziele->get_count(); idx++ ) { halthandle_t a_halt = (*ziele)[idx]; - if(a_halt.is_bound()) { +#endif + if(a_halt.is_bound()) + { has_stops = true; @@ -238,6 +257,15 @@ void halt_detail_t::halt_detail_info(cbuffer_t & buf) } buf.append("\n"); +#ifdef NEW_PATHING + buf.append("("); + buf.append(cnx.journey_time); + buf.append(translator::translate(" mins. travelling")); + buf.append(", "); + buf.append(cnx.waiting_time); + buf.append(translator::translate(" mins. waiting")); + buf.append("\n"); +#endif offset_y += LINESPACE; } } diff --git a/gui/halt_list_frame.cc b/gui/halt_list_frame.cc index 37ce7d4521b..515442abba7 100644 --- a/gui/halt_list_frame.cc +++ b/gui/halt_list_frame.cc @@ -145,8 +145,13 @@ bool halt_list_frame_t::passes_filter(halthandle_t halt) } if(!ok && get_filter(ohneverb_filter)) { ok = true; - for (uint8 i = 0; i<warenbauer_t::get_max_catg_index(); i++){ + for (uint8 i = 0; i<warenbauer_t::get_max_catg_index(); i++) + { +#ifdef NEW_PATHING + ok &= halt->get_connexions(i)->empty(); //only display stations with NO connexion +#else ok &= halt->get_warenziele(i)->empty(); //only display stations with NO connection +#endif } } if(!ok) { diff --git a/player/ai_passenger.cc b/player/ai_passenger.cc index 3991344166f..0a23b1e8ffb 100755 --- a/player/ai_passenger.cc +++ b/player/ai_passenger.cc @@ -214,9 +214,18 @@ bool ai_passenger_t::create_water_transport_vehikel(const stadt_t* start_stadt, start_connect_hub = start_hub; start_hub = halthandle_t(); // is there already one harbour next to this one? - for( uint32 i=0; i<start_connect_hub->get_warenziele(0)->get_count(); i++ ) { +#ifdef NEW_PATHING + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*start_connect_hub->get_connexions(0)); + while(iter.next()) + { + halthandle_t h = iter.get_current_key(); +#else + for(uint32 i = 0; i < start_connect_hub->get_warenziele(0)->get_count(); i++) + { halthandle_t h = (*(start_connect_hub->get_warenziele(0)))[i]; - if( h->get_station_type()&haltestelle_t::dock ) { +#endif + if( h->get_station_type()&haltestelle_t::dock ) + { start_hub = h; break; } @@ -243,9 +252,18 @@ bool ai_passenger_t::create_water_transport_vehikel(const stadt_t* start_stadt, end_connect_hub = end_hub; end_hub = halthandle_t(); // is there already one harbour next to this one? - for( uint32 i=0; i<end_connect_hub->get_warenziele(0)->get_count(); i++ ) { +#ifdef NEW_PATHING + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*end_connect_hub->get_connexions(0)); + while(iter.next()) + { + halthandle_t h = iter.get_current_key(); +#else + for( uint32 i=0; i<end_connect_hub->get_warenziele(0)->get_count(); i++ ) + { halthandle_t h = (*(end_connect_hub->get_warenziele(0)))[i]; - if( h->get_station_type()&haltestelle_t::dock ) { +#endif + if( h->get_station_type()&haltestelle_t::dock ) + { start_hub = h; break; } @@ -643,8 +661,15 @@ bool ai_passenger_t::create_air_transport_vehikel(const stadt_t *start_stadt, co start_connect_hub = start_hub; start_hub = halthandle_t(); // is there already one airport next to this town? +#ifdef NEW_PATHING + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*start_connect_hub->get_connexions(0)); + while(iter.next()) + { + halthandle_t h = iter.get_current_key(); +#else for( uint32 i=0; i<start_connect_hub->get_warenziele(0)->get_count(); i++ ) { halthandle_t h = (*(start_connect_hub->get_warenziele(0)))[i]; +#endif if( h->get_station_type()&haltestelle_t::airstop ) { start_hub = h; break; @@ -672,9 +697,18 @@ bool ai_passenger_t::create_air_transport_vehikel(const stadt_t *start_stadt, co end_connect_hub = end_hub; end_hub = halthandle_t(); // is there already one airport next to this town? - for( uint32 i=0; i<end_connect_hub->get_warenziele(0)->get_count(); i++ ) { +#ifdef NEW_PATHING + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*end_connect_hub->get_connexions(0)); + while(iter.next()) + { + halthandle_t h = iter.get_current_key(); +#else + for( uint32 i=0; i<end_connect_hub->get_warenziele(0)->get_count(); i++ ) + { halthandle_t h = (*(end_connect_hub->get_warenziele(0)))[i]; - if( h->get_station_type()&haltestelle_t::airstop ) { +#endif + if( h->get_station_type()&haltestelle_t::airstop ) + { start_hub = h; break; } @@ -712,14 +746,23 @@ bool ai_passenger_t::create_air_transport_vehikel(const stadt_t *start_stadt, co } if(!end_hub.is_bound()) { end_hub = build_airport(end_stadt, end_airport, true); - if(!end_hub.is_bound()) { - if(start_hub->get_warenziele_passenger()->get_count()==0) { + if(!end_hub.is_bound()) + { +#ifdef NEW_PATHING + if(start_hub->get_connexions(0)->empty()) + { +#else + if(start_hub->get_warenziele_passenger()->get_count()==0) + { +#endif // remove airport busstop welt->lookup_kartenboden(start_hub->get_basis_pos())->remove_everything_from_way( this, road_wt, ribi_t::keine ); koord center = start_hub->get_basis_pos() + koord( welt->lookup_kartenboden(start_hub->get_basis_pos())->get_weg_ribi_unmasked( air_wt ) ); // now the remaining taxi-/runways - for( sint16 y=center.y-1; y<=center.y+1; y++ ) { - for( sint16 x=center.x-1; x<=center.x+1; x++ ) { + for( sint16 y=center.y-1; y<=center.y+1; y++ ) + { + for( sint16 x=center.x-1; x<=center.x+1; x++ ) + { welt->lookup_kartenboden(koord(x,y))->remove_everything_from_way( this, air_wt, ribi_t::keine ); } } diff --git a/simcity.cc b/simcity.cc index c03a9daede6..b638cef97a4 100644 --- a/simcity.cc +++ b/simcity.cc @@ -1630,11 +1630,13 @@ void stadt_t::step_passagiere() const halthandle_t* halt_list = plan->get_haltlist(); // suitable start search - fixed_list_tpl<halthandle_t*, 5> start_halts; - for (uint h = 0; h < plan->get_haltlist_count(); h++) { + vector_tpl<halthandle_t> start_halts(2); + for (uint h = 0; h < plan->get_haltlist_count(); h++) + { halthandle_t halt = halt_list[h]; - if (halt->is_enabled(wtyp) && !halt->is_overcrowded(wtyp->get_catg_index())) { - if(halt.is_bound() && !start_halts.add_to_tail_no_overwrite(&halt)) + if (halt->is_enabled(wtyp) && !halt->is_overcrowded(wtyp->get_catg_index())) + { + if(halt.is_bound() && !start_halts.append_unique(halt)) { // Stops looking for new halts if we have found too many to fit // into the fixed size list. Number limited to keep the speed up. @@ -1742,7 +1744,7 @@ void stadt_t::step_passagiere() { if(start_halts.get_count() > 0) { - halthandle_t start_halt = *start_halts.get_element(0); + halthandle_t start_halt = start_halts.get_element(0); if(start_halt.is_bound()) { erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, destinations[current_destination].location); @@ -1766,10 +1768,10 @@ void stadt_t::step_passagiere() ziel_count++; for(int i = start_halts.get_count(); i >= 0; i--) { - if(start_halts.get_count() > i && halt == *start_halts.get_element(i)) + if(start_halts.get_count() > i && halt == start_halts.get_element(i)) { can_walk_ziel = true; - start_halt = *start_halts.get_element(i); + start_halt = start_halts.get_element(i); } } break; // because we found at least one valid step ... @@ -1783,7 +1785,7 @@ void stadt_t::step_passagiere() merke_passagier_ziel(destinations[current_destination].location, COL_DARK_ORANGE); if(start_halts.get_count() > 0) { - halthandle_t current_halt = *start_halts.get_element(0); + halthandle_t current_halt = start_halts.get_element(0); current_halt->add_pax_no_route(pax_left_to_do); } #ifdef NEW_PATHING @@ -1862,9 +1864,9 @@ void stadt_t::step_passagiere() { break; } - halthandle_t current_halt = *start_halts[i]; + halthandle_t current_halt = start_halts[i]; #ifdef NEW_PATHING - uint16 current_journey_time = current_halt->find_route(ware, best_journey_time); + uint16 current_journey_time = current_halt->find_route(pax, best_journey_time); if(current_journey_time < best_journey_time) { best_journey_time = current_journey_time; @@ -1896,9 +1898,10 @@ void stadt_t::step_passagiere() best_destination[1] = pax.get_zwischenziel(); best_destination[2] = tmp[2]; } +#endif } -#endif + #ifdef NEW_PATHING if(route_good) { @@ -1990,9 +1993,10 @@ void stadt_t::step_passagiere() // *road* transport. // This is the speed bonus calculation, without reference to price. - const uint16 average_speed = (60 * distance) / (best_journey_time * (1.0 - welt->get_einstellungen()->get_journey_time_multiplier()); + const ware_besch_t* passengers = pax.get_besch(); + const uint16 average_speed = (60 * distance) / (best_journey_time * (1.0 - welt->get_einstellungen()->get_journey_time_multiplier())); const sint32 ref_speed = welt->get_average_speed(road_wt); - const uint16 speed_bonus_rating = calc_adjusted_speed_bonus(goods->get_speed_bonus(), distance); + const uint16 speed_bonus_rating = convoi_t::calc_adjusted_speed_bonus(passengers->get_speed_bonus(), distance); const sint32 speed_base = (100 * average_speed) / ref_speed - 100; const float base_bonus = (float)speed_base * ((float)speed_bonus_rating / 100.0); //base_bonus should be 1 if the average speed is the same as the bonus speed. @@ -2056,7 +2060,7 @@ void stadt_t::step_passagiere() #endif //Secondly, the number of unhappy passengers at the start station compared with the number of happy passengers. - float unhappy_factor = start_halt->get_unhappy_proportion; + float unhappy_factor = start_halt->get_unhappy_proportion(0); /*float unhappy_total = start_halt->get_pax_unhappy() - start_halt->get_pax_happy(); float unhappy_factor; if(unhappy_total > 0) @@ -2099,10 +2103,12 @@ void stadt_t::step_passagiere() city_history_year[0][history_type] += pax.menge; city_history_month[0][history_type] += pax.menge; - } else { + } + else + { if(start_halts.get_count() > 0) { - start_halt = *start_halts.get_element(0); //If there is no route, it does not matter where passengers express their unhappiness. + start_halt = start_halts.get_element(0); //If there is no route, it does not matter where passengers express their unhappiness. #ifndef NEW_PATHING if( route_result == haltestelle_t::ROUTE_OVERCROWDED ) { @@ -2158,8 +2164,13 @@ void stadt_t::step_passagiere() for (uint i = 0; i < plan->get_haltlist_count(); i++) { halthandle_t test_halt = halt_list[i]; - if (test_halt->is_enabled(wtyp) && (start_halt==test_halt || test_halt->get_warenziele(wtyp->get_catg_index())->is_contained(start_halt))) - { +#ifdef NEW_PATHING + if(test_halt->is_enabled(wtyp) && (start_halt==test_halt || test_halt->get_connexions(wtyp->get_catg_index())->access(start_halt) != NULL)) + { +#else + if (test_halt->is_enabled(wtyp) && (start_halt==test_halt || test_halt->get_warenziele(wtyp->get_catg_index())->is_contained(start_halt))) + { +#endif found = true; start_halt = test_halt; break; @@ -2178,7 +2189,9 @@ void stadt_t::step_passagiere() return_pax.set_zielpos(k); return_pax.set_ziel(start_halt); return_pax.set_zwischenziel(welt->lookup(return_zwischenziel)->get_halt()); +#ifndef NEW_PATHING return_pax.set_journey_steps(best_journey_steps); +#endif return_pax.arrival_time = welt->get_zeit_ms(); ret_halt->starte_mit_route(return_pax); @@ -2200,6 +2213,7 @@ void stadt_t::step_passagiere() { // return halt crowded ret_halt->add_pax_unhappy(pax_left_to_do); + if(has_private_car) { //Must use private car, since the halt is crowded. diff --git a/simconvoi.cc b/simconvoi.cc index 764506616e8..c1f55abc5d6 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -234,11 +234,11 @@ DBG_MESSAGE("convoi_t::~convoi_t()", "destroying %d, %p", self.get_id(), this); if(fpl->get_count()>0 && !line.is_bound() ) { // New method - recalculate as necessary - ITERATE(fpl, j) + ITERATE_PTR(fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); tmp_halt->reschedule = true; - tmp_halt->force_paths_stale); + tmp_halt->force_paths_stale(); } #else // Old method - brute force @@ -1301,11 +1301,11 @@ void convoi_t::start() #ifdef NEW_PATHING // New method - recalculate as necessary - ITERATE(fpl, j) + ITERATE_PTR(fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); tmp_halt->reschedule = true; - tmp_halt->force_paths_stale); + tmp_halt->force_paths_stale(); } #else @@ -1563,18 +1563,18 @@ bool convoi_t::set_schedule(schedule_t * f) if(!line.is_bound() && old_state != INITIAL) { // New method - recalculate as necessary - ITERATE(fpl, j) + ITERATE_PTR(fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); tmp_halt->reschedule = true; - tmp_halt->force_paths_stale); + tmp_halt->force_paths_stale(); } - ITERATE(f, k) + ITERATE_PTR(f, k) { - halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); + halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[k].pos); tmp_halt->reschedule = true; - tmp_halt->force_paths_stale); + tmp_halt->force_paths_stale(); } } #endif @@ -3198,7 +3198,7 @@ const uint8 convoi_t::calc_tolerable_comfort(uint16 journey_minutes) const return (proportion * (comfort_long - comfort_median_long)) + comfort_median_long; } -const uint16 convoi_t::calc_adjusted_speed_bonus(uint16 base_bonus, uint32 distance) const +const uint16 convoi_t::calc_adjusted_speed_bonus(uint16 base_bonus, uint32 distance) { const uint32 min_distance = welt->get_einstellungen()->get_min_bonus_max_distance(); if(distance <= min_distance) @@ -3497,11 +3497,11 @@ void convoi_t::set_line(linehandle_t org_line) #ifdef NEW_PATHING // New method - recalculate on demand - ITERATE(fpl, j) + ITERATE_PTR(fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); tmp_halt->reschedule = true; - tmp_halt->force_paths_stale); + tmp_halt->force_paths_stale(); } #else // Old method - brute force @@ -3513,11 +3513,11 @@ void convoi_t::set_line(linehandle_t org_line) schedule_t *new_fpl= org_line->get_schedule()->copy(); set_schedule(new_fpl); - ITERATE(new_fpl, j) + ITERATE_PTR(new_fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); tmp_halt->reschedule = true; - tmp_halt->force_paths_stale); + tmp_halt->force_paths_stale(); } line->add_convoy(self); diff --git a/simconvoi.h b/simconvoi.h index 936f974ea54..ad182e184f8 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -411,7 +411,6 @@ class convoi_t : public sync_steppable, public overtaker_t uint16 rolling_average_count[MAX_CONVOI_COST]; // @author: jamespetts - const uint16 calc_adjusted_speed_bonus(uint16 base_bonus, uint32 distance) const; const uint8 calc_tolerable_comfort(uint16 journey_minutes) const; @@ -924,6 +923,9 @@ class convoi_t : public sync_steppable, public overtaker_t // vehicle in the convoy. // @author: jamespetts void calc_revenue(ware_t &ware); + + // @author: jamespetts + static const uint16 calc_adjusted_speed_bonus(uint16 base_bonus, uint32 distance); }; #endif diff --git a/simhalt.cc b/simhalt.cc index 173dab365c9..072161f7cc4 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -48,7 +48,9 @@ #include "dataobj/loadsave.h" #include "dataobj/translator.h" #include "dataobj/umgebung.h" +#ifndef NEW_PATHING #include "dataobj/warenziel.h" +#endif #include "dings/gebaeude.h" #include "dings/label.h" @@ -247,7 +249,11 @@ haltestelle_t::haltestelle_t(karte_t* wl, loadsave_t* file) pax_no_route = 0; waren = (vector_tpl<ware_t> **)calloc( warenbauer_t::get_max_catg_index(), sizeof(vector_tpl<ware_t> *) ); +#ifdef NEW_PATHING + iterations = 0; +#else warenziele = new vector_tpl<halthandle_t>[ warenbauer_t::get_max_catg_index() ]; +#endif status_color = COL_YELLOW; @@ -291,7 +297,11 @@ haltestelle_t::haltestelle_t(karte_t* wl, koord k, spieler_t* sp) rebuilt_destination_counter = reroute_counter; waren = (vector_tpl<ware_t> **)calloc( warenbauer_t::get_max_catg_index(), sizeof(vector_tpl<ware_t> *) ); +#ifdef NEW_PATHING + iterations = 0; +#else warenziele = new vector_tpl<halthandle_t>[ warenbauer_t::get_max_catg_index() ]; +#endif pax_happy = 0; pax_unhappy = 0; @@ -304,10 +314,11 @@ haltestelle_t::haltestelle_t(karte_t* wl, koord k, spieler_t* sp) if(welt->ist_in_kartengrenzen(k)) { welt->access(k)->set_halt(self); } - +#ifdef NEW_PATHING connexions_timestamp = 0; paths_timestamp = 0; reschedule = false; +#endif } @@ -385,7 +396,9 @@ haltestelle_t::~haltestelle_t() } } free( waren ); +#ifndef NEW_PATHING delete[] warenziele; +#endif // routes may have changed without this station ... verbinde_fabriken(); @@ -831,7 +844,7 @@ void haltestelle_t::reroute_goods() } INT_CHECK( "simhalt.cc 489" ); - +#ifndef NEW_PATHING // delete, if nothing connects here if (new_warray->empty()) { if( warenziele[i].empty() ) { @@ -844,6 +857,7 @@ void haltestelle_t::reroute_goods() // replace the array delete waren[i]; waren[i] = new_warray; +#endif } } // likely the display must be updated after this @@ -893,7 +907,7 @@ haltestelle_t::remove_fabriken(fabrik_t *fab) } - +#ifndef NEW_PATHING void haltestelle_t::hat_gehalten(const ware_besch_t *type, const schedule_t *fpl) { if(type != warenbauer_t::nichts) { @@ -920,7 +934,7 @@ void haltestelle_t::hat_gehalten(const ware_besch_t *type, const schedule_t *fpl } } -#ifdef NEW_PATHING +#else void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fpl, const convoihandle_t cnv, const linehandle_t line) { if(type != warenbauer_t::nichts) @@ -991,16 +1005,18 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp linehandle_t haltestelle_t::get_preferred_line(halthandle_t transfer, uint8 category) const { linehandle_t best_line = connexions[category].get(transfer).best_line; - return linehandle_t; + return best_line; } -convoihandle_t haltestelle_t::get_preferred_convoi(halthandle_t transfer, uint8 category) const +convoihandle_t haltestelle_t::get_preferred_convoy(halthandle_t transfer, uint8 category) const { convoihandle_t best_convoy = connexions[category].get(transfer).best_convoy; return best_convoy; } -#else +#endif + +#ifndef NEW_PATHING /** * Rebuilds the list of reachable destinations @@ -1075,9 +1091,8 @@ void haltestelle_t::rebuild_destinations() } } } -#endif -#ifdef NEW_PATHING +#else //@author: jamespetts (although much is taken from the original rebuild_destinations()) void haltestelle_t::rebuild_connexions(uint8 category) @@ -1199,14 +1214,17 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) paths_timestamp = welt->get_base_pathing_counter(); } - uint16 iterations = 0; - - path_node* starting_node; - starting_node->halt = self; - starting_node->link = NULL; - starting_node->journey_time = 0; // Takes 0 time to stay in the same place - - open_list.insert(starting_node); + if(open_list.get_count() < 1) + { + // Only reset the list if it is empty, so as to allow for re-using the open + // list on subsequent occasions of finding a path. + iterations = 0; + path_node* starting_node; + starting_node->halt = self; + starting_node->link = NULL; + starting_node->journey_time = 0; // Takes 0 time to stay in the same place + open_list.insert(starting_node); + } const uint16 max_transfers = welt->get_einstellungen()->get_max_transfers(); @@ -1222,8 +1240,8 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) // not found, is searched for, unless the index is stale. return; } - quickstone_hashtable_tpl<haltestelle_t, connexion> current_connexions = current_node->halt->get_connexions(category); - quickstone_hashtable_iterator_tpl<haltestelle_t, connexion> iter(current_connexions); + quickstone_hashtable_tpl<haltestelle_t, connexion> *current_connexions = current_node->halt->get_connexions(category); + quickstone_hashtable_iterator_tpl<haltestelle_t, connexion> iter(*current_connexions); while(iter.next()) { path_node* new_node; @@ -1278,7 +1296,7 @@ haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category return destination_path; } -quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion> haltestelle_t::get_connexions(uint8 c) +quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion>* haltestelle_t::get_connexions(uint8 c) { if(reschedule || paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) { @@ -1286,7 +1304,7 @@ quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion> haltestelle_t: rebuild_connexions(c); } - return connexions[c]; + return &connexions[c]; } void haltestelle_t::force_paths_stale() @@ -1343,9 +1361,9 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim uint16 best_destination; // Now, find the best route from here. - ITERATE(zeil_list,i) + ITERATE(ziel_list,i) { - path test_path = get_path_to(zeil_list[i], ware.get_catg()); + path test_path = get_path_to(ziel_list[i], ware.get_catg()); if(test_path.journey_time < journey_time) { journey_time = test_path.journey_time; @@ -1357,8 +1375,8 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim { // If we are comparing this with other routes from different start halts, // only set the details if it is the best route so far. - ware.set_ziel(zeil_list[best_destination]); - path final_path = get_path_to(zeil_list[best_destination], ware.get_catg(); + ware.set_ziel(ziel_list[best_destination]); + path final_path = get_path_to(ziel_list[best_destination], ware.get_catg()); ware.set_zwischenziel(final_path.next_transfer); return final_path.journey_time; } @@ -1366,7 +1384,9 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim return journey_time; } -#else +#endif + +#ifndef NEW_PATHING /* HNode is used for route search */ @@ -1760,7 +1780,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t { if(cnv->get_line().is_bound()) { - linehandle_t best_line = halt->get_preferred_line(ware.get_zwischenziel(), ware.get_catg(); + linehandle_t best_line = get_preferred_line(tmp.get_zwischenziel(), tmp.get_catg()); if(!best_line.is_bound() && best_line == cnv->get_line()) { continue; @@ -1768,7 +1788,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t } else { - convoihandle_t best_convoy = halt->get_preferred_convoy(ware.get_zwischenziel(), ware.get_catg(); + convoihandle_t best_convoy = get_preferred_convoy(tmp.get_zwischenziel(), tmp.get_catg()); if(!best_convoy.is_bound() && best_convoy == cnv) { continue; @@ -2563,11 +2583,24 @@ void haltestelle_t::rdwr(loadsave_t *file) // old games save the list with stations // however, we have to rebuilt them anyway for the new format - if(file->get_version()<99013) { + if(file->get_version()<99013) + { file->rdwr_short(count, " "); - for(int i=0; i<count; i++) { + + for(int i=0; i<count; i++) + { +#ifndef NEW_PATHING warenziel_t wz (file); +#else + if(file->is_loading()) + { + // Dummy loading and saving to maintain backwards compatibility + char dummy[256]; + file->rdwr_str(dummy,256); + } +#endif } + } } diff --git a/simhalt.h b/simhalt.h index 0a22c7bd1ad..63fc7691bff 100644 --- a/simhalt.h +++ b/simhalt.h @@ -220,7 +220,7 @@ class haltestelle_t bool operator >=(const path_node& p) { return journey_time < p.journey_time; } // Necessary to work with the HOT queue. - uint32 get_distance() { return journey_time; } + inline uint32 get_distance() { return journey_time; } }; // Data on paths to ultimate destinations @@ -247,6 +247,10 @@ class haltestelle_t quickstone_hashtable_tpl<haltestelle_t, path> paths[8]; + // The number of iterations of paths currently traversed. Used for + // detecting when max_transfers has been reached. + uint16 iterations; + #else // List with all reachable destinations (old method) vector_tpl<halthandle_t>* warenziele; @@ -403,15 +407,18 @@ class haltestelle_t void verbinde_fabriken(); void remove_fabriken(fabrik_t *fab); +#ifndef NEW_PATHING /** * Rebuilds the list of reachable destinations * * @author Hj. Malthaner */ void rebuild_destinations(); +#endif uint8 get_rebuild_destination_counter() const { return rebuilt_destination_counter; } +#ifdef NEW_PATHING // New routing method: finds shortest route in *time*, not necessarily distance // @ author: jamespetts @@ -422,6 +429,7 @@ class haltestelle_t // grab a pre-calculated path from the hashtable generated by this method. void calculate_paths(halthandle_t goal, uint8 category); +#endif void rotate90( const sint16 y_size ); @@ -432,11 +440,13 @@ class haltestelle_t bool make_public_and_join( spieler_t *sp ); +#ifndef NEW_PATHING const vector_tpl<halthandle_t> *get_warenziele_passenger() const {return warenziele;} const vector_tpl<halthandle_t> *get_warenziele_mail() const {return warenziele+1;} // returns the matchin warenziele const vector_tpl<halthandle_t> *get_warenziele(uint8 catg_index) const {return warenziele+catg_index;} +#endif const slist_tpl<fabrik_t*>& get_fab_list() const { return fab_list; } @@ -598,6 +608,7 @@ class haltestelle_t uint32 liefere_an(ware_t ware); uint32 starte_mit_route(ware_t ware); +#ifndef NEW_PATHING /** * wird von Fahrzeug aufgerufen, wenn dieses an der Haltestelle * gehalten hat. @@ -609,10 +620,12 @@ class haltestelle_t * @author Hj. Malthaner */ void hat_gehalten(const ware_besch_t *warentyp, const schedule_t *fpl); +#else // Adding method for the new routing system. Equivalent to // hat_gehalten with the old system. void add_connexion(const ware_besch_t *type, const schedule_t *fpl, const convoihandle_t cnv, const linehandle_t line); +#endif const grund_t *find_matching_position(waytype_t wt) const; @@ -778,7 +791,7 @@ class haltestelle_t inline uint16 get_waiting_minutes(uint32 waiting_ticks) const; #ifdef NEW_PATHING - quickstone_hashtable_tpl<haltestelle_t, connexion> get_connexions(uint8 c); + quickstone_hashtable_tpl<haltestelle_t, connexion>* get_connexions(uint8 c); // Finds the best path from here to the goal halt. // Looks up the paths in the hashtable - if the table @@ -787,7 +800,7 @@ class haltestelle_t path get_path_to(halthandle_t goal, uint8 category); linehandle_t get_preferred_line(halthandle_t transfer, uint8 category) const; - convoihandle_t get_preferred_convoi(halthandle_t transfer, uint8 category) const; + convoihandle_t get_preferred_convoy(halthandle_t transfer, uint8 category) const; // Set to true if a schedule that serves this stop has changed since // the connexions were last recalculated. Used for spreading the load diff --git a/simplan.cc b/simplan.cc index 7966fb8aaca..5855e44584c 100644 --- a/simplan.cc +++ b/simplan.cc @@ -523,15 +523,26 @@ void planquadrat_t::add_to_haltlist(halthandle_t halt) const koord pos = get_kartenboden()->get_pos().get_2d(); // exact position does matter only for passenger/mail transport - if(sp!=NULL && halt->get_warenziele_passenger()->get_count()+halt->get_warenziele_mail()->get_count()>0 && halt_list_count>0 ) { +#ifdef NEW_PATHING + if(sp != NULL && !(halt->get_connexions(0)->empty() && halt->get_connexions(1)->empty()) && halt_list_count > 0) + { +#else + if(sp!=NULL && halt->get_warenziele_passenger()->get_count()+halt->get_warenziele_mail()->get_count()>0 && halt_list_count>0 ) + { +#endif halt_list_remove(halt); // since only the first one gets all the passengers, we want the closest one for passenger transport to be on top for(insert_pos=0; insert_pos<halt_list_count; insert_pos++) { // not a passenger KI or other is farer away +#ifdef NEW_PATHING + if (halt_list[insert_pos]->get_connexions(0)->empty() && halt_list[insert_pos]->get_connexions(1)->empty() || + abs_distance(halt_list[insert_pos]->get_next_pos(pos), pos) > abs_distance(halt->get_next_pos(pos), pos)) +#else if( halt_list[insert_pos]->get_warenziele_passenger()->get_count()+halt_list[insert_pos]->get_warenziele_mail()->get_count()==0 || abs_distance(halt_list[insert_pos]->get_next_pos(pos), pos) > abs_distance(halt->get_next_pos(pos), pos)) +#endif { halt_list_insert_at( halt, insert_pos ); return; diff --git a/simware.cc b/simware.cc index 88dfd2bbadd..4b49962639f 100644 --- a/simware.cc +++ b/simware.cc @@ -32,7 +32,9 @@ ware_t::ware_t() : ziel(), zwischenziel(), zielpos(-1, -1) menge = 0; index = 0; accumulated_distance = 0; +#ifndef NEW_PATHING journey_steps = 0; +#endif arrival_time = 0; } @@ -42,8 +44,10 @@ ware_t::ware_t(const ware_besch_t *wtyp) : ziel(), zwischenziel(), zielpos(-1, - //This constructor is called from simcity.cc menge = 0; index = wtyp->get_index(); - accumulated_distance = 0; +#ifndef NEW_PATHING journey_steps = 0; +#endif + accumulated_distance = 0; arrival_time = 0; } @@ -55,7 +59,9 @@ ware_t::ware_t(const ware_besch_t *wtyp, halthandle_t o) : ziel(), zwischenziel( index = wtyp->get_index(); origin = o; accumulated_distance = 0; +#ifndef NEW_PATHING journey_steps = 0; +#endif arrival_time = 0; } @@ -167,13 +173,21 @@ ware_t::rdwr(karte_t *welt,loadsave_t *file) if(file->get_experimental_version() >= 2) { file->rdwr_long(accumulated_distance, ""); +#ifdef NEW_PATHING + // Was journey steps + uint8 dummy; + file->rdwr_byte(dummy, ""); +#else file->rdwr_byte(journey_steps, ""); +#endif file->rdwr_longlong(arrival_time, ""); } else { accumulated_distance = 0; +#ifndef NEW_PATHING journey_steps = 0; +#endif arrival_time = 0; } } diff --git a/simware.h b/simware.h index dfd79045730..1322f13fc25 100644 --- a/simware.h +++ b/simware.h @@ -48,10 +48,11 @@ class ware_t // "the final target position, which is on behalf not the goal stop position" koord zielpos; +#ifndef NEW_PATHING //@author: jamespetts //The number of remaining steps on this packet's journey. - //TODO: Remove this variable when the new system is implemented. uint8 journey_steps; +#endif // @author: jamespetts // The distance travelled so far this leg of the journey. @@ -138,9 +139,10 @@ class ware_t origin == w.origin; } - +#ifndef NEW_PATHING uint8 get_journey_steps() { return journey_steps; } void set_journey_steps(uint8 value) { journey_steps = value; } +#endif int operator!=(const ware_t &w) { return !(*this == w); } diff --git a/simworld.cc b/simworld.cc index 1fd344338fb..9db3f643888 100644 --- a/simworld.cc +++ b/simworld.cc @@ -3851,7 +3851,9 @@ DBG_MESSAGE("karte_t::laden()", "%d ways loaded",weg_t::get_alle_wege().get_coun if((hnr++%32)==0) { display_progress(get_groesse_y()+48+stadt.get_count()+128+(hnr*80)/hmax, get_groesse_y()+256+stadt.get_count()); } +#ifndef NEW_PATHING iter.get_current()->rebuild_destinations(); +#endif } #if 0 diff --git a/tpl/weighted_vector_tpl.h b/tpl/weighted_vector_tpl.h index 2792cd73574..33615afea02 100644 --- a/tpl/weighted_vector_tpl.h +++ b/tpl/weighted_vector_tpl.h @@ -6,7 +6,7 @@ #endif #ifndef ITERATE_PTR -#define ITERATE_PTR(collection,enumerator) for(uint16 enumerator = 0; enumerator < collection->get_count(); ienumerator++) +#define ITERATE_PTR(collection,enumerator) for(uint16 enumerator = 0; enumerator < collection->get_count(); enumerator++) #endif #include "../macros.h" diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 4bff252b25b..c075949b6fa 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -787,7 +787,8 @@ bool vehikel_t::load_freight(halthandle_t halt, bool overcrowd) const uint16 hinein = (besch->get_zuladung() - total_freight) + (overcrowd ? besch->get_overcrowded_capacity() : 0); //hinein = inside (Google) - ware_t ware = halt->hole_ab(besch->get_ware(), hinein, fpl); + convoihandle_t convoy(cnv); + ware_t ware = halt->hole_ab(besch->get_ware(), hinein, fpl, convoy); if(ware.menge==0) { From 23badbe69833e504e0515fb45e708d8ee827df03 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Fri, 10 Apr 2009 22:46:52 +0100 Subject: [PATCH 50/61] New routing system - initial round of debugging finished. Has passed basic testing on reliability and performance, but needs more extensive testing. --- dataobj/route.h | 4 +- gui/halt_detail.cc | 7 +- simcity.cc | 21 ++-- simhalt.cc | 231 +++++++++++++++++++++++++++++++++++------- simhalt.h | 34 +++---- simmain.cc | 6 +- tpl/hashtable_tpl.h | 24 +++++ tpl/minivec_tpl.h | 10 +- vehicle/simvehikel.cc | 1 + 9 files changed, 259 insertions(+), 79 deletions(-) diff --git a/dataobj/route.h b/dataobj/route.h index 4c0e1e856e9..d30f93b978f 100644 --- a/dataobj/route.h +++ b/dataobj/route.h @@ -49,8 +49,8 @@ class route_t // next one only needed for sorted_heap_tpl inline bool operator == (const ANode k) const { return f==k.f && g==k.g; } // next two only needed for HOT-queues - inline bool is_matching(const ANode &l) const { return gr==l.gr; } - inline uint32 get_distance() const { return f; } + //inline bool is_matching(const ANode &l) const { return gr==l.gr; } + //inline uint32 get_distance() const { return f; } }; static ANode *nodes; diff --git a/gui/halt_detail.cc b/gui/halt_detail.cc index 67b7cb866b1..9a23550edc4 100644 --- a/gui/halt_detail.cc +++ b/gui/halt_detail.cc @@ -263,10 +263,13 @@ void halt_detail_t::halt_detail_info(cbuffer_t & buf) buf.append(translator::translate(" mins. travelling")); buf.append(", "); buf.append(cnx.waiting_time); - buf.append(translator::translate(" mins. waiting")); + buf.append(translator::translate(" mins. waiting)")); buf.append("\n"); -#endif + + offset_y += 2 * LINESPACE; +#else offset_y += LINESPACE; +#endif } } } diff --git a/simcity.cc b/simcity.cc index b638cef97a4..be30e4db37a 100644 --- a/simcity.cc +++ b/simcity.cc @@ -1620,7 +1620,8 @@ void stadt_t::step_passagiere() max(1,(gb->get_tile()->get_besch()->get_post_level() + 5) >> 4); // create pedestrians in the near area? - if (welt->get_einstellungen()->get_random_pedestrians() && wtyp == warenbauer_t::passagiere) { + if (welt->get_einstellungen()->get_random_pedestrians() && wtyp == warenbauer_t::passagiere) + { haltestelle_t::erzeuge_fussgaenger(welt, gb->get_pos(), num_pax); } @@ -1636,12 +1637,7 @@ void stadt_t::step_passagiere() halthandle_t halt = halt_list[h]; if (halt->is_enabled(wtyp) && !halt->is_overcrowded(wtyp->get_catg_index())) { - if(halt.is_bound() && !start_halts.append_unique(halt)) - { - // Stops looking for new halts if we have found too many to fit - // into the fixed size list. Number limited to keep the speed up. - break; - } + start_halts.append(halt); } } @@ -1731,7 +1727,7 @@ void stadt_t::step_passagiere() bool can_walk_ziel = false; #ifdef NEW_PATHING - while(route_good && !can_walk_ziel && current_destination < destination_count) + while(!route_good && !can_walk_ziel && current_destination < destination_count) { #else while(route_result != haltestelle_t::ROUTE_OK && !can_walk_ziel && current_destination < destination_count) @@ -1849,11 +1845,12 @@ void stadt_t::step_passagiere() //"Menge" = volume (Google) // now, finally search a route; this consumes most of the time - koord return_zwischenziel = koord::invalid; // for people going back ... + #ifdef NEW_PATHING uint16 best_journey_time = 65535; uint8 best_start_halt = 0; #else + koord return_zwischenziel = koord::invalid; // for people going back ... halthandle_t best_destination[3]; uint8 best_journey_steps = 255; #endif @@ -2165,7 +2162,7 @@ void stadt_t::step_passagiere() { halthandle_t test_halt = halt_list[i]; #ifdef NEW_PATHING - if(test_halt->is_enabled(wtyp) && (start_halt==test_halt || test_halt->get_connexions(wtyp->get_catg_index())->access(start_halt) != NULL)) + if(test_halt->is_enabled(wtyp) && (start_halt == test_halt || test_halt->get_connexions(wtyp->get_catg_index())->access(start_halt) != NULL)) { #else if (test_halt->is_enabled(wtyp) && (start_halt==test_halt || test_halt->get_warenziele(wtyp->get_catg_index())->is_contained(start_halt))) @@ -2188,9 +2185,11 @@ void stadt_t::step_passagiere() return_pax.menge = pax_left_to_do; return_pax.set_zielpos(k); return_pax.set_ziel(start_halt); - return_pax.set_zwischenziel(welt->lookup(return_zwischenziel)->get_halt()); #ifndef NEW_PATHING + return_pax.set_zwischenziel(welt->lookup(return_zwischenziel)->get_halt()); return_pax.set_journey_steps(best_journey_steps); +#else + ret_halt->find_route(return_pax); #endif return_pax.arrival_time = welt->get_zeit_ms(); diff --git a/simhalt.cc b/simhalt.cc index 072161f7cc4..26036383755 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -236,7 +236,6 @@ void haltestelle_t::destroy_all(karte_t *welt) } } - haltestelle_t::haltestelle_t(karte_t* wl, loadsave_t* file) { self = halthandle_t(this); @@ -251,6 +250,7 @@ haltestelle_t::haltestelle_t(karte_t* wl, loadsave_t* file) waren = (vector_tpl<ware_t> **)calloc( warenbauer_t::get_max_catg_index(), sizeof(vector_tpl<ware_t> *) ); #ifdef NEW_PATHING iterations = 0; + search_complete = false; #else warenziele = new vector_tpl<halthandle_t>[ warenbauer_t::get_max_catg_index() ]; #endif @@ -299,6 +299,7 @@ haltestelle_t::haltestelle_t(karte_t* wl, koord k, spieler_t* sp) waren = (vector_tpl<ware_t> **)calloc( warenbauer_t::get_max_catg_index(), sizeof(vector_tpl<ware_t> *) ); #ifdef NEW_PATHING iterations = 0; + search_complete = false; #else warenziele = new vector_tpl<halthandle_t>[ warenbauer_t::get_max_catg_index() ]; #endif @@ -396,7 +397,10 @@ haltestelle_t::~haltestelle_t() } } free( waren ); -#ifndef NEW_PATHING +#ifdef NEW_PATHING + //delete[] connexions; + //delete[] paths; +#else delete[] warenziele; #endif @@ -945,7 +949,7 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp //"Station itself is not in target list" (Google) halthandle_t halt = get_halt(welt, fpl->eintrag[i].pos); // not existing, or own, or not enabled => ignore - if(!halt.is_bound() || halt == self || !halt->is_enabled(type)) + if(!halt.is_bound() || halt == self || !halt->is_enabled(type)) { continue; } @@ -955,18 +959,24 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp new_connexion.waiting_time = get_average_waiting_time(halt, type->get_catg_index()); // Check the average speed. - uint16 average_speed; + uint16 average_speed = 0; if(line.is_bound()) { - average_speed = line->get_finance_history(1, LINE_AVERAGE_SPEED) > 0 ? cnv->get_finance_history(1, LINE_AVERAGE_SPEED) : cnv->get_finance_history(0, LINE_AVERAGE_SPEED); - // If the average speed is not initialised, take a guess to prevent perverse outcomes and possible deadlocks. - average_speed = average_speed > 0 ? average_speed : line->get_convoy(0)->get_min_top_speed() / 2; + average_speed = line->get_finance_history(1, LINE_AVERAGE_SPEED) > 0 ? line->get_finance_history(1, LINE_AVERAGE_SPEED) : line->get_finance_history(0, LINE_AVERAGE_SPEED); + if(average_speed == 0) + { + // If the average speed is not initialised, take a guess to prevent perverse outcomes and possible deadlocks. + average_speed = speed_to_kmh(line->get_convoy(0)->get_min_top_speed()) / 2; + } } else if(cnv.is_bound()) { average_speed = cnv->get_finance_history(1, CONVOI_AVERAGE_SPEED) > 0 ? cnv->get_finance_history(1, CONVOI_AVERAGE_SPEED) : cnv->get_finance_history(0, CONVOI_AVERAGE_SPEED); - // If the average speed is not initialised, take a guess to prevent perverse outcomes and possible deadlocks. - average_speed = average_speed > 0 ? average_speed : cnv->get_min_top_speed() / 2; + if(average_speed == 0) + { + // If the average speed is not initialised, take a guess to prevent perverse outcomes and possible deadlocks. + average_speed = speed_to_kmh(cnv->get_min_top_speed()) / 2; + } } else { @@ -975,7 +985,50 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp continue; } - const uint32 journey_distance = accurate_distance(halt->get_basis_pos(), get_basis_pos()); + //const uint32 journey_distance = accurate_distance(halt->get_basis_pos(), get_basis_pos()); + uint32 journey_distance = 0; + bool start_counting = false; + halthandle_t current_halt; + halthandle_t previous_halt; + bool goal_found = false; + //ITERATE_PTR(fpl, j) + const uint16 max_steps = fpl->get_count(); + uint16 current_step = 0; + while(!goal_found) + { + previous_halt = current_halt; + current_halt = get_halt(welt, fpl->eintrag[current_step].pos); + if(current_halt == self) + { + if(!start_counting) + { + start_counting = true; + } + else + { + // This means that the route returns to this halt before it gets + // to the destination, so the distance will be measured from the + // *second* instance of it coming here. + journey_distance = 0; + } + } + if(start_counting && current_halt.is_bound() && previous_halt.is_bound() && current_halt != self) + { + journey_distance += accurate_distance(current_halt->get_basis_pos(), previous_halt->get_basis_pos()); + } + if(start_counting && current_halt == halt) + { + goal_found = true; + } + if(current_step < max_steps - 1) + { + current_step ++; + } + else + { + current_step = 0; + } + } new_connexion.journey_time = (((float)journey_distance / average_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 60); new_connexion.best_convoy = cnv; new_connexion.best_line = line; @@ -1173,7 +1226,7 @@ void haltestelle_t::rebuild_connexions(uint8 category) if(line->count_convoys( )> 0 && (i_am_public || line->get_convoy(0)->get_besitzer() == get_besitzer())) { const convoihandle_t dummy; - add_connexion(warenbauer_t::get_info_catg_index(line->get_goods_catg_index()[category]), fpl, dummy, line); + add_connexion(warenbauer_t::get_info_catg_index(category), fpl, dummy, line); } } } @@ -1214,66 +1267,136 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) paths_timestamp = welt->get_base_pathing_counter(); } + const uint32 total_halts = alle_haltestellen.get_count(); + const sint32 max_transfers = welt->get_einstellungen()->get_max_transfers(); + const uint32 max_depth = total_halts * max_transfers; + const uint32 max_iterations = max_depth <= 65535 ? max_depth : 65535; + + iterations = 0; + path_node* path_nodes = new path_node[max_iterations]; + if(open_list.get_count() < 1) { // Only reset the list if it is empty, so as to allow for re-using the open // list on subsequent occasions of finding a path. - iterations = 0; - path_node* starting_node; + path_node* starting_node = &path_nodes[iterations++]; starting_node->halt = self; + starting_node->journey_time = 0; starting_node->link = NULL; - starting_node->journey_time = 0; // Takes 0 time to stay in the same place open_list.insert(starting_node); } - const uint16 max_transfers = welt->get_einstellungen()->get_max_transfers(); - do - { - iterations ++; + { path_node* current_node = open_list.pop(); - if(current_node->halt == goal) + assert(current_node->halt.is_bound()); + + uint32 open_list_count = open_list.get_count(); + + const char* current_node_halt_name = (char*)current_node->halt->get_name(); + const bool is_in_list_1 = paths[category].is_contained(current_node->halt); + const bool is_in_list_2 = paths[category].get(current_node->halt).next_transfer.is_bound(); + const path test_path_1 = paths[category].get(current_node->halt); + if(paths[category].get(current_node->halt).journey_time != 65535) { - // Abort the search early if the goal stop is found. - // Because the open list is stored on the heap, the search - // can be resumed where it left off if another goal, as yet - // not found, is searched for, unless the index is stale. - return; + // Only insert into the open list if the + // item is not already on the closed list + continue; } + quickstone_hashtable_tpl<haltestelle_t, connexion> *current_connexions = current_node->halt->get_connexions(category); quickstone_hashtable_iterator_tpl<haltestelle_t, connexion> iter(*current_connexions); - while(iter.next()) + while(iter.next() && iterations <= max_iterations) { - path_node* new_node; - new_node->halt = iter.get_current_key(); - new_node->link = current_node; + const halthandle_t h = iter.get_current_key(); + + if(paths[category].get(h).journey_time != 65535) + { + // Only insert into the open list if the + // item is not already on the closed list. + continue; + } + + //open_list_count = open_list.get_count(); connexion current_connexion = iter.get_current_value(); + path_node* new_node = &path_nodes[iterations++]; + new_node->halt = h; new_node->journey_time = current_connexion.journey_time + current_connexion.waiting_time + current_node->journey_time; + new_node->link = current_node; + + /*const char* new_node_halt_name = (char*)new_node->halt->get_name(); + const path test_path_2 = paths[category].get(new_node->halt); + const bool n_is_in_list_1 = paths[category].is_contained(new_node->halt); + const bool n_is_in_list_2 = paths[category].get(new_node->halt).next_transfer.is_bound();*/ + open_list.insert(new_node); + } path new_path; new_path.journey_time = current_node->journey_time; - // Add only if not already contained. - if(paths[category].put(current_node->halt, new_path)) + open_list_count = open_list.get_count(); + + // Add only if not already contained and it is not the head node. + if(current_node->link != NULL && paths[category].put(current_node->halt, new_path)) { // Track the path back to get the next transfer from this halt path_node* track_node = current_node; - while(track_node->link->halt != self) + //while(track_node->link != NULL) + //for(uint8 depth = 0; depth <= max_transfers; depth ++) + for(uint8 depth = 0; depth <= 255; depth ++) { + if(track_node->link->link == NULL && track_node->halt.is_bound()) + { + paths[category].access(current_node->halt)->next_transfer = track_node->halt; + break; + } + track_node = track_node->link; } - paths[category].access(current_node->halt)->next_transfer = track_node->halt; + if(!paths[category].get(current_node->halt).next_transfer.is_bound()) + { + // Remove bad paths (transfer depth too great, so aborted) + paths[category].remove(current_node->halt); + } } - } - while(iterations <= max_transfers && open_list.get_count() > 0); - search_complete = true; + + if(current_node->halt == goal) + //path test_path_3 = paths[category].get(goal); + //if(paths[category].get(goal).journey_time != 65535) + { + // Abort the search early if the goal stop is found. + // Because the open list is stored on the heap, the search + // can be resumed where it left off if another goal, as yet + // not found, is searched for, unless the index is stale. + + /*char* goal_name = (char*)goal->get_name(); + char* next_transfer_name = "NULL"; + if(paths[category].access(current_node->halt)->next_transfer.is_bound()) + { + next_transfer_name = (char*)paths[category].access(current_node->halt)->next_transfer->get_name(); + }*/ + return; + } + + current_node = NULL; + if(iterations >= max_iterations) + { + // The search is not complete, but we abandon it for now + // to save memory. It can be resumed again later when the + // next packet tries to find a route. + break; + } + } + while(open_list.get_count() > 0); + search_complete = open_list.get_count() < 1; } haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category) { + assert(goal.is_bound()); path destination_path; if(reschedule || paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) @@ -1282,9 +1405,18 @@ haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category // This will mean that all the paths will need to be recalculated. // Must always recalculate if the schedules change. paths[category].clear(); + search_complete = false; } destination_path = paths[category].get(goal); + char* self_name = (char*)self->get_name(); + char* goal_name = (char*)goal->get_name(); + char* next_transfer_name = "NULL"; + if(destination_path.next_transfer.is_bound()) + { + next_transfer_name = (char*)destination_path.next_transfer->get_name(); + } + if(!destination_path.next_transfer.is_bound() && !search_complete) { // The pathfinding is incomplete or stale - recalculate @@ -1293,12 +1425,19 @@ haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category calculate_paths(goal, category); destination_path = paths[category].get(goal); } + + if(destination_path.next_transfer.is_bound()) + { + next_transfer_name = (char*)destination_path.next_transfer->get_name(); + } + return destination_path; } quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion>* haltestelle_t::get_connexions(uint8 c) { - if(reschedule || paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) + + if(reschedule || connexions->get_count() == 0 || paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) { // Rebuild the connexions if they are stale. rebuild_connexions(c); @@ -1325,6 +1464,13 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim uint16 journey_time = previous_journey_time; const ware_besch_t * warentyp = ware.get_besch(); const uint8 ware_catg_index = warentyp->get_catg_index(); + + + if(ware.get_zielpos() == koord::invalid && ware.get_ziel().is_bound()) + { + ware.set_zielpos(ware.get_ziel()->get_basis_pos()); + } + const koord ziel = ware.get_zielpos(); // since also the factory halt list is added to the ground, we can use just this ... @@ -1358,20 +1504,24 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim return 0; } - uint16 best_destination; + sint16 best_destination = -1; // Now, find the best route from here. ITERATE(ziel_list,i) { path test_path = get_path_to(ziel_list[i], ware.get_catg()); + if(!test_path.next_transfer.is_bound()) + { + continue; + } if(test_path.journey_time < journey_time) { journey_time = test_path.journey_time; best_destination = i; } } - - if(journey_time < previous_journey_time) + + if(journey_time < previous_journey_time && best_destination >= 0) { // If we are comparing this with other routes from different start halts, // only set the details if it is the best route so far. @@ -2595,6 +2745,9 @@ void haltestelle_t::rdwr(loadsave_t *file) if(file->is_loading()) { // Dummy loading and saving to maintain backwards compatibility + koord dummy_koord; + dummy_koord.rdwr(file); + char dummy[256]; file->rdwr_str(dummy,256); } diff --git a/simhalt.h b/simhalt.h index 63fc7691bff..c6b91c7248c 100644 --- a/simhalt.h +++ b/simhalt.h @@ -8,6 +8,8 @@ #ifndef simhalt_h #define simhalt_h +#define NEW_PATHING + #include "convoihandle_t.h" #include "linehandle_t.h" #include "halthandle_t.h" @@ -25,9 +27,9 @@ #include "tpl/vector_tpl.h" #include "tpl/quickstone_hashtable_tpl.h" #include "tpl/fixed_list_tpl.h" -#include "tpl/HOT_queue2_tpl.h" - -#define NEW_PATHING +#ifdef NEW_PATHING +#include "tpl/binary_heap_tpl.h" +#endif #define MAX_HALT_COST 7 // Total number of cost items #define MAX_MONTHS 12 // Max history @@ -192,16 +194,10 @@ class haltestelle_t uint16 waiting_time; // Convoy only used if line not used - // (i.e., if the best route involves using a convoi without a line) + // (i.e., if the best route involves using a convoy without a line) linehandle_t best_line; convoihandle_t best_convoy; - // Necessary for sorting - bool operator ==(const connexion& c) { return (journey_time + waiting_time) == (c.journey_time + c.waiting_time); } - bool operator !=(const connexion& c) { return (journey_time + waiting_time) != (c.journey_time + c.waiting_time); } - bool operator >(const connexion& c) { return (journey_time + waiting_time) > (c.journey_time + c.waiting_time); } - bool operator <(const connexion& c) { return (journey_time + waiting_time) < (c.journey_time + c.waiting_time); } - // TODO: Consider whether to add comfort }; @@ -211,16 +207,9 @@ class haltestelle_t uint16 journey_time; path_node* link; - // Necessary for sorting - bool operator ==(const path_node& p) { return journey_time == p.journey_time; } - bool operator !=(const path_node& p) { return journey_time != p.journey_time; } - bool operator >(const path_node& p) { return journey_time > p.journey_time; } - bool operator <(const path_node& p) { return journey_time < p.journey_time; } - bool operator <=(const path_node& p) { return journey_time <= p.journey_time; } - bool operator >=(const path_node& p) { return journey_time < p.journey_time; } + // Necessary for sorting in a binary heap + inline bool operator <= (const path_node p) const { return journey_time <= p.journey_time; } - // Necessary to work with the HOT queue. - inline uint32 get_distance() { return journey_time; } }; // Data on paths to ultimate destinations @@ -229,6 +218,7 @@ class haltestelle_t { halthandle_t next_transfer; uint16 journey_time; + path() { journey_time = 65535; } //TODO: Consider whether to add comfort }; @@ -243,9 +233,9 @@ class haltestelle_t #ifdef NEW_PATHING // Table of all direct connexions to this halt, with routing information. // Array: one entry per goods type. - quickstone_hashtable_tpl<haltestelle_t, connexion> connexions[8]; + quickstone_hashtable_tpl<haltestelle_t, connexion> connexions[16]; - quickstone_hashtable_tpl<haltestelle_t, path> paths[8]; + quickstone_hashtable_tpl<haltestelle_t, path> paths[16]; // The number of iterations of paths currently traversed. Used for // detecting when max_transfers has been reached. @@ -356,7 +346,7 @@ class haltestelle_t // Used for pathfinding. The list is stored on the heap so that it can be re-used // if searching is aborted part-way through. // @author: jamespetts - HOT_queue_tpl<path_node*> open_list; + binary_heap_tpl<path_node*> open_list; // Whether the search for the destination has completed: if so, the search will not // re-run unless the results are stale. diff --git a/simmain.cc b/simmain.cc index 830a42002a8..b52c2165c9b 100644 --- a/simmain.cc +++ b/simmain.cc @@ -290,6 +290,10 @@ static void ask_language() /** * Dies wird in main mittels set_new_handler gesetzt und von der * Laufzeitumgebung im Falle des Speichermangels bei new() aufgerufen + * + * + * This is main means of set_new_handler set and the runtime environment + * in the case of memory shortage when new () is called (Google) */ #ifdef _MSC_VER int sim_new_handler(unsigned int) @@ -297,7 +301,7 @@ int sim_new_handler(unsigned int) void sim_new_handler() #endif { - dbg->fatal("sim_new_handler()", "OUT OF MEMORY"); + dbg->fatal("sim_new_handler()", "Error allocating new object"); #ifdef _MSC_VER return 0; #endif diff --git a/tpl/hashtable_tpl.h b/tpl/hashtable_tpl.h index ae79e7d73a0..56dcafe7a44 100644 --- a/tpl/hashtable_tpl.h +++ b/tpl/hashtable_tpl.h @@ -97,6 +97,30 @@ class hashtable_tpl : public hash_t return true; } + // + // Checks whether the specified key is already + // contained in the hashtable. + // @author: jamespetts + // + bool is_contained(const key_t key) + { + const STHT_BAG_COUNTER_T code = get_hash(key); + slist_iterator_tpl<node_t> iter(bags[code]); + + // Code taken from the "put" method. + while(iter.next()) + { + node_t &node = iter.access_current(); + + if(comp(node.key, key) == 0) + { + // duplicate + return false; + } + } + return true; + } + // // Insert or replace a value - if a value is replaced, the old value is // returned, otherwise a nullvalue. This may be useful, if You need to delete it diff --git a/tpl/minivec_tpl.h b/tpl/minivec_tpl.h index 482301e82ce..d0a7b70f86d 100644 --- a/tpl/minivec_tpl.h +++ b/tpl/minivec_tpl.h @@ -135,13 +135,19 @@ template<class T> class minivec_tpl T& operator [](uint8 i) { - if (i >= count) dbg->fatal("minivec_tpl<T>::[]", "index out of bounds: %i not in 0..%d", i, count - 1); + if (i >= count) + { + dbg->fatal("minivec_tpl<T>::[]", "index out of bounds: %i not in 0..%d", i, count - 1); + } return data[i]; } const T& operator [](uint8 i) const { - if (i >= count) dbg->fatal("minivec_tpl<T>::[]", "index out of bounds: %i not in 0..%d", i, count - 1); + if (i >= count) + { + dbg->fatal("minivec_tpl<T>::[]", "index out of bounds: %i not in 0..%d", i, count - 1); + } return data[i]; } diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index c075949b6fa..f66eabdc936 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -1581,6 +1581,7 @@ vehikel_t::rauche() grund_t * gr = welt->lookup( get_pos() ); // nicht im tunnel ? if(gr && !gr->ist_im_tunnel() ) { + const koord3d TEST = get_pos(); wolke_t *abgas = new wolke_t(welt, get_pos(), get_xoff()+((dx*(sint16)((uint16)steps*TILE_STEPS))>>8), get_yoff()+((dy*(sint16)((uint16)steps*TILE_STEPS))>>8)+hoff, besch->get_rauch() ); if( !gr->obj_add(abgas) ) { From ed210e030ed5e2039ea5f247597ae743e4f6e1b3 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sat, 11 Apr 2009 19:41:21 +0100 Subject: [PATCH 51/61] Further refinements of the new pathing. Also, fixed the problem with the floating money display from the new revenue model. Outstanding issue: waiting times are not stored properly. --- dataobj/einstellungen.cc | 2 +- gui/halt_detail.cc | 4 +- simconvoi.cc | 29 ++++----- simconvoi.h | 2 +- simhalt.cc | 133 +++++++++++++++++++++++---------------- simhalt.h | 53 +++++----------- simline.cc | 6 +- vehicle/simvehikel.cc | 7 ++- vehicle/simvehikel.h | 2 + 9 files changed, 125 insertions(+), 113 deletions(-) diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index 243cbcfa621..00795e21f12 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -107,7 +107,7 @@ einstellungen_t::einstellungen_t() : // 4 is faster; 2 is more accurate. // Not recommended to use anything other than 2 or 4 // @author: jamespetts - max_rerouting_interval_months = 4; + max_rerouting_interval_months = 2; /* multiplier for steps on diagonal: * 1024: TT-like, faktor 2, vehicle will be too long and too fast diff --git a/gui/halt_detail.cc b/gui/halt_detail.cc index 9a23550edc4..b9b0431d9f1 100644 --- a/gui/halt_detail.cc +++ b/gui/halt_detail.cc @@ -259,10 +259,10 @@ void halt_detail_t::halt_detail_info(cbuffer_t & buf) buf.append("\n"); #ifdef NEW_PATHING buf.append("("); - buf.append(cnx.journey_time); + buf.append(cnx.journey_time * 0.1); // Convert from tenths buf.append(translator::translate(" mins. travelling")); buf.append(", "); - buf.append(cnx.waiting_time); + buf.append(cnx.waiting_time * 0.1); // Convert from tenths buf.append(translator::translate(" mins. waiting)")); buf.append("\n"); diff --git a/simconvoi.cc b/simconvoi.cc index c1f55abc5d6..9745dfd4999 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -2288,7 +2288,7 @@ convoi_t::rdwr(loadsave_t *file) { for (int k = MAX_MONTHS-1; k >= 0; k--) { - if(j == CONVOI_AVERAGE_SPEED || j == CONVOI_COMFORT && file->get_experimental_version() <= 1) + if((j == CONVOI_AVERAGE_SPEED || j == CONVOI_COMFORT) && file->get_experimental_version() <= 1) { // Versions of Experimental saves with 1 and below // did not have settings for average speed or comfort. @@ -2304,7 +2304,7 @@ convoi_t::rdwr(loadsave_t *file) { for (int k = MAX_MONTHS-1; k >= 0; k--) { - if(j == CONVOI_AVERAGE_SPEED || j == CONVOI_COMFORT && file->get_experimental_version() <= 1) + if((j == CONVOI_AVERAGE_SPEED || j == CONVOI_COMFORT) && file->get_experimental_version() <= 1) { // Versions of Experimental saves with 1 and below // did not have settings for average speed or comfort. @@ -2324,7 +2324,7 @@ convoi_t::rdwr(loadsave_t *file) { for (int k = MAX_MONTHS-1; k >= 0; k--) { - if(j == CONVOI_AVERAGE_SPEED || j == CONVOI_COMFORT && file->get_experimental_version() <= 1) + if((j == CONVOI_AVERAGE_SPEED || j == CONVOI_COMFORT) && file->get_experimental_version() <= 1) { // Versions of Experimental saves with 1 and below // did not have settings for average speed or comfort. @@ -2507,6 +2507,13 @@ convoi_t::rdwr(loadsave_t *file) file->rdwr_short(rolling_average_count[i], ""); } } + else + { + // For loading older games, assume that the convoy + // left twenty seconds ago, to avoid anomalies when + // measuring average speed. + last_departure_time = welt->get_zeit_ms() - 20000; + } } @@ -2899,7 +2906,7 @@ void convoi_t::laden() //"load" (Babelfish) }*/ -void convoi_t::calc_revenue(ware_t& ware) +sint64 convoi_t::calc_revenue(ware_t& ware) { float average_speed; @@ -3132,14 +3139,7 @@ void convoi_t::calc_revenue(ware_t& ware) final_revenue = (final_revenue + 1500ll) / 3000ll; - if(final_revenue > 0) - { - besitzer_p->buche(final_revenue, fahr[0]->get_pos().get_2d(), COST_INCOME); - jahresgewinn += final_revenue; - - book(final_revenue, CONVOI_PROFIT); - book(final_revenue, CONVOI_REVENUE); - } + return final_revenue; } const uint8 convoi_t::calc_tolerable_comfort(uint16 journey_minutes) const @@ -3311,7 +3311,9 @@ void convoi_t::hat_gehalten(koord k, halthandle_t halt) //"has held" (Google) //gewinn += v->calc_gewinn(v->last_stop_pos, v->get_pos().get_2d(), tmp ); v->last_stop_pos = v->get_pos().get_2d(); //Unload + v->current_revenue = 0; freight_info_resort |= v->entladen(k, halt); + gewinn += v->current_revenue; } if(!no_load) { @@ -3337,9 +3339,8 @@ void convoi_t::hat_gehalten(koord k, halthandle_t halt) //"has held" (Google) if(gewinn) { - besitzer_p->buche(gewinn, fahr[0]->get_pos().get_2d(), COST_INCOME); jahresgewinn += gewinn; //"annual profit" (Babelfish) - + besitzer_p->buche(gewinn, fahr[0]->get_pos().get_2d(), COST_INCOME); book(gewinn, CONVOI_PROFIT); book(gewinn, CONVOI_REVENUE); } diff --git a/simconvoi.h b/simconvoi.h index ad182e184f8..73c853d976c 100644 --- a/simconvoi.h +++ b/simconvoi.h @@ -922,7 +922,7 @@ class convoi_t : public sync_steppable, public overtaker_t // than iterating through each ware packet in each // vehicle in the convoy. // @author: jamespetts - void calc_revenue(ware_t &ware); + sint64 calc_revenue(ware_t &ware); // @author: jamespetts static const uint16 calc_adjusted_speed_bonus(uint16 base_bonus, uint32 distance); diff --git a/simhalt.cc b/simhalt.cc index 26036383755..207b1d96b56 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -939,6 +939,28 @@ void haltestelle_t::hat_gehalten(const ware_besch_t *type, const schedule_t *fpl } #else + +uint16 haltestelle_t::get_average_waiting_time(halthandle_t halt, uint8 category) const +{ + if(&waiting_times[category].get(halt) != NULL) + { + fixed_list_tpl<uint16, 16> times = waiting_times[category].get(halt); + const uint8 count = times.get_count(); + if(count > 0 && halt.is_bound()) + { + uint16 total_times = 0; + ITERATE(times,i) + { + total_times += times.get_element(i); + } + total_times /= count; + return total_times; + } + return 0; + } + return 0; +} + void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fpl, const convoihandle_t cnv, const linehandle_t line) { if(type != warenbauer_t::nichts) @@ -963,6 +985,7 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp if(line.is_bound()) { average_speed = line->get_finance_history(1, LINE_AVERAGE_SPEED) > 0 ? line->get_finance_history(1, LINE_AVERAGE_SPEED) : line->get_finance_history(0, LINE_AVERAGE_SPEED); + if(average_speed == 0) { // If the average speed is not initialised, take a guess to prevent perverse outcomes and possible deadlocks. @@ -994,6 +1017,7 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp //ITERATE_PTR(fpl, j) const uint16 max_steps = fpl->get_count(); uint16 current_step = 0; + while(!goal_found) { previous_halt = current_halt; @@ -1029,7 +1053,8 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp current_step = 0; } } - new_connexion.journey_time = (((float)journey_distance / average_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 60); + // Journey time in *tenths* of minutes. + new_connexion.journey_time = (((float)journey_distance / (float)average_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 600); new_connexion.best_convoy = cnv; new_connexion.best_line = line; @@ -1238,7 +1263,7 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) // http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm // Only recalculate when necessary (i.e., on schedule change, or - // after a certain period of time has elapse), and in any event + // after a certain period of time has elapsed), and in any event // not until a destination from this halt is requested, to prevent // the game pausing and becoming unresponsive whilst everything is // re-calculated all at the same time. @@ -1263,6 +1288,7 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) // If this is false, then this is only being called to finish calculating // paths that have not yet been calculated. open_list.clear(); + // Reset the timestamp. paths_timestamp = welt->get_base_pathing_counter(); } @@ -1272,13 +1298,13 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) const uint32 max_depth = total_halts * max_transfers; const uint32 max_iterations = max_depth <= 65535 ? max_depth : 65535; - iterations = 0; path_node* path_nodes = new path_node[max_iterations]; if(open_list.get_count() < 1) { // Only reset the list if it is empty, so as to allow for re-using the open // list on subsequent occasions of finding a path. + iterations = 0; path_node* starting_node = &path_nodes[iterations++]; starting_node->halt = self; starting_node->journey_time = 0; @@ -1286,17 +1312,13 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) open_list.insert(starting_node); } - do + while(open_list.get_count() > 0 || iterations < max_iterations) { path_node* current_node = open_list.pop(); assert(current_node->halt.is_bound()); uint32 open_list_count = open_list.get_count(); - const char* current_node_halt_name = (char*)current_node->halt->get_name(); - const bool is_in_list_1 = paths[category].is_contained(current_node->halt); - const bool is_in_list_2 = paths[category].get(current_node->halt).next_transfer.is_bound(); - const path test_path_1 = paths[category].get(current_node->halt); if(paths[category].get(current_node->halt).journey_time != 65535) { // Only insert into the open list if the @@ -1309,7 +1331,6 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) while(iter.next() && iterations <= max_iterations) { const halthandle_t h = iter.get_current_key(); - if(paths[category].get(h).journey_time != 65535) { // Only insert into the open list if the @@ -1323,11 +1344,6 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) new_node->halt = h; new_node->journey_time = current_connexion.journey_time + current_connexion.waiting_time + current_node->journey_time; new_node->link = current_node; - - /*const char* new_node_halt_name = (char*)new_node->halt->get_name(); - const path test_path_2 = paths[category].get(new_node->halt); - const bool n_is_in_list_1 = paths[category].is_contained(new_node->halt); - const bool n_is_in_list_2 = paths[category].get(new_node->halt).next_transfer.is_bound();*/ open_list.insert(new_node); @@ -1363,35 +1379,20 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) } if(current_node->halt == goal) - //path test_path_3 = paths[category].get(goal); - //if(paths[category].get(goal).journey_time != 65535) { // Abort the search early if the goal stop is found. // Because the open list is stored on the heap, the search // can be resumed where it left off if another goal, as yet // not found, is searched for, unless the index is stale. - /*char* goal_name = (char*)goal->get_name(); - char* next_transfer_name = "NULL"; - if(paths[category].access(current_node->halt)->next_transfer.is_bound()) - { - next_transfer_name = (char*)paths[category].access(current_node->halt)->next_transfer->get_name(); - }*/ - return; } current_node = NULL; - if(iterations >= max_iterations) - { - // The search is not complete, but we abandon it for now - // to save memory. It can be resumed again later when the - // next packet tries to find a route. - break; - } } - while(open_list.get_count() > 0); - search_complete = open_list.get_count() < 1; + + // If the code has reached here without returning, the search is complete. + search_complete = true; } haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category) @@ -1409,13 +1410,13 @@ haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category } destination_path = paths[category].get(goal); - char* self_name = (char*)self->get_name(); + /*char* self_name = (char*)self->get_name(); char* goal_name = (char*)goal->get_name(); char* next_transfer_name = "NULL"; if(destination_path.next_transfer.is_bound()) { next_transfer_name = (char*)destination_path.next_transfer->get_name(); - } + }*/ if(!destination_path.next_transfer.is_bound() && !search_complete) { @@ -1426,10 +1427,10 @@ haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category destination_path = paths[category].get(goal); } - if(destination_path.next_transfer.is_bound()) + /*if(destination_path.next_transfer.is_bound()) { next_transfer_name = (char*)destination_path.next_transfer->get_name(); - } + }*/ return destination_path; } @@ -1855,7 +1856,7 @@ bool haltestelle_t::recall_ware( ware_t& w, uint32 menge ) // will load something compatible with wtyp into the car which schedule is fpl -ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t *fpl, convoihandle_t cnv) //"hole from" (Google) +ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t *fpl, convoi_t* cnv) //"hole from" (Google) { // prissi: first iterate over the next stop, then over the ware // might be a little slower, but ensures that passengers to nearest stop are served first @@ -1908,7 +1909,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t if(tmp.get_besch()->get_speed_bonus() > 0) { //Only consider for discarding if the goods care about their timings. - const uint16 max_minutes = welt->get_einstellungen()->get_passenger_max_wait() / tmp.get_besch()->get_speed_bonus(); + const uint16 max_minutes = (welt->get_einstellungen()->get_passenger_max_wait() / tmp.get_besch()->get_speed_bonus()) * 10; // Minutes are recorded in tenths const sint64 waiting_ticks = welt->get_zeit_ms() - tmp.arrival_time; const uint16 waiting_minutes = get_waiting_minutes(welt->get_zeit_ms() - tmp.arrival_time); if(waiting_minutes > max_minutes) @@ -1926,12 +1927,12 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t #ifdef NEW_PATHING // Skip if the goods have recently arrived, and this is not their preferred line/convoy // After waiting some time (1/3rd of their maximum wait), they will board anything. - if(cnv.is_bound() && waiting_minutes <= max_minutes / 3) + if(cnv != NULL && waiting_minutes <= max_minutes / 3) { if(cnv->get_line().is_bound()) { linehandle_t best_line = get_preferred_line(tmp.get_zwischenziel(), tmp.get_catg()); - if(!best_line.is_bound() && best_line == cnv->get_line()) + if(best_line.is_bound() && best_line != cnv->get_line()) { continue; } @@ -1939,7 +1940,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t else { convoihandle_t best_convoy = get_preferred_convoy(tmp.get_zwischenziel(), tmp.get_catg()); - if(!best_convoy.is_bound() && best_convoy == cnv) + if(best_convoy.is_bound() && best_convoy.get_rep() != cnv) { continue; } @@ -1996,7 +1997,11 @@ inline uint16 haltestelle_t::get_waiting_minutes(uint32 waiting_ticks) const { // Waiting time is reduced (2* ...) instead of (3 * ...) because, in real life, people // can organise their journies according to timetables, so waiting is more efficient. - return (2 * welt->get_einstellungen()->get_journey_time_multiplier() * waiting_ticks) / 4096.0; + + // Note: waiting times now in *tenths* of minutes (hence difference in arithmetic) + //uint16 test_minutes_1 = ((float)1 / (1 / (waiting_ticks / 4096.0) * 20) * welt->get_einstellungen()->get_journey_time_multiplier() * 600); + //uint16 test_minutes_2 = (2 * welt->get_einstellungen()->get_journey_time_multiplier() * waiting_ticks) / 409.6; + return (2 * welt->get_einstellungen()->get_journey_time_multiplier() * waiting_ticks) / 409.6; //Old method (both are functionally equivalent, except for reduction in time. Would be fully equivalent if above was 3 * ...): //return ((float)1 / (1 / (waiting_ticks / 4096.0) * 20) * welt->get_einstellungen()->get_journey_time_multiplier() * 60); @@ -2776,11 +2781,19 @@ void haltestelle_t::rdwr(loadsave_t *file) quickstone_hashtable_iterator_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>> iter(waiting_times[i]); - iter.begin(); + //iter.begin(); while(iter.next()) { // Store the coordinates of the key halt - iter.get_current_key()->get_basis_pos().rdwr(file); + + koord halt_position = koord::invalid; + + if(iter.get_current_key().is_bound()) + { + halt_position = iter.get_current_key()->get_basis_pos(); + } + + halt_position.rdwr(file); uint8 waiting_time_count = iter.get_current_value().get_count(); file->rdwr_byte(waiting_time_count, ""); ITERATE(iter.get_current_value(),i) @@ -2799,17 +2812,31 @@ void haltestelle_t::rdwr(loadsave_t *file) { koord halt_position; halt_position.rdwr(file); - halthandle_t current_halt = welt->lookup(halt_position)->get_halt(); - fixed_list_tpl<uint16, 16> list; - uint8 waiting_time_count; - file->rdwr_byte(waiting_time_count, ""); - for(uint8 j = 0; j < waiting_time_count; j ++) + if(halt_position != koord::invalid) { - uint16 current_time; - file->rdwr_short(current_time, ""); - list.add_to_tail(current_time); + halthandle_t current_halt = welt->lookup(halt_position)->get_halt(); + fixed_list_tpl<uint16, 16> list; + uint8 waiting_time_count; + file->rdwr_byte(waiting_time_count, ""); + for(uint8 j = 0; j < waiting_time_count; j ++) + { + uint16 current_time; + file->rdwr_short(current_time, ""); + list.add_to_tail(current_time); + } + waiting_times[i].put(current_halt, list); + } + else + { + // The halt was not properly saved. + uint8 waiting_time_count; + file->rdwr_byte(waiting_time_count, ""); + for(uint8 j = 0; j < waiting_time_count; j ++) + { + uint16 current_time; + file->rdwr_short(current_time, ""); + } } - waiting_times[i].put(current_halt, list); } } } diff --git a/simhalt.h b/simhalt.h index c6b91c7248c..33f921c3f3e 100644 --- a/simhalt.h +++ b/simhalt.h @@ -8,7 +8,9 @@ #ifndef simhalt_h #define simhalt_h +#ifndef OLD_PATHING #define NEW_PATHING +#endif #include "convoihandle_t.h" #include "linehandle_t.h" @@ -31,16 +33,16 @@ #include "tpl/binary_heap_tpl.h" #endif -#define MAX_HALT_COST 7 // Total number of cost items -#define MAX_MONTHS 12 // Max history -#define MAX_HALT_NON_MONEY_TYPES 7 // number of non money types in HALT's financial statistic -#define HALT_ARRIVED 0 // the amount of ware that arrived here -#define HALT_DEPARTED 1 // the amount of ware that has departed from here -#define HALT_WAITING 2 // the amount of ware waiting -#define HALT_HAPPY 3 // number of happy passangers -#define HALT_UNHAPPY 4 // number of unhappy passangers -#define HALT_NOROUTE 5 // number of no-route passangers -#define HALT_CONVOIS_ARRIVED 6 // number of convois arrived this month +#define MAX_HALT_COST 7 // Total number of cost items +#define MAX_MONTHS 12 // Max history +#define MAX_HALT_NON_MONEY_TYPES 7 // number of non money types in HALT's financial statistic +#define HALT_ARRIVED 0 // the amount of ware that arrived here +#define HALT_DEPARTED 1 // the amount of ware that has departed from here +#define HALT_WAITING 2 // the amount of ware waiting +#define HALT_HAPPY 3 // number of happy passangers +#define HALT_UNHAPPY 4 // number of unhappy passangers +#define HALT_NOROUTE 5 // number of no-route passangers +#define HALT_CONVOIS_ARRIVED 6 // number of convois arrived this month class cbuffer_t; class grund_t; @@ -70,9 +72,9 @@ class haltestelle_t { public: enum station_flags { NOT_ENABLED=0, PAX=1, POST=2, WARE=4, CROWDED=8 }; - +#ifndef NEW_PATHING enum routine_result_flags { NO_ROUTE=0, ROUTE_OK=1, ROUTE_OVERCROWDED=8 }; - +#endif //13-Jan-02 Markus Weber Added enum stationtyp {invalid=0, loadingbay=1, railstation = 2, dock = 4, busstop = 8, airstop = 16, monorailstop = 32, tramstop = 64, maglevstop=128, narrowgaugestop=256 }; //could be combined with or! @@ -340,7 +342,7 @@ class haltestelle_t // Record of waiting times. Takes a list of the last 16 waiting times per type of goods. // Getter method will need to average the waiting times. // @author: jamespetts - quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>> waiting_times[8]; + quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>> waiting_times[16]; #ifdef NEW_PATHING // Used for pathfinding. The list is stored on the heap so that it can be re-used @@ -579,7 +581,7 @@ class haltestelle_t * @return collected volume (Google) * @author Hj. Malthaner */ - ware_t hole_ab(const ware_besch_t *warentyp, uint32 menge, schedule_t *fpl, convoihandle_t cnv); + ware_t hole_ab(const ware_besch_t *warentyp, uint32 menge, schedule_t *fpl, convoi_t* cnv); /* liefert ware an. Falls die Ware zu wartender Ware dazugenommen * werden kann, kann ware_t gelöscht werden! D.h. man darf ware nach @@ -737,28 +739,7 @@ class haltestelle_t // Getting and setting average waiting times in minutes // @author: jamespetts - uint16 get_average_waiting_time(halthandle_t halt, uint8 category) const - { - if(&waiting_times[category].get(halt) != NULL) - { - fixed_list_tpl<uint16, 16> times = waiting_times[category].get(halt); - const uint8 count = times.get_count(); - if(count > 0 && halt.is_bound()) - { - uint16 total_times = 0; - ITERATE(times,i) - { - total_times += times.get_element(i); - } - total_times /= count; - return total_times; - } - - return 0; - } - - return 0; - } + uint16 get_average_waiting_time(halthandle_t halt, uint8 category) const; void add_waiting_time(uint16 time, halthandle_t halt, uint8 category) { diff --git a/simline.cc b/simline.cc index b99ba8b482e..2ffb784a9ec 100644 --- a/simline.cc +++ b/simline.cc @@ -159,11 +159,11 @@ void simline_t::rdwr(loadsave_t *file) fpl->rdwr(file); //financial history - for (int j = 0; j<MAX_LINE_COST; j++) + for (int j = 0; j < MAX_LINE_COST; j++) { - for (int k = MAX_MONTHS-1; k>=0; k--) + for (int k = MAX_MONTHS - 1; k >= 0; k--) { - if(j == LINE_AVERAGE_SPEED || j == LINE_COMFORT && file->get_experimental_version() <= 1) + if((j == LINE_AVERAGE_SPEED || j == LINE_COMFORT) && file->get_experimental_version() <= 1) { // Versions of Experimental saves with 1 and below // did not have settings for average speed or comfort. diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index f66eabdc936..f938dc24d31 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -737,7 +737,7 @@ vehikel_t::unload_freight(halthandle_t halt) // Calculates the revenue for each packet under the new // revenue model. // @author: jamespetts - cnv->calc_revenue(iter.access_current()); + current_revenue += cnv->calc_revenue(iter.access_current()); // book delivered goods to destination @@ -787,8 +787,7 @@ bool vehikel_t::load_freight(halthandle_t halt, bool overcrowd) const uint16 hinein = (besch->get_zuladung() - total_freight) + (overcrowd ? besch->get_overcrowded_capacity() : 0); //hinein = inside (Google) - convoihandle_t convoy(cnv); - ware_t ware = halt->hole_ab(besch->get_ware(), hinein, fpl, convoy); + ware_t ware = halt->hole_ab(besch->get_ware(), hinein, fpl, cnv); if(ware.menge==0) { @@ -996,6 +995,7 @@ vehikel_t::vehikel_t(koord3d pos, const vehikel_besch_t* besch, spieler_t* sp) : //local_bonus_supplement = 0; is_overweight = false; reversed = false; + current_revenue = 0; } @@ -1025,6 +1025,7 @@ vehikel_t::vehikel_t(karte_t *welt) : //local_bonus_supplement = 0; is_overweight = false; reversed = false; + current_revenue = 0; } diff --git a/vehicle/simvehikel.h b/vehicle/simvehikel.h index 9481baae91f..13321c87535 100644 --- a/vehicle/simvehikel.h +++ b/vehicle/simvehikel.h @@ -514,6 +514,8 @@ class vehikel_t : public vehikel_basis_t, public fahrer_t // @author: jamespetts uint8 get_comfort() const; + sint64 current_revenue; + }; From a1bf832427f556474cbc8898f3b7544be699bc8a Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 12 Apr 2009 11:21:59 +0100 Subject: [PATCH 52/61] Interest payments are now correctly recorded in the profit graph. --- player/simplay.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/player/simplay.cc b/player/simplay.cc index d86704870b9..cec70ac6831 100644 --- a/player/simplay.cc +++ b/player/simplay.cc @@ -326,6 +326,7 @@ void spieler_t::neuer_monat() sint32 monthly_interest = interest_rate * konto; konto += monthly_interest; finance_history_month[0][COST_INTEREST] += monthly_interest; + finance_history_month[0][COST_PROFIT] -= monthly_interest; } // Adjust credit limit @@ -340,7 +341,7 @@ void spieler_t::neuer_monat() { if(this == welt->get_spieler(0)) { - if(finance_history_year[0][COST_NETWEALTH]<0 && welt->get_einstellungen()->bankruptsy_allowed()) + if(finance_history_year[0][COST_NETWEALTH] < 0 && welt->get_einstellungen()->bankruptsy_allowed() && konto_ueberzogen > 3) { destroy_all_win(); create_win(280, 40, new news_img("Bankrott:\n\nDu bist bankrott.\n"), w_info, magic_none); From 801c926c7ddc6df6560178d8f4d7e98ceea5c172 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 12 Apr 2009 14:48:25 +0100 Subject: [PATCH 53/61] Removed reference to "no routing over overcrowding" if the new pathing system is enabled. Changed some settings in the .vcproj file. If compiling manually, the "NEW PATHING" compiler option must be used to get the new pathing algorithm. Credit limit is restored slowly after a period of indebtedness. Revenue system updated to calculate the effect of the convoy's or line's speed on the likelihood of passengers using private cars. The "avoid overcrowding" setting now causes passengers/goods to be discarded at any overcrowded intermediate stop, not being their destination, and not pay for the journey there. A necessary file for the quickstone hashtable, missing from previous uploads, and necessary for the new pathing system, is included. --- Simutrans-Experimental.vcproj | 6 +-- dataobj/einstellungen.cc | 17 ++++++-- dataobj/einstellungen.h | 6 ++- player/simplay.cc | 12 +++++- simcity.cc | 51 ++++++++++++++++++----- simconvoi.cc | 2 +- simfab.cc | 75 +++++++++++++++++++++------------- simhalt.cc | 9 ++-- simhalt.h | 6 +-- tpl/quickstone_hashtable_tpl.h | 64 +++++++++++++++++++++++++++++ vehicle/simvehikel.cc | 42 ++++++++++++------- 11 files changed, 219 insertions(+), 71 deletions(-) create mode 100644 tpl/quickstone_hashtable_tpl.h diff --git a/Simutrans-Experimental.vcproj b/Simutrans-Experimental.vcproj index aa1abc80e88..10a2524790c 100644 --- a/Simutrans-Experimental.vcproj +++ b/Simutrans-Experimental.vcproj @@ -22,7 +22,7 @@ IntermediateDirectory="..\simutrans-experimental-binaries\debug\intermediates" ConfigurationType="1" CharacterSet="1" - WholeProgramOptimization="1" + WholeProgramOptimization="0" > <Tool Name="VCPreBuildEventTool" @@ -43,7 +43,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories=""G:\Projects\SDL-1.2.10\include";"G:\Program Files\PlatformSDK\Include";G:\Projects\zlib\include" - PreprocessorDefinitions="ZLIB_WINAPI;LITTLE_ENDIAN;STEPS16;USE_C;WIN32;DEBUG=3" + PreprocessorDefinitions="ZLIB_WINAPI;LITTLE_ENDIAN;STEPS16;USE_C;WIN32;DEBUG=3;NEW_PATHING" MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" @@ -127,7 +127,7 @@ Name="VCCLCompilerTool" InlineFunctionExpansion="2" AdditionalIncludeDirectories=""G:\Projects\SDL-1.2.10\include";"G:\Program Files\PlatformSDK\Include";G:\Projects\zlib\include" - PreprocessorDefinitions="ZLIB_WINAPI;LITTLE_ENDIAN;STEPS16;USE_C;WIN32;NDEBUG" + PreprocessorDefinitions="ZLIB_WINAPI;LITTLE_ENDIAN;STEPS16;USE_C;WIN32;NDEBUG;NEW_PATHING" RuntimeLibrary="2" UsePrecompiledHeader="0" WarningLevel="3" diff --git a/dataobj/einstellungen.cc b/dataobj/einstellungen.cc index 00795e21f12..fc90b6f186d 100644 --- a/dataobj/einstellungen.cc +++ b/dataobj/einstellungen.cc @@ -99,7 +99,9 @@ einstellungen_t::einstellungen_t() : max_route_steps = 1000000; max_transfers = 7; max_hops = 300; +#ifndef NEW_PATHING no_routing_over_overcrowding = false; +#endif //Two and a half hours (9 * 18 = 162; 162 approx 2:30h) passenger_max_wait = 2700; @@ -548,11 +550,18 @@ void einstellungen_t::rdwr(loadsave_t *file) if(file->get_version()>102000) { file->rdwr_bool( avoid_overcrowding, "" ); } - - if(file->get_version()>102001) { +#ifndef NEW_PATHING + if(file->get_version()>102001) + { file->rdwr_bool( no_routing_over_overcrowding, "" ); } - +#else + if(file->get_version()>102001) + { + bool dummy; + file->rdwr_bool(dummy, "" ); + } +#endif if(file->get_experimental_version() >= 1) { file->rdwr_short(min_bonus_max_distance, ""); @@ -762,7 +771,9 @@ void einstellungen_t::parse_simuconf( tabfile_t &simuconf, sint16 &disp_width, s passenger_factor = contents.get_int("passenger_factor", passenger_factor ); /* this can manipulate the passenger generation */ seperate_halt_capacities = contents.get_int("seperate_halt_capacities", seperate_halt_capacities ) != 0; avoid_overcrowding = contents.get_int("avoid_overcrowding", avoid_overcrowding )!=0; +#ifndef NEW_PATHING no_routing_over_overcrowding = contents.get_int("no_routing_over_overcrowded", no_routing_over_overcrowding )!=0; +#endif passenger_max_wait = contents.get_int("passenger_max_wait", passenger_max_wait); max_rerouting_interval_months = contents.get_int("max_rerouting_interval_months", max_rerouting_interval_months); diff --git a/dataobj/einstellungen.h b/dataobj/einstellungen.h index 399f3a27546..bdd186b9802 100644 --- a/dataobj/einstellungen.h +++ b/dataobj/einstellungen.h @@ -155,8 +155,10 @@ class einstellungen_t /* if set, goods will avoid being routed over overcrowded stops */ bool avoid_overcrowding; +#ifndef NEW_PATHING /* if set, goods will not routed over overcroded stations but rather try detours (if possible) */ bool no_routing_over_overcrowding; +#endif // The longest time that a passenger is // prepared to wait for transport. @@ -509,12 +511,12 @@ class einstellungen_t float get_global_power_factor() const { return global_power_factor; } - // do not take people to overcrowded destinations bool is_avoid_overcrowding() const { return avoid_overcrowding; } +#ifndef NEW_PATHING // do not allow routes over overcrowded destinations bool is_no_routing_over_overcrowding() const { return no_routing_over_overcrowding; } - +#endif uint16 get_passenger_max_wait() const { return passenger_max_wait; } uint8 get_max_rerouting_interval_months() const { return max_rerouting_interval_months; } diff --git a/player/simplay.cc b/player/simplay.cc index cec70ac6831..cb3f3a46f88 100644 --- a/player/simplay.cc +++ b/player/simplay.cc @@ -315,6 +315,7 @@ void spieler_t::neuer_monat() // Modified by jamespetts, February 2009 if(konto < 0) { + // Record of the number of months for which a player has been overdrawn. konto_ueberzogen++; // Add interest @@ -341,7 +342,7 @@ void spieler_t::neuer_monat() { if(this == welt->get_spieler(0)) { - if(finance_history_year[0][COST_NETWEALTH] < 0 && welt->get_einstellungen()->bankruptsy_allowed() && konto_ueberzogen > 3) + if(finance_history_year[0][COST_NETWEALTH] < 0 && welt->get_einstellungen()->bankruptsy_allowed()) { destroy_all_win(); create_win(280, 40, new news_img("Bankrott:\n\nDu bist bankrott.\n"), w_info, magic_none); @@ -389,12 +390,19 @@ void spieler_t::neuer_monat() else { konto_ueberzogen = 0; - if(base_credit_limit != get_base_credit_limit()) + if(base_credit_limit < get_base_credit_limit()) { // Restore credit rating slowly // after a period of debt base_credit_limit += (get_base_credit_limit() *0.1); } + if(base_credit_limit > get_base_credit_limit()) + { + // Make sure that the above computation does not + // allow the credit limit to increase beyond its + // normal level. + base_credit_limit = get_base_credit_limit(); + } } } diff --git a/simcity.cc b/simcity.cc index be30e4db37a..faedcecdfd1 100644 --- a/simcity.cc +++ b/simcity.cc @@ -1671,7 +1671,8 @@ void stadt_t::step_passagiere() if(passenger_packet_size < 1) passenger_packet_size = 7; // Find passenger destination - for (int pax_routed = 0; pax_routed < num_pax; pax_routed += passenger_packet_size) { + for (int pax_routed = 0; pax_routed < num_pax; pax_routed += passenger_packet_size) + { /* number of passengers that want to travel * Hajo: for efficiency we try to route not every @@ -1718,7 +1719,7 @@ void stadt_t::step_passagiere() } } - int current_destination = 0; + uint8 current_destination = 0; #ifdef NEW_PATHING bool route_good = false; #else @@ -1754,10 +1755,10 @@ void stadt_t::step_passagiere() const halthandle_t* dest_list = dest_plan->get_haltlist(); halthandle_t start_halt; - - // suitable end search + unsigned ziel_count = 0; - for (uint h = 0; h < dest_plan->get_haltlist_count(); h++) { + for (uint h = 0; h < dest_plan->get_haltlist_count(); h++) + { halthandle_t halt = dest_list[h]; if (halt->is_enabled(wtyp)) { @@ -1774,7 +1775,9 @@ void stadt_t::step_passagiere() } } - if (ziel_count == 0) { + //if (ziel_count == 0) + if(ziel_count == 0 && !can_walk_ziel) + { // DBG_MESSAGE("stadt_t::step_passagiere()", "No stop near dest (%d, %d)", ziel.x, ziel.y); // Thus, routing is not possible and we do not need to do a calculation. // Mark ziel as destination without route and continue. @@ -1810,10 +1813,10 @@ void stadt_t::step_passagiere() #ifdef DESTINATION_CITYCARS //citycars with destinations - if(start_halt.is_bound()) + if(start_halts.get_count() > 0) { //"Produce road users" (Babelfish) - erzeuge_verkehrsteilnehmer(start_halt->get_basis_pos(), step_count, destinations[current_destination].location); + erzeuge_verkehrsteilnehmer(start_halts[0]->get_basis_pos(), step_count, destinations[current_destination].location); } #endif } @@ -1997,8 +2000,36 @@ void stadt_t::step_passagiere() const sint32 speed_base = (100 * average_speed) / ref_speed - 100; const float base_bonus = (float)speed_base * ((float)speed_bonus_rating / 100.0); //base_bonus should be 1 if the average speed is the same as the bonus speed. - //TODO: Check whether these calculations are correct. - private_car_chance *= base_bonus; + + if(base_bonus > 0) + { + // Positive bonus - reduce probability of car use + // by up to 50% if the bonus is 50 or more. + if(base_bonus >= 50) + { + private_car_chance *= 0.5; + } + else + { + const float proportion = (float)base_bonus / 50.0; + private_car_chance -= (private_car_chance * 0.5) * proportion; + } + } + else if(base_bonus < 0) + { + // Negative bonus - increase probability of car use + // by up to 85% if the bonus is -50 or less. + if(base_bonus <= -50) + { + private_car_chance += private_car_chance * 0.85; + } + else + { + const float proportion = (float)base_bonus / -50.0; + private_car_chance += (private_car_chance * 0.85) * proportion; + } + } + // Do nothing if base_bonus == 0. #else diff --git a/simconvoi.cc b/simconvoi.cc index 54bb56af87d..3676bc269d7 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -2969,7 +2969,7 @@ sint64 convoi_t::calc_revenue(ware_t& ware) final_revenue -= tmp; } - if(goods->get_catg() == 0) + if(ware.is_passenger()) { //Passengers care about their comfort const uint8 tolerable_comfort = calc_tolerable_comfort(journey_minutes); diff --git a/simfab.cc b/simfab.cc index e8275455853..86aa1425352 100644 --- a/simfab.cc +++ b/simfab.cc @@ -1034,16 +1034,19 @@ class distribute_ware_t void fabrik_t::verteile_waren(const uint32 produkt) { // wohin liefern ? - if (lieferziele.empty()) { + if (lieferziele.empty()) + { return; } // not connected? const planquadrat_t *plan = welt->lookup(pos.get_2d()); - if(plan==NULL) { + if(plan==NULL) + { dbg->fatal("fabrik_t::verteile_waren", "%s has not distibution target", get_name() ); } - if(plan->get_haltlist_count()==0) { + if(plan->get_haltlist_count()==0) + { return; } @@ -1058,20 +1061,24 @@ void fabrik_t::verteile_waren(const uint32 produkt) // ok, first send everything away const halthandle_t *haltlist = plan->get_haltlist(); - for( unsigned i=0; i<plan->get_haltlist_count(); i++ ) { + + for(unsigned i = 0; i < plan->get_haltlist_count(); i++) + { halthandle_t halt = haltlist[i]; // Über alle Ziele iterieren // "Iterate over all goals" (Babelfish) - for(uint32 n=0; n<lieferziele.get_count(); n++) { - - // prissi: this way, the halt, that is tried first, will change. As a result, if all destinations are empty, it will be spread evenly + for(uint32 n = 0; n < lieferziele.get_count(); n++) + { + // prissi: this way, the halt, that is tried first, will change. + // As a result, if all destinations are empty, it will be spread evenly. const koord lieferziel = lieferziele[(n + last_lieferziel_start) % lieferziele.get_count()]; fabrik_t * ziel_fab = get_fab(welt, lieferziel); int vorrat; - if (ziel_fab && (vorrat = ziel_fab->verbraucht(ausgang[produkt].get_typ())) >= 0) { + if (ziel_fab && (vorrat = ziel_fab->verbraucht(ausgang[produkt].get_typ())) >= 0) + { //ware_t ware(ausgang[produkt].get_typ()); ware_t ware(ausgang[produkt].get_typ(), halt); ware.menge = menge; @@ -1080,7 +1087,8 @@ void fabrik_t::verteile_waren(const uint32 produkt) unsigned w; // find the index in the target factory - for (w = 0; w < ziel_fab->get_eingang().get_count() && ziel_fab->get_eingang()[w].get_typ() != ware.get_besch(); w++) { + for (w = 0; w < ziel_fab->get_eingang().get_count() && ziel_fab->get_eingang()[w].get_typ() != ware.get_besch(); w++) + { // emtpy } @@ -1088,7 +1096,8 @@ void fabrik_t::verteile_waren(const uint32 produkt) const sint32 halt_left = (sint32)halt->get_capacity(2) - (sint32)halt->get_ware_summe(ware.get_besch()); // ok, still enough space #ifdef NEW_PATHING - if(halt->find_route(ware) < 65535) + const uint16 current_journey_time = halt->find_route(ware); + if(current_journey_time < 65535) { #else if( halt->suche_route( ware, NULL, welt->get_einstellungen()->is_no_routing_over_overcrowding() )==haltestelle_t::ROUTE_OK ) @@ -1099,22 +1108,26 @@ void fabrik_t::verteile_waren(const uint32 produkt) // else deliver to non-overflown factory bool overflown = (ziel_fab->get_eingang()[w].menge >= ziel_fab->get_eingang()[w].max); - if(!welt->get_einstellungen()->get_just_in_time()) { + if(!welt->get_einstellungen()->get_just_in_time()) + { // distribution also to overflowing factories - if(still_overflow && !overflown) { + if(still_overflow && !overflown) + { // not overflowing factory found still_overflow = false; dist_list.clear(); } - if(still_overflow || !overflown) { + if(still_overflow || !overflown) + { dist_list.insert( distribute_ware_t( halt, halt_left, ware ) ); } } - else { - + else + { // only distribute to no-overflowed factories - if(!overflown) { + if(!overflown) + { dist_list.insert( distribute_ware_t( halt, halt_left, ware ) ); } } @@ -1125,8 +1138,8 @@ void fabrik_t::verteile_waren(const uint32 produkt) // Auswertung der Ergebnisse // "Evaluation of the results" (Babelfish) - if (!dist_list.empty()) { - + if (!dist_list.empty()) + { slist_iterator_tpl<distribute_ware_t> iter (dist_list); ware_t best_ware = dist_list.front().ware; @@ -1134,13 +1147,14 @@ void fabrik_t::verteile_waren(const uint32 produkt) sint32 best_amount = 999999; sint32 capacity_left = -1; - while(iter.next()) { - + while(iter.next()) + { halthandle_t halt = iter.get_current().halt; const ware_t& ware = iter.get_current().ware; const sint32 amount = (sint32)halt->get_ware_fuer_zielpos(ausgang[produkt].get_typ(),ware.get_zielpos()); - if(amount < best_amount) { + if(amount < best_amount) + { best_ware = ware; best_halt = halt; best_amount = amount; @@ -1151,14 +1165,16 @@ void fabrik_t::verteile_waren(const uint32 produkt) menge = max( 10, min( menge, 9+capacity_left ) ); best_ware.menge = menge; - if(capacity_left<0) { - + if(capacity_left<0) + { // find, what is most waiting here from us ware_t most_waiting(ausgang[produkt].get_typ()); most_waiting.menge = 0; - for(uint32 n=0; n<lieferziele.get_count(); n++) { + for(uint32 n=0; n<lieferziele.get_count(); n++) + { const uint32 amount = (sint32)best_halt->get_ware_fuer_zielpos( ausgang[produkt].get_typ(), lieferziele[n] ); - if(amount > most_waiting.menge) { + if(amount > most_waiting.menge) + { most_waiting.set_zielpos( lieferziele[n] ); most_waiting.menge = amount; most_waiting.arrival_time = welt->get_zeit_ms(); @@ -1167,9 +1183,11 @@ void fabrik_t::verteile_waren(const uint32 produkt) // we will reroute some goods - if(best_amount==0 && most_waiting.menge>0) { + if(best_amount==0 && most_waiting.menge>0) + { // remove something from the most waiting goods - if(best_halt->recall_ware( most_waiting, min(most_waiting.menge/2,1-capacity_left) ) ) { + if(best_halt->recall_ware( most_waiting, min(most_waiting.menge/2,1-capacity_left) ) ) + { best_ware.menge += most_waiting.menge; assert( (sint32)best_halt->get_ware_summe(best_ware.get_besch())==(sint32)best_halt->get_capacity(2)-capacity_left-(sint32)most_waiting.menge ); } @@ -1180,7 +1198,8 @@ void fabrik_t::verteile_waren(const uint32 produkt) } else { // overflowed with our own ware and we have still nearly full stock - if( ausgang[produkt].menge>= 0.75 * ausgang[produkt].max ) { + if( ausgang[produkt].menge>= 0.75 * ausgang[produkt].max ) + { /* Station too full, notify player */ best_halt->bescheid_station_voll(); } diff --git a/simhalt.cc b/simhalt.cc index a1f146c8f32..eb7b3b33d82 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -1915,7 +1915,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t if(waiting_minutes > max_minutes) { // Waiting too long: discard - if(tmp.get_catg() == 1) + if(tmp.is_passenger()) { // Passengers - use unhappy graph. add_pax_unhappy(tmp.menge); @@ -1952,15 +1952,16 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t // compatible car and right target stop? if( tmp.get_zwischenziel() == plan_halt ) { - - if( plan_halt->is_overcrowded(wtyp->get_catg_index()) ) + // Overcrowding is now dealt with elsewhere. This method creates deadlocks. + + /*if( plan_halt->is_overcrowded(wtyp->get_catg_index()) ) { if( welt->get_einstellungen()->is_avoid_overcrowding() && !(tmp.get_ziel()==plan_halt) ) { // do not go for transfer to overcrowded transfer stop continue; } - } + }*/ // not too much? ware_t neu(tmp); diff --git a/simhalt.h b/simhalt.h index 33f921c3f3e..f6f15146d6e 100644 --- a/simhalt.h +++ b/simhalt.h @@ -8,9 +8,9 @@ #ifndef simhalt_h #define simhalt_h -#ifndef OLD_PATHING -#define NEW_PATHING -#endif +//#ifndef OLD_PATHING +//#define NEW_PATHING +//#endif #include "convoihandle_t.h" #include "linehandle_t.h" diff --git a/tpl/quickstone_hashtable_tpl.h b/tpl/quickstone_hashtable_tpl.h new file mode 100644 index 00000000000..9a01ac21618 --- /dev/null +++ b/tpl/quickstone_hashtable_tpl.h @@ -0,0 +1,64 @@ +/* + * a template class which implements a hashtable with quickstone keys + * adapted from the pointer hashtable by jamespetts + */ + +#ifndef quickstone_hashtable_tpl_h +#define quickstone_hashtable_tpl_h + +#include "hashtable_tpl.h" +#include "quickstone_tpl.h" +#include <stdlib.h> + +/* + * Define the key characteristics for hashing pointers. For hashing the + * direct value is used. + */ +template<class key_t> +class quickstone_hash_tpl { +public: + static uint32 hash(const quickstone_tpl<key_t> key) + { + return labs((long)key.get_rep()); + } + + static key_t null() + { + return NULL; + } + + static void dump(const quickstone_tpl<key_t> key) + { + printf("%p", (void *)key.get_rep()); + } + + static long comp(quickstone_tpl<key_t> key1, quickstone_tpl<key_t> key2) + { + return (long)key1.get_rep() - (long)key2.get_rep(); + } +}; + + +/* + * Ready to use class for hashing pointers. + */ +template<class key_t, class value_t> +class quickstone_hashtable_tpl : public hashtable_tpl<quickstone_tpl<key_t>, value_t, quickstone_hash_tpl<key_t> > +{ +}; + + +template<class key_t, class value_t> +class quickstone_hashtable_iterator_tpl : public hashtable_iterator_tpl<quickstone_tpl<key_t>, value_t, quickstone_hash_tpl<key_t> > +{ +public: + quickstone_hashtable_iterator_tpl(const hashtable_tpl<quickstone_tpl<key_t>, value_t, quickstone_hash_tpl<key_t> > *hashtable) : + hashtable_iterator_tpl<quickstone_tpl<key_t>, value_t, ptrhash_tpl<quickstone_tpl<key_t>> >(hashtable) + { } + + quickstone_hashtable_iterator_tpl(const hashtable_tpl<quickstone_tpl<key_t>, value_t, quickstone_hash_tpl<key_t> > &hashtable) : + hashtable_iterator_tpl<quickstone_tpl<key_t>, value_t, quickstone_hash_tpl<key_t> >(hashtable) + { } +}; + +#endif diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index f938dc24d31..0dd01ecb9bb 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -719,7 +719,7 @@ vehikel_t::unload_freight(halthandle_t halt) kill_queue.insert(tmp); } - else if(end_halt==halt || via_halt==halt) + else if(halt == end_halt || halt == via_halt) { // printf("Liefere %d %s nach %s via %s an %s\n", @@ -731,22 +731,34 @@ vehikel_t::unload_freight(halthandle_t halt) // hier sollte nur ordentliche ware verabeitet werden // "here only tidy commodity should be processed" (Babelfish) - int menge = halt->liefere_an(tmp); //"supply" (Babelfish) - sum_menge += menge; - - // Calculates the revenue for each packet under the new - // revenue model. - // @author: jamespetts - current_revenue += cnv->calc_revenue(iter.access_current()); - - // book delivered goods to destination - if(end_halt==halt) + if(halt != end_halt && halt->is_overcrowded(tmp.get_catg()) && welt->get_einstellungen()->is_avoid_overcrowding()) { - // pax is always index 1 - const int categorie = tmp.get_index()>1 ? 2 : tmp.get_index(); - get_besitzer()->buche( menge, (player_cost)(COST_TRANSPORTED_PAS+categorie) ); + // Halt overcrowded - discard goods/passengers, and collect no revenue. + // Add passengers to unhappy passengers. + if(tmp.is_passenger()) + { + halt->add_pax_unhappy(tmp.menge); + } } + + else + { + const uint32 menge = halt->liefere_an(tmp); //"supply" (Babelfish) + sum_menge += menge; + + // Calculates the revenue for each packet under the new + // revenue model. + // @author: jamespetts + current_revenue += cnv->calc_revenue(iter.access_current()); + // book delivered goods to destination + if(end_halt == halt) + { + // pax is always index 1 + const int categorie = tmp.get_index()>1 ? 2 : tmp.get_index(); + get_besitzer()->buche( menge, (player_cost)(COST_TRANSPORTED_PAS+categorie) ); + } + } kill_queue.insert(tmp); @@ -1914,7 +1926,7 @@ uint8 vehikel_t::get_comfort() const while(iter.next()) { ware_t ware = iter.get_current(); - if(ware.get_catg() == 0) + if(ware.is_passenger()) { passenger_count += ware.menge; } From deb5709905fca67af9ca5c32767546783b08f991 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Sun, 12 Apr 2009 15:58:04 +0100 Subject: [PATCH 54/61] Fix compile error in makeobj --- besch/writer/tunnel_writer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/besch/writer/tunnel_writer.cc b/besch/writer/tunnel_writer.cc index 023b5ecedb8..d486a7354c1 100644 --- a/besch/writer/tunnel_writer.cc +++ b/besch/writer/tunnel_writer.cc @@ -88,7 +88,7 @@ void tunnel_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj) node.write_uint32(fp, max_weight, 20); node.write_uint8(fp, permissive_way_constraints, 24); node.write_uint8(fp, prohibitive_way_constraints, 25); - str = obj.get("way"); + cstring_t str = obj.get("way"); if (str.len() > 0) { xref_writer_t::instance()->write_obj(fp, node, obj_way, str, true); @@ -112,7 +112,7 @@ void tunnel_writer_t::write_obj(FILE* fp, obj_node_t& parent, tabfileobj_t& obj) char buf[40]; sprintf(buf, "%simage[%s][0]", "back", indices[0]); - cstring_t str = obj.get(buf); + str = obj.get(buf); if (strlen(str) == 0) { node.write_sint8(fp, number_seasons, 19); write_head(fp, node, obj); From 5155390289337daaf17a737988f747b4f5f36a8c Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 13 Apr 2009 15:32:31 +0100 Subject: [PATCH 55/61] FIX: Players with no money could still raise or lower land FIX: Erroneous credit limit message when adding halts. FIX: AI players could not build halts FIX: Incorrect calculation of which goods could be transported to/from a halt when lines, rather than individual convoys, were used. CHANGE: settings.xml renamed settings-experimental.xml to avoid conflicts with Simutrans-Standard FIX: Settings from settings-experimental.xml are now read --- dataobj/loadsave.cc | 6 ++-- gui/banner.cc | 3 +- player/ai.cc | 2 +- player/ai_passenger.cc | 2 +- player/simplay.h | 2 +- simcity.cc | 2 +- simconvoi.cc | 36 ++++++++++++++++------- simhalt.cc | 67 ++++++++++++++++++++++++++++++++++++------ simline.h | 2 +- simmain.cc | 13 ++++---- simversion.h | 2 +- simwerkz.cc | 38 ++++++++++++++++-------- vehicle/simvehikel.cc | 7 ++++- 13 files changed, 133 insertions(+), 49 deletions(-) diff --git a/dataobj/loadsave.cc b/dataobj/loadsave.cc index 81b541d1015..de2c0a209be 100644 --- a/dataobj/loadsave.cc +++ b/dataobj/loadsave.cc @@ -815,8 +815,7 @@ loadsave_t::combined_version loadsave_t::int_version(const char *version_text, i // major number (0..) uint32 v0 = atoi(version_text); - while(*version_text && *version_text++ != '.') - ; + while(*version_text && *version_text++ != '.'); if(!*version_text) { dbg->fatal( "loadsave_t::int_version()","Really broken version string!" ); combined_version dud; @@ -827,8 +826,7 @@ loadsave_t::combined_version loadsave_t::int_version(const char *version_text, i // middle number (.99.) uint32 v1 = atoi(version_text); - while(*version_text && *version_text++ != '.') - ; + while(*version_text && *version_text++ != '.'); if(!*version_text) { dbg->fatal( "loadsave_t::int_version()","Really broken version string!" ); combined_version dud; diff --git a/gui/banner.cc b/gui/banner.cc index 452dbe7d14a..bd912a4477c 100644 --- a/gui/banner.cc +++ b/gui/banner.cc @@ -56,8 +56,9 @@ void banner_t::zeichnen(koord /*pos*/, koord) int color = (s == 0 ? COL_WHITE : COL_BLACK); display_proportional(xoff + s + 24+30, yoff + s + 10, "This is an experimental version of Simutrans:", ALIGN_LEFT, heading, true); - display_proportional(xoff + s + 48+30, yoff + s + 22, "Version " VERSION_NUMBER " " VERSION_DATE, ALIGN_LEFT, color, true); + display_proportional(xoff + s + 48+30, yoff + s + 22, "Version " VERSION_NUMBER " " VERSION_DATE, ALIGN_LEFT, color, true); display_proportional(xoff + s + 24+30, yoff + s + 40, "This experimental version", ALIGN_LEFT, heading, true); + display_proportional(xoff + s + 24+30+155, yoff + s + 40, (const char*)EXPERIMENTAL_VERSION, ALIGN_LEFT, color, true); display_proportional(xoff + s + 48+30, yoff + s + 56, "is modified by James E. Petts", ALIGN_LEFT, color, true); display_proportional(xoff + s + 48+30, yoff + s + 70, "from Simutrans, 1997-2005", ALIGN_LEFT, color, true); display_proportional(xoff + s + 48+30, yoff + s + 82, "(c) Hj. Malthaner; and", ALIGN_LEFT, color, true); diff --git a/player/ai.cc b/player/ai.cc index fd4cd076c88..2c888b0606a 100755 --- a/player/ai.cc +++ b/player/ai.cc @@ -83,7 +83,7 @@ bool ai_t::is_my_halt(koord pos) const */ bool ai_t::is_connected( const koord start_pos, const koord dest_pos, const ware_besch_t *wtyp ) const { - // Dario: Check if there's a stop near destination + // Dario: Check if there's a stop near the start const planquadrat_t* start_plan = welt->lookup(start_pos); const halthandle_t* start_list = start_plan->get_haltlist(); diff --git a/player/ai_passenger.cc b/player/ai_passenger.cc index a0a6e0e1ac8..a6de144e400 100755 --- a/player/ai_passenger.cc +++ b/player/ai_passenger.cc @@ -72,7 +72,7 @@ halthandle_t ai_passenger_t::get_our_hub( const stadt_t *s ) const { //slist_iterator_tpl <halthandle_t> iter( halt_list ); //while(iter.next()) { - for(sint16 i = halt_list.get_count() - 1; i >= 0; i --) + ITERATE(halt_list,i) { //halthandle_t halt = iter.get_current(); halthandle_t halt = halt_list[i]; diff --git a/player/simplay.h b/player/simplay.h index aafa029c68d..2ccd97c7298 100644 --- a/player/simplay.h +++ b/player/simplay.h @@ -370,7 +370,7 @@ class spieler_t //Checks the affordability of any possible purchase. inline bool can_afford(sint64 price) const { - return (price < (konto + finance_history_month[0][COST_CREDIT_LIMIT]) || welt->get_einstellungen()->insolvent_purchases_allowed() || welt->get_einstellungen()->is_freeplay()); + return (price < (konto + finance_history_month[0][COST_CREDIT_LIMIT]) || welt->get_einstellungen()->insolvent_purchases_allowed() || welt->get_einstellungen()->is_freeplay()); } uint32 get_credit_limit() const { return finance_history_month[0][COST_CREDIT_LIMIT]; } diff --git a/simcity.cc b/simcity.cc index faedcecdfd1..f0f8479c824 100644 --- a/simcity.cc +++ b/simcity.cc @@ -2206,7 +2206,7 @@ void stadt_t::step_passagiere() } // now try to add them to the target halt - uint32 max_ware = ret_halt->get_capacity(wtyp->get_index()); + uint32 max_ware = ret_halt->get_capacity(wtyp->get_catg_index()); if( !ret_halt->is_overcrowded(wtyp->get_catg_index()) ) { // prissi: not overcrowded and can recieve => add them diff --git a/simconvoi.cc b/simconvoi.cc index 3676bc269d7..0337e75d17c 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -237,8 +237,11 @@ DBG_MESSAGE("convoi_t::~convoi_t()", "destroying %d, %p", self.get_id(), this); ITERATE_PTR(fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); - tmp_halt->reschedule = true; - tmp_halt->force_paths_stale(); + if(tmp_halt.is_bound()) + { + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale(); + } } #else // Old method - brute force @@ -1307,8 +1310,15 @@ void convoi_t::start() ITERATE_PTR(fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); - tmp_halt->reschedule = true; - tmp_halt->force_paths_stale(); + if(tmp_halt.is_bound()) + { + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale(); + } + else + { + dbg->error("convoi_t::start()", "Halt in schedule does not exist"); + } } #else @@ -1569,8 +1579,11 @@ bool convoi_t::set_schedule(schedule_t * f) ITERATE_PTR(fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); - tmp_halt->reschedule = true; - tmp_halt->force_paths_stale(); + if(tmp_halt.is_bound()) + { + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale(); + } } ITERATE_PTR(f, k) @@ -3038,7 +3051,7 @@ sint64 convoi_t::calc_revenue(ware_t& ware) const uint8 catering_level = get_catering_level(ware.get_besch()->get_catg_index()); if(catering_level > 0) { - if(ware.get_index() == 1) + if(ware.is_mail()) { // Mail if(journey_minutes >= welt->get_einstellungen()->get_tpo_min_minutes()) @@ -3046,7 +3059,7 @@ sint64 convoi_t::calc_revenue(ware_t& ware) final_revenue += (welt->get_einstellungen()->get_tpo_revenue() * ware.menge); } } - else if(ware.get_index() == 0) + else if(ware.is_passenger()) { // Passengers float proportion = 0.0; @@ -3504,8 +3517,11 @@ void convoi_t::set_line(linehandle_t org_line) ITERATE_PTR(fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); - tmp_halt->reschedule = true; - tmp_halt->force_paths_stale(); + if(tmp_halt.is_bound()) + { + tmp_halt->reschedule = true; + tmp_halt->force_paths_stale(); + } } #else // Old method - brute force diff --git a/simhalt.cc b/simhalt.cc index eb7b3b33d82..5ce8d069e8b 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -847,6 +847,10 @@ void haltestelle_t::reroute_goods() new_warray->append( ware ); } + // TESTING CODE + + + INT_CHECK( "simhalt.cc 489" ); #ifndef NEW_PATHING // delete, if nothing connects here @@ -1229,11 +1233,14 @@ void haltestelle_t::rebuild_connexions(uint8 category) continue; } - if(ware != warenbauer_t::nichts && !add_catg_index.is_contained(ware->get_catg_index())) + if(ware != warenbauer_t::nichts) { // now add the freights add_connexion(ware, fpl, cnv, dummy); - add_catg_index.append_unique(category); + if(!add_catg_index.is_contained(ware->get_catg_index())) + { + add_catg_index.append_unique(category); + } } } } @@ -1250,8 +1257,42 @@ void haltestelle_t::rebuild_connexions(uint8 category) // ok, now add line to the connections if(line->count_convoys( )> 0 && (i_am_public || line->get_convoy(0)->get_besitzer() == get_besitzer())) { - const convoihandle_t dummy; - add_connexion(warenbauer_t::get_info_catg_index(category), fpl, dummy, line); + INT_CHECK("simhalt.cc 613"); + schedule_t *fpl = line->get_schedule(); + + if(fpl != NULL) + { + const convoihandle_t dummy; + + ITERATE_PTR(fpl, i) + { + if (get_halt(welt, fpl->eintrag[i].pos) == self) + { + // what goods can this line transport? + add_catg_index.clear(); + const minivec_tpl<uint8> &goods = line->get_goods_catg_index(); + ITERATE(goods, j) + { + const ware_besch_t *ware = warenbauer_t::get_info_catg_index(goods[j]); + + if (ware->get_catg_index() != category) + { + continue; + } + + if(ware != warenbauer_t::nichts) + { + // now add the freights + add_connexion(ware, fpl, dummy, line); + if(!add_catg_index.is_contained(ware->get_catg_index())) + { + add_catg_index.append_unique(category); + } + } + } + } + } + } } } } @@ -1507,10 +1548,18 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim sint16 best_destination = -1; + const uint8 test_1 = ware.get_catg(); + const uint8 test_2 = ware.get_index(); + const uint8 test_3 = ware.get_besch()->get_catg(); + const uint8 test_4 = ware.get_besch()->get_catg_index(); + const char* test_5 = ware.get_name(); + const char* test_6 = ware.get_besch()->get_catg_name(); + uint8 a = 1 + 1; + // Now, find the best route from here. ITERATE(ziel_list,i) { - path test_path = get_path_to(ziel_list[i], ware.get_catg()); + path test_path = get_path_to(ziel_list[i], ware.get_besch()->get_catg_index()); if(!test_path.next_transfer.is_bound()) { continue; @@ -1527,7 +1576,7 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim // If we are comparing this with other routes from different start halts, // only set the details if it is the best route so far. ware.set_ziel(ziel_list[best_destination]); - path final_path = get_path_to(ziel_list[best_destination], ware.get_catg()); + path final_path = get_path_to(ziel_list[best_destination], ware.get_besch()->get_catg_index()); ware.set_zwischenziel(final_path.next_transfer); return final_path.journey_time; } @@ -1931,7 +1980,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t { if(cnv->get_line().is_bound()) { - linehandle_t best_line = get_preferred_line(tmp.get_zwischenziel(), tmp.get_catg()); + linehandle_t best_line = get_preferred_line(tmp.get_zwischenziel(), tmp.get_besch()->get_catg_index()); if(best_line.is_bound() && best_line != cnv->get_line()) { continue; @@ -1939,7 +1988,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t } else { - convoihandle_t best_convoy = get_preferred_convoy(tmp.get_zwischenziel(), tmp.get_catg()); + convoihandle_t best_convoy = get_preferred_convoy(tmp.get_zwischenziel(), tmp.get_besch()->get_catg_index()); if(best_convoy.is_bound() && best_convoy.get_rep() != cnv) { continue; @@ -1979,7 +2028,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t book(neu.menge, HALT_DEPARTED); const uint16 waiting_minutes = get_waiting_minutes(welt->get_zeit_ms() - neu.arrival_time); - add_waiting_time(waiting_minutes, neu.get_zwischenziel(), neu.get_catg()); + add_waiting_time(waiting_minutes, neu.get_zwischenziel(), neu.get_besch()->get_catg_index()); resort_freight_info = true; return neu; } diff --git a/simline.h b/simline.h index 8cc8f082d91..76a45465665 100644 --- a/simline.h +++ b/simline.h @@ -76,7 +76,7 @@ class simline_t { vector_tpl<convoihandle_t> line_managed_convoys; /* - * a list of all convoys assigned to this line + * ??? * @author hsiegeln */ minivec_tpl<uint8> goods_catg_index; diff --git a/simmain.cc b/simmain.cc index b52c2165c9b..db57dadde05 100644 --- a/simmain.cc +++ b/simmain.cc @@ -422,14 +422,16 @@ int simu_main(int argc, char** argv) // now read last setting (might be overwritten by the tab-files) loadsave_t file; - if(file.rd_open("settings.xml")) { - if( file.get_version() > loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL).version || file.get_experimental_version() > loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL).experimental_version) + if(file.rd_open("settings-experimental.xml")) + { + if( file.get_version() > loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL).version || file.get_experimental_version() > loadsave_t::int_version(EXPERIMENTAL_SAVEGAME_VERSION, NULL, NULL).experimental_version) { // too new => remove it file.close(); - remove( "settings.xml" ); + remove( "settings-experimental.xml" ); } - else { + else + { found_settings = true; umgebung_t::rdwr(&file); umgebung_t::default_einstellungen.rdwr(&file); @@ -943,7 +945,8 @@ DBG_MESSAGE("simmain","loadgame file found at %s",buffer); // save setting ... chdir( umgebung_t::user_dir ); - if(file.wr_open("settings.xml",loadsave_t::xml,"settings only/")) { + if(file.wr_open("settings-experimental.xml",loadsave_t::xml,"settings only/")) + { umgebung_t::rdwr(&file); umgebung_t::default_einstellungen.rdwr(&file); file.close(); diff --git a/simversion.h b/simversion.h index f9b2ceb9763..8e7675eb199 100644 --- a/simversion.h +++ b/simversion.h @@ -14,7 +14,7 @@ #define SAVEGAME_VER_NR "0.102.1" #define SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR) -#define EXPERIMENTAL_VERSION L"2" +#define EXPERIMENTAL_VERSION L"2.1" #define EXPERIMENTAL_VER_NR ".2" #define EXPERIMENTAL_SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) #define COMBINED_VER_NR (SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) diff --git a/simwerkz.cc b/simwerkz.cc index 92eca0d8710..e2f93954753 100644 --- a/simwerkz.cc +++ b/simwerkz.cc @@ -722,18 +722,30 @@ const char *wkz_raise_t::work( karte_t *welt, spieler_t *sp, koord3d k ) n = welt->raise(pos); ok = (n!=0); } - if(n>0) { - spieler_t::accounting(sp, welt->get_einstellungen()->cst_alter_land*n, pos, COST_CONSTRUCTION); - // update image - for(int j=-n; j<=n; j++) { - for(int i=-n; i<=n; i++) { - const planquadrat_t* p = welt->lookup(pos + koord(i, j)); - if (p) { - grund_t* g = p->get_kartenboden(); - if (g) g->calc_bild(); + if(n>0) + { + const sint64 cost = welt->get_einstellungen()->cst_alter_land * n; + if(sp->can_afford(-cost)) + { + spieler_t::accounting(sp, cost, pos, COST_CONSTRUCTION); + // update image + for(int j=-n; j<=n; j++) + { + for(int i=-n; i<=n; i++) + { + const planquadrat_t* p = welt->lookup(pos + koord(i, j)); + if (p) + { + grund_t* g = p->get_kartenboden(); + if (g) g->calc_bild(); + } } } } + else + { + return CREDIT_MESSAGE; + } } return !ok ? "Tile not empty." : NULL; } @@ -1109,7 +1121,7 @@ DBG_MESSAGE("wkz_senke()","called on %d,%d", k.x, k.y); */ const char *wkz_add_city_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) { - if(!sp->can_afford(0 - welt->get_einstellungen()->cst_found_city)) + if(!sp->can_afford(0 - welt->get_einstellungen()->cst_found_city)) { return CREDIT_MESSAGE; } @@ -2353,7 +2365,7 @@ DBG_MESSAGE("wkz_halt_aux()", "building %s on square %d,%d for waytype %x", besc return false; } - if(!sp->can_afford(cost + ((welt->get_einstellungen()->maint_building*besch->get_level()*besch->get_b()*besch->get_h()*60)<<(welt->ticks_bits_per_tag-18)))); + if(!sp->can_afford(cost + ((welt->get_einstellungen()->maint_building*besch->get_level()*besch->get_b()*besch->get_h()*60)<<(welt->ticks_bits_per_tag-18)))) { return CREDIT_MESSAGE; } @@ -2643,7 +2655,7 @@ const char *wkz_station_t::work( karte_t *welt, spieler_t *sp, koord3d pos ) case haus_besch_t::generic_stop: switch(besch->get_extra()) { case road_wt: - if(!sp->can_afford(welt->get_einstellungen()->cst_multiply_roadstop * besch->get_level())) + if(!sp->can_afford(-(welt->get_einstellungen()->cst_multiply_roadstop * besch->get_level()))) { return CREDIT_MESSAGE; } @@ -3436,7 +3448,7 @@ DBG_MESSAGE("wkz_headquarter()", "building headquarter at (%d,%d)", pos.x, pos.y const sint64 headquarters_cost = welt->get_einstellungen()->cst_multiply_headquarter * besch->get_level() * size.x * size.y; - if(!sp->can_afford(headquarters_cost)) + if(!sp->can_afford(-headquarters_cost)) { return CREDIT_MESSAGE; } diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 0dd01ecb9bb..299b7c69fc8 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -707,6 +707,11 @@ vehikel_t::unload_freight(halthandle_t halt) { const ware_t& tmp = iter.get_current(); + if(&tmp == NULL) + { + continue; + } + halthandle_t end_halt = tmp.get_ziel(); halthandle_t via_halt = tmp.get_zwischenziel(); @@ -732,7 +737,7 @@ vehikel_t::unload_freight(halthandle_t halt) // hier sollte nur ordentliche ware verabeitet werden // "here only tidy commodity should be processed" (Babelfish) - if(halt != end_halt && halt->is_overcrowded(tmp.get_catg()) && welt->get_einstellungen()->is_avoid_overcrowding()) + if(halt != end_halt && halt->is_overcrowded(tmp.get_besch()->get_catg_index()) && welt->get_einstellungen()->is_avoid_overcrowding()) { // Halt overcrowded - discard goods/passengers, and collect no revenue. // Add passengers to unhappy passengers. From 07e735de01b986449e9394da37b67cb64c8f28bc Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Mon, 13 Apr 2009 22:38:29 +0100 Subject: [PATCH 56/61] FIX: Memory leak in new routing algorithm. FIX: Crash when starting with show_month = 3 in simuconf.tab FIX: Incorrect display of the date and time in the main game window --- simhalt.cc | 37 +++++++++++++++++++++++++------------ simhalt.h | 4 ++++ simversion.h | 2 +- simwin.cc | 10 +++++----- tpl/weighted_vector_tpl.h | 5 +++-- 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/simhalt.cc b/simhalt.cc index 5ce8d069e8b..0e2c501df58 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -62,7 +62,6 @@ #include "vehicle/simpeople.h" - #ifdef LAGER_NOT_IN_USE #include "dings/lagerhaus.h" #endif @@ -398,6 +397,7 @@ haltestelle_t::~haltestelle_t() } free( waren ); #ifdef NEW_PATHING + // These do not work: access violations result. Not clear why. //delete[] connexions; //delete[] paths; #else @@ -799,8 +799,6 @@ void haltestelle_t::neuer_monat() */ void haltestelle_t::reroute_goods() { - //TODO: Update this to use the new routing method. - // reroute only on demand reroute_counter = welt->get_schedule_counter(); @@ -1297,6 +1295,8 @@ void haltestelle_t::rebuild_connexions(uint8 category) } } + + //@author: jamespetts void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) { @@ -1314,6 +1314,11 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) // Cannot route from this station: do not try. return; } + + const uint32 total_halts = alle_haltestellen.get_count(); + const sint32 max_transfers = welt->get_einstellungen()->get_max_transfers(); + const uint32 max_depth = total_halts * max_transfers; + const uint32 max_iterations = max_depth <= 65535 ? max_depth : 65535; if(reschedule || connexions_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) { @@ -1321,26 +1326,32 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) rebuild_connexions(category); // Not clearing the open list would be faster, but could give anomalous results. // Thus, if connexions are stale, all new paths will be recalculated from scratch. - open_list.clear(); + if(!open_list.empty()) + { + open_list.clear(); + delete[] path_nodes; + } + + path_nodes = new path_node[max_iterations]; + } if(paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) { // List is stale. Recalculate. // If this is false, then this is only being called to finish calculating // paths that have not yet been calculated. - open_list.clear(); + if(!open_list.empty()) + { + open_list.clear(); + delete[] path_nodes; + } + + path_nodes = new path_node[max_iterations]; // Reset the timestamp. paths_timestamp = welt->get_base_pathing_counter(); } - const uint32 total_halts = alle_haltestellen.get_count(); - const sint32 max_transfers = welt->get_einstellungen()->get_max_transfers(); - const uint32 max_depth = total_halts * max_transfers; - const uint32 max_iterations = max_depth <= 65535 ? max_depth : 65535; - - path_node* path_nodes = new path_node[max_iterations]; - if(open_list.get_count() < 1) { // Only reset the list if it is empty, so as to allow for re-using the open @@ -1426,6 +1437,7 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) // can be resumed where it left off if another goal, as yet // not found, is searched for, unless the index is stale. + //delete[] path_nodes; return; } @@ -1434,6 +1446,7 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) // If the code has reached here without returning, the search is complete. search_complete = true; + //delete[] path_nodes; } haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category) diff --git a/simhalt.h b/simhalt.h index f6f15146d6e..53dfc63be74 100644 --- a/simhalt.h +++ b/simhalt.h @@ -243,6 +243,10 @@ class haltestelle_t // detecting when max_transfers has been reached. uint16 iterations; + // Allocation of memory for nodes used during the pathing search. + // @author: jamespetts + path_node* path_nodes; + #else // List with all reachable destinations (old method) vector_tpl<halthandle_t>* warenziele; diff --git a/simversion.h b/simversion.h index 8e7675eb199..467f4c79e5b 100644 --- a/simversion.h +++ b/simversion.h @@ -14,7 +14,7 @@ #define SAVEGAME_VER_NR "0.102.1" #define SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR) -#define EXPERIMENTAL_VERSION L"2.1" +#define EXPERIMENTAL_VERSION L"2.2" #define EXPERIMENTAL_VER_NR ".2" #define EXPERIMENTAL_SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) #define COMBINED_VER_NR (SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) diff --git a/simwin.cc b/simwin.cc index bf7ac844700..47a349401b1 100644 --- a/simwin.cc +++ b/simwin.cc @@ -1091,7 +1091,7 @@ void win_display_flush(double konto) //#ifdef DEBUG // case 4: sprintf(time, "%s, %d %s %d %d:%02dh TICKS: %li", //#else - case 4: sprintf(time, "%s, %d %s %d %u:%02uh", + case 4: sprintf(time, "%s, %d %s %lld %u:%02uh", //#endif translator::translate(seasons[wl->get_jahreszeit()]), //Season tage, //Day @@ -1107,7 +1107,7 @@ void win_display_flush(double konto) ); break; // us style - case 3: sprintf(time, "%s, %s %d %d %2d:%02d%s", + case 3: sprintf(time, "%s, %s %d %lld %2d:%02d%s", translator::translate(seasons[wl->get_jahreszeit()]), translator::get_month_name(month%12), tage, @@ -1118,7 +1118,7 @@ void win_display_flush(double konto) ); break; // japanese style - case 2: sprintf(time, "%s, %d/%s/%d %2d:%02dh", + case 2: sprintf(time, "%s, %lld/%s/%d %2d:%02dh", translator::translate(seasons[wl->get_jahreszeit()]), year, translator::get_month_name(month%12), @@ -1128,7 +1128,7 @@ void win_display_flush(double konto) ); break; // just month - case 1: sprintf(time, "%s, %s %d %2d:%02dh", + case 1: sprintf(time, "%s, %s %lld %2d:%02dh", translator::get_month_name(month%12), translator::translate(seasons[wl->get_jahreszeit()]), year, @@ -1137,7 +1137,7 @@ void win_display_flush(double konto) ); break; // just only season - default: sprintf(time, "%s %d", + default: sprintf(time, "%s %lld", translator::translate(seasons[wl->get_jahreszeit()]), year); break; diff --git a/tpl/weighted_vector_tpl.h b/tpl/weighted_vector_tpl.h index 33615afea02..25927aea6b8 100644 --- a/tpl/weighted_vector_tpl.h +++ b/tpl/weighted_vector_tpl.h @@ -214,8 +214,9 @@ template<class T> class weighted_vector_tpl /** removes element, if contained */ bool remove(T elem) { - for (uint32 i = 0; i < count; i++) { - if (nodes[i].data == elem) return remove_at(i); + for (uint32 i = 0; i < count; i++) + { + if (nodes != NULL && nodes[i].data == elem) return remove_at(i); } return false; } From bf0e0a5dfc259f6662bad62c20b3e58c3f98703e Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Tue, 14 Apr 2009 09:36:34 +0100 Subject: [PATCH 57/61] Some improvements in memory management. --- simhalt.cc | 29 +++++++++++++++++++++++------ simhalt.h | 2 +- simversion.h | 2 +- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/simhalt.cc b/simhalt.cc index 0e2c501df58..197dd741fa1 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -250,6 +250,7 @@ haltestelle_t::haltestelle_t(karte_t* wl, loadsave_t* file) #ifdef NEW_PATHING iterations = 0; search_complete = false; + waiting_times = new quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>>[warenbauer_t::get_max_catg_index()]; #else warenziele = new vector_tpl<halthandle_t>[ warenbauer_t::get_max_catg_index() ]; #endif @@ -299,6 +300,7 @@ haltestelle_t::haltestelle_t(karte_t* wl, koord k, spieler_t* sp) #ifdef NEW_PATHING iterations = 0; search_complete = false; + waiting_times = new quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>>[warenbauer_t::get_max_catg_index()]; #else warenziele = new vector_tpl<halthandle_t>[ warenbauer_t::get_max_catg_index() ]; #endif @@ -400,6 +402,11 @@ haltestelle_t::~haltestelle_t() // These do not work: access violations result. Not clear why. //delete[] connexions; //delete[] paths; + if(!open_list.empty()) + { + delete[] path_nodes; + } + delete[] waiting_times; #else delete[] warenziele; #endif @@ -1331,9 +1338,6 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) open_list.clear(); delete[] path_nodes; } - - path_nodes = new path_node[max_iterations]; - } if(paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) { @@ -1346,8 +1350,6 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) delete[] path_nodes; } - path_nodes = new path_node[max_iterations]; - // Reset the timestamp. paths_timestamp = welt->get_base_pathing_counter(); } @@ -1356,6 +1358,8 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) { // Only reset the list if it is empty, so as to allow for re-using the open // list on subsequent occasions of finding a path. + path_nodes = new path_node[max_iterations]; + iterations = 0; path_node* starting_node = &path_nodes[iterations++]; starting_node->halt = self; @@ -2855,13 +2859,26 @@ void haltestelle_t::rdwr(loadsave_t *file) { uint16 halts_count; file->rdwr_short(halts_count, ""); - for(uint16 i = 0; i < halts_count; i ++) + for(uint16 k = 0; k < halts_count; k ++) { koord halt_position; halt_position.rdwr(file); if(halt_position != koord::invalid) { halthandle_t current_halt = welt->lookup(halt_position)->get_halt(); + if(!current_halt.is_bound()) + { + // The halt was not properly saved, + // or was removed at some point. + uint8 waiting_time_count; + file->rdwr_byte(waiting_time_count, ""); + for(uint8 j = 0; j < waiting_time_count; j ++) + { + uint16 current_time; + file->rdwr_short(current_time, ""); + } + continue; + } fixed_list_tpl<uint16, 16> list; uint8 waiting_time_count; file->rdwr_byte(waiting_time_count, ""); diff --git a/simhalt.h b/simhalt.h index 53dfc63be74..31167740ff3 100644 --- a/simhalt.h +++ b/simhalt.h @@ -346,7 +346,7 @@ class haltestelle_t // Record of waiting times. Takes a list of the last 16 waiting times per type of goods. // Getter method will need to average the waiting times. // @author: jamespetts - quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>> waiting_times[16]; + quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>>* waiting_times; #ifdef NEW_PATHING // Used for pathfinding. The list is stored on the heap so that it can be re-used diff --git a/simversion.h b/simversion.h index 467f4c79e5b..79529947f81 100644 --- a/simversion.h +++ b/simversion.h @@ -14,7 +14,7 @@ #define SAVEGAME_VER_NR "0.102.1" #define SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR) -#define EXPERIMENTAL_VERSION L"2.2" +#define EXPERIMENTAL_VERSION L"2.3" #define EXPERIMENTAL_VER_NR ".2" #define EXPERIMENTAL_SAVEGAME_VERSION (SAVEGAME_PREFIX SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) #define COMBINED_VER_NR (SAVEGAME_VER_NR EXPERIMENTAL_VER_NR) From 43da7a50fb8d7e5d4e894b830fd3ed3ac8e35d33 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Wed, 15 Apr 2009 21:49:06 +0100 Subject: [PATCH 58/61] CHANGE: Further memory optimisations. FIX: Returning passengers that could not find a route were added in any event to the station with a next transfer of "unknown". FIX: Crashes in some cases on deleting halts. --- gui/halt_detail.cc | 10 +-- player/ai_passenger.cc | 8 +- simcity.cc | 16 +++- simconvoi.cc | 6 +- simhalt.cc | 177 +++++++++++++++++++++++++---------------- simhalt.h | 12 ++- vehicle/simvehikel.cc | 5 +- 7 files changed, 142 insertions(+), 92 deletions(-) diff --git a/gui/halt_detail.cc b/gui/halt_detail.cc index b9b0431d9f1..d7ad5ec5384 100644 --- a/gui/halt_detail.cc +++ b/gui/halt_detail.cc @@ -210,7 +210,7 @@ void halt_detail_t::halt_detail_info(cbuffer_t & buf) { #ifdef NEW_PATHING - const quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion> *connexions = halt->get_connexions(i); + const quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion*> *connexions = halt->get_connexions(i); #else const vector_tpl<halthandle_t> *ziele = halt->get_warenziele(i); if(!ziele->empty()) @@ -230,11 +230,11 @@ void halt_detail_t::halt_detail_info(cbuffer_t & buf) buf.append(":\n"); offset_y += LINESPACE; #ifdef NEW_PATHING - quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*connexions); + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion*> iter(*connexions); while(iter.next()) { halthandle_t a_halt = iter.get_current_key(); - haltestelle_t::connexion cnx = iter.get_current_value(); + haltestelle_t::connexion* cnx = iter.get_current_value(); #else for( uint32 idx=0; idx < ziele->get_count(); idx++ ) { halthandle_t a_halt = (*ziele)[idx]; @@ -259,10 +259,10 @@ void halt_detail_t::halt_detail_info(cbuffer_t & buf) buf.append("\n"); #ifdef NEW_PATHING buf.append("("); - buf.append(cnx.journey_time * 0.1); // Convert from tenths + buf.append(cnx->journey_time * 0.1); // Convert from tenths buf.append(translator::translate(" mins. travelling")); buf.append(", "); - buf.append(cnx.waiting_time * 0.1); // Convert from tenths + buf.append(cnx->waiting_time * 0.1); // Convert from tenths buf.append(translator::translate(" mins. waiting)")); buf.append("\n"); diff --git a/player/ai_passenger.cc b/player/ai_passenger.cc index a6de144e400..4aec1aa7a5a 100755 --- a/player/ai_passenger.cc +++ b/player/ai_passenger.cc @@ -215,7 +215,7 @@ bool ai_passenger_t::create_water_transport_vehikel(const stadt_t* start_stadt, start_hub = halthandle_t(); // is there already one harbour next to this one? #ifdef NEW_PATHING - quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*start_connect_hub->get_connexions(0)); + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion*> iter(*start_connect_hub->get_connexions(0)); while(iter.next()) { halthandle_t h = iter.get_current_key(); @@ -253,7 +253,7 @@ bool ai_passenger_t::create_water_transport_vehikel(const stadt_t* start_stadt, end_hub = halthandle_t(); // is there already one harbour next to this one? #ifdef NEW_PATHING - quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*end_connect_hub->get_connexions(0)); + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion*> iter(*end_connect_hub->get_connexions(0)); while(iter.next()) { halthandle_t h = iter.get_current_key(); @@ -663,7 +663,7 @@ bool ai_passenger_t::create_air_transport_vehikel(const stadt_t *start_stadt, co start_hub = halthandle_t(); // is there already one airport next to this town? #ifdef NEW_PATHING - quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*start_connect_hub->get_connexions(0)); + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion*> iter(*start_connect_hub->get_connexions(0)); while(iter.next()) { halthandle_t h = iter.get_current_key(); @@ -699,7 +699,7 @@ bool ai_passenger_t::create_air_transport_vehikel(const stadt_t *start_stadt, co end_hub = halthandle_t(); // is there already one airport next to this town? #ifdef NEW_PATHING - quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion> iter(*end_connect_hub->get_connexions(0)); + quickstone_hashtable_iterator_tpl<haltestelle_t, haltestelle_t::connexion*> iter(*end_connect_hub->get_connexions(0)); while(iter.next()) { halthandle_t h = iter.get_current_key(); diff --git a/simcity.cc b/simcity.cc index f0f8479c824..c22aba11cf4 100644 --- a/simcity.cc +++ b/simcity.cc @@ -2220,12 +2220,20 @@ void stadt_t::step_passagiere() return_pax.set_zwischenziel(welt->lookup(return_zwischenziel)->get_halt()); return_pax.set_journey_steps(best_journey_steps); #else - ret_halt->find_route(return_pax); + if(ret_halt->find_route(return_pax) != 65535) + { #endif - return_pax.arrival_time = welt->get_zeit_ms(); + return_pax.arrival_time = welt->get_zeit_ms(); - ret_halt->starte_mit_route(return_pax); - ret_halt->add_pax_happy(pax_left_to_do); + ret_halt->starte_mit_route(return_pax); + ret_halt->add_pax_happy(pax_left_to_do); +#ifdef NEW_PATHING + } + else + { + ret_halt->add_pax_no_route(pax_left_to_do); + } +#endif } else { diff --git a/simconvoi.cc b/simconvoi.cc index 0337e75d17c..53fb772b869 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -2954,7 +2954,9 @@ sint64 convoi_t::calc_revenue(ware_t& ware) // Cannot not charge for journey if the journey distance is more than a certain proportion of the straight line distance. // This eliminates the possibility of cheating by building circuitous routes, or the need to prevent that by always using // the straight line distance, which makes the game difficult and unrealistic. - const uint32 max_distance = accurate_distance(ware.get_origin()->get_basis_pos(), fahr[0]->get_pos().get_2d()) * 2.2; + // If the origin has been deleted since the packet departed, then the best that we can do is guess by + // trebling the distance to the last stop. + const uint32 max_distance = ware.get_origin().is_bound() ? accurate_distance(ware.get_origin()->get_basis_pos(), fahr[0]->get_pos().get_2d()) * 2.2 : 3 * accurate_distance(last_stop_pos.get_2d(), fahr[0]->get_pos().get_2d()); const uint32 distance = ware.get_accumulated_distance(); const uint32 revenue_distance = distance < max_distance ? distance : max_distance; @@ -2973,7 +2975,7 @@ sint64 convoi_t::calc_revenue(ware_t& ware) const sint64 revenue = (sint64)(min_price > base_bonus ? min_price : base_bonus) * (sint64)revenue_distance * (sint64)ware.menge; sint64 final_revenue = revenue; - const float happy_ratio = ware.get_origin()->get_unhappy_proportion(1); + const float happy_ratio = ware.get_origin().is_bound() ? ware.get_origin()->get_unhappy_proportion(1) : 1; if(speed_bonus_rating > 0 && happy_ratio > 0) { // Reduce revenue if the origin stop is crowded, if speed is important for the cargo. diff --git a/simhalt.cc b/simhalt.cc index 197dd741fa1..31e5edc2272 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -251,6 +251,8 @@ haltestelle_t::haltestelle_t(karte_t* wl, loadsave_t* file) iterations = 0; search_complete = false; waiting_times = new quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>>[warenbauer_t::get_max_catg_index()]; + connexions = new quickstone_hashtable_tpl<haltestelle_t, connexion*>[warenbauer_t::get_max_catg_index()]; + paths = new quickstone_hashtable_tpl<haltestelle_t, path>[warenbauer_t::get_max_catg_index()]; #else warenziele = new vector_tpl<halthandle_t>[ warenbauer_t::get_max_catg_index() ]; #endif @@ -301,6 +303,8 @@ haltestelle_t::haltestelle_t(karte_t* wl, koord k, spieler_t* sp) iterations = 0; search_complete = false; waiting_times = new quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>>[warenbauer_t::get_max_catg_index()]; + connexions = new quickstone_hashtable_tpl<haltestelle_t, connexion*>[warenbauer_t::get_max_catg_index()]; + paths = new quickstone_hashtable_tpl<haltestelle_t, path>[warenbauer_t::get_max_catg_index()]; #else warenziele = new vector_tpl<halthandle_t>[ warenbauer_t::get_max_catg_index() ]; #endif @@ -399,9 +403,13 @@ haltestelle_t::~haltestelle_t() } free( waren ); #ifdef NEW_PATHING - // These do not work: access violations result. Not clear why. - //delete[] connexions; - //delete[] paths; + for(uint8 i = 0; i < warenbauer_t::get_max_catg_index(); i ++) + { + reset_connexions(i); + } + + delete[] connexions; + delete[] paths; if(!open_list.empty()) { delete[] path_nodes; @@ -809,8 +817,10 @@ void haltestelle_t::reroute_goods() // reroute only on demand reroute_counter = welt->get_schedule_counter(); - for(unsigned i=0; i<warenbauer_t::get_max_catg_index(); i++) { - if(waren[i]) { + for(unsigned i=0; i<warenbauer_t::get_max_catg_index(); i++) + { + if(waren[i]) + { vector_tpl<ware_t> * warray = waren[i]; vector_tpl<ware_t> * new_warray = new vector_tpl<ware_t>(warray->get_count()); @@ -819,17 +829,21 @@ void haltestelle_t::reroute_goods() // world layout, remove all goods which destination was removed from the map // prissi; // also the empty entries of the array are cleared - for(int j=warray->get_count()-1; j>=0; j-- ) { + for(int j = warray->get_count() - 1; j >= 0; j--) + { ware_t & ware = (*warray)[j]; - if(ware.menge == 0) { + if(ware.menge == 0) + { continue; } // since also the factory halt list is added to the ground, we can use just this ... - if(welt->lookup(ware.get_zielpos())->is_connected(self)) { + if(welt->lookup(ware.get_zielpos())->is_connected(self)) + { // we are already there! - if(ware.is_freight()) { + if(ware.is_freight()) + { liefere_an_fabrik(ware); } continue; @@ -850,17 +864,19 @@ void haltestelle_t::reroute_goods() // add to new array new_warray->append( ware ); - } - - // TESTING CODE - - + } INT_CHECK( "simhalt.cc 489" ); -#ifndef NEW_PATHING + // delete, if nothing connects here - if (new_warray->empty()) { - if( warenziele[i].empty() ) { + if (new_warray->empty()) + { +#ifndef NEW_PATHING + if(warenziele[i].empty()) +#else + if(connexions[i].empty()) +#endif + { // no connections from here => delete delete new_warray; new_warray = NULL; @@ -870,9 +886,9 @@ void haltestelle_t::reroute_goods() // replace the array delete waren[i]; waren[i] = new_warray; -#endif } } +//#endif // likely the display must be updated after this resort_freight_info = true; } @@ -986,8 +1002,8 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp } // Check the journey times to the connexion - connexion new_connexion; - new_connexion.waiting_time = get_average_waiting_time(halt, type->get_catg_index()); + connexion* new_connexion = new connexion; + new_connexion->waiting_time = get_average_waiting_time(halt, type->get_catg_index()); // Check the average speed. uint16 average_speed = 0; @@ -1063,16 +1079,16 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp } } // Journey time in *tenths* of minutes. - new_connexion.journey_time = (((float)journey_distance / (float)average_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 600); - new_connexion.best_convoy = cnv; - new_connexion.best_line = line; + new_connexion->journey_time = (((float)journey_distance / (float)average_speed) * welt->get_einstellungen()->get_journey_time_multiplier() * 600); + new_connexion->best_convoy = cnv; + new_connexion->best_line = line; // Check whether this is the best connexion so far, and, if so, add it. if(!connexions[type->get_catg_index()].put(halt, new_connexion)) { // The key exists in the hashtable already - check whether this entry is better. - const connexion existing_connexion = connexions[type->get_catg_index()].get(halt); - if(existing_connexion.journey_time > new_connexion.journey_time) + const connexion* existing_connexion = connexions[type->get_catg_index()].get(halt); + if(existing_connexion->journey_time > new_connexion->journey_time) { // The new connexion is better - replace it. connexions[type->get_catg_index()].set(halt, new_connexion); @@ -1091,13 +1107,23 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp linehandle_t haltestelle_t::get_preferred_line(halthandle_t transfer, uint8 category) const { - linehandle_t best_line = connexions[category].get(transfer).best_line; + if(connexions[category].empty() || connexions[category].get(transfer) == NULL) + { + linehandle_t dummy; + return dummy; + } + linehandle_t best_line = connexions[category].get(transfer)->best_line; return best_line; } convoihandle_t haltestelle_t::get_preferred_convoy(halthandle_t transfer, uint8 category) const { - convoihandle_t best_convoy = connexions[category].get(transfer).best_convoy; + if(connexions[category].empty() || connexions[category].get(transfer) == NULL) + { + convoihandle_t dummy; + return dummy; + } + convoihandle_t best_convoy = connexions[category].get(transfer)->best_convoy; return best_convoy; } @@ -1181,10 +1207,31 @@ void haltestelle_t::rebuild_destinations() #else +void haltestelle_t::reset_connexions(uint8 category) +{ + if(connexions[category].empty()) + { + // Nothing to do here + return; + } + + quickstone_hashtable_iterator_tpl<haltestelle_t, connexion*> iter(connexions[category]); + + // Delete the connexions. + while(iter.next()) + { + delete iter.get_current_value(); + } + + + // Finally, clear the collection class. + connexions[category].clear(); +} + //@author: jamespetts (although much is taken from the original rebuild_destinations()) void haltestelle_t::rebuild_connexions(uint8 category) { - connexions[category].clear(); + reset_connexions(category); connexions_timestamp = welt->get_base_pathing_counter(); if(connexions_timestamp == 0 || reschedule) { @@ -1354,7 +1401,7 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) paths_timestamp = welt->get_base_pathing_counter(); } - if(open_list.get_count() < 1) + if(open_list.empty()) { // Only reset the list if it is empty, so as to allow for re-using the open // list on subsequent occasions of finding a path. @@ -1371,19 +1418,18 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) while(open_list.get_count() > 0 && iterations < max_iterations) { path_node* current_node = open_list.pop(); - assert(current_node->halt.is_bound()); - - uint32 open_list_count = open_list.get_count(); - if(paths[category].get(current_node->halt).journey_time != 65535) + if(!current_node->halt.is_bound() || paths[category].get(current_node->halt).journey_time != 65535) { // Only insert into the open list if the - // item is not already on the closed list + // item is not already on the closed list, + // and the halt has not been deleted since + // being added to the open list. continue; } - quickstone_hashtable_tpl<haltestelle_t, connexion> *current_connexions = current_node->halt->get_connexions(category); - quickstone_hashtable_iterator_tpl<haltestelle_t, connexion> iter(*current_connexions); + quickstone_hashtable_tpl<haltestelle_t, connexion*> *current_connexions = current_node->halt->get_connexions(category); + quickstone_hashtable_iterator_tpl<haltestelle_t, connexion*> iter(*current_connexions); while(iter.next() && iterations <= max_iterations) { const halthandle_t h = iter.get_current_key(); @@ -1394,11 +1440,10 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) continue; } - //open_list_count = open_list.get_count(); - connexion current_connexion = iter.get_current_value(); + connexion* current_connexion = iter.get_current_value(); path_node* new_node = &path_nodes[iterations++]; new_node->halt = h; - new_node->journey_time = current_connexion.journey_time + current_connexion.waiting_time + current_node->journey_time; + new_node->journey_time = current_connexion->journey_time + current_connexion->waiting_time + current_node->journey_time; new_node->link = current_node; open_list.insert(new_node); @@ -1408,8 +1453,6 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) path new_path; new_path.journey_time = current_node->journey_time; - open_list_count = open_list.get_count(); - // Add only if not already contained and it is not the head node. if(current_node->link != NULL && paths[category].put(current_node->halt, new_path)) { @@ -1421,7 +1464,10 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) { if(track_node->link->link == NULL && track_node->halt.is_bound()) { - paths[category].access(current_node->halt)->next_transfer = track_node->halt; + //path tmp = *paths[category].access(current_node->halt); + //tmp.next_transfer = track_node->halt; + //tmp = NULL; + paths[category].access(current_node->halt) ->next_transfer = track_node->halt; break; } @@ -1441,7 +1487,6 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) // can be resumed where it left off if another goal, as yet // not found, is searched for, unless the index is stale. - //delete[] path_nodes; return; } @@ -1450,9 +1495,10 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) // If the code has reached here without returning, the search is complete. search_complete = true; - //delete[] path_nodes; } + + haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category) { assert(goal.is_bound()); @@ -1493,7 +1539,7 @@ haltestelle_t::path haltestelle_t::get_path_to(halthandle_t goal, uint8 category return destination_path; } -quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion>* haltestelle_t::get_connexions(uint8 c) +quickstone_hashtable_tpl<haltestelle_t, haltestelle_t::connexion*>* haltestelle_t::get_connexions(uint8 c) { if(reschedule || connexions->get_count() == 0 || paths_timestamp < welt->get_base_pathing_counter() - welt->get_einstellungen()->get_max_rerouting_interval_months() || welt->get_base_pathing_counter() >= (65535 - welt->get_einstellungen()->get_max_rerouting_interval_months())) @@ -1547,7 +1593,7 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim } } - if( ziel_list.empty() ) + if(ziel_list.empty()) { //no target station found ware.set_ziel(halthandle_t()); @@ -1560,28 +1606,16 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim { ware.set_ziel(self); ware.set_zwischenziel( halthandle_t()); - return 0; + return 65535; } sint16 best_destination = -1; - const uint8 test_1 = ware.get_catg(); - const uint8 test_2 = ware.get_index(); - const uint8 test_3 = ware.get_besch()->get_catg(); - const uint8 test_4 = ware.get_besch()->get_catg_index(); - const char* test_5 = ware.get_name(); - const char* test_6 = ware.get_besch()->get_catg_name(); - uint8 a = 1 + 1; - // Now, find the best route from here. ITERATE(ziel_list,i) { path test_path = get_path_to(ziel_list[i], ware.get_besch()->get_catg_index()); - if(!test_path.next_transfer.is_bound()) - { - continue; - } - if(test_path.journey_time < journey_time) + if(test_path.journey_time != 65535 && test_path.next_transfer.is_bound()) { journey_time = test_path.journey_time; best_destination = i; @@ -1594,8 +1628,13 @@ uint16 haltestelle_t::find_route(ware_t &ware, const uint16 previous_journey_tim // only set the details if it is the best route so far. ware.set_ziel(ziel_list[best_destination]); path final_path = get_path_to(ziel_list[best_destination], ware.get_besch()->get_catg_index()); - ware.set_zwischenziel(final_path.next_transfer); - return final_path.journey_time; + if(final_path.next_transfer.is_bound()) + { + ware.set_zwischenziel(final_path.next_transfer); + return final_path.journey_time; + } + // If the next transfer is not bound, something has gone wrong. + return 65535; } return journey_time; @@ -1939,7 +1978,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t // because we have to keep the current haltestelle // loop starts from 1, i.e. the next stop (Google) - for( uint8 i=1; i<count; i++ ) + for(uint8 i = 1; i < count; i++) { const uint8 wrap_i = (i + fpl->get_aktuell()) % count; @@ -1949,7 +1988,7 @@ ware_t haltestelle_t::hole_ab(const ware_besch_t *wtyp, uint32 maxi, schedule_t // we will come later here again ... break; } - else if( plan_halt.is_bound() && warray->get_count()>0 ) + else if(plan_halt.is_bound() && warray->get_count() > 0) { // The random offset will ensure that all goods have an equal chance to be loaded. @@ -2919,21 +2958,23 @@ void haltestelle_t::rdwr(loadsave_t *file) //"Load lock" (Google) void haltestelle_t::laden_abschliessen() { - if(besitzer_p==NULL) { + if(besitzer_p==NULL) + { return; } // fix good destination coordinates for(unsigned i=0; i<warenbauer_t::get_max_catg_index(); i++) { - if(waren[i]) { + if(waren[i]) + { vector_tpl<ware_t> * warray = waren[i]; - for(unsigned j=0; j<warray->get_count(); j++) + ITERATE_PTR(warray,j) { (*warray)[j].laden_abschliessen(welt); } // merge identical entries (should only happen with old games) - for(unsigned j=0; j<warray->get_count(); j++) + ITERATE_PTR(warray,j) { if( (*warray)[j].menge==0 ) { diff --git a/simhalt.h b/simhalt.h index 31167740ff3..03b713c900d 100644 --- a/simhalt.h +++ b/simhalt.h @@ -8,10 +8,6 @@ #ifndef simhalt_h #define simhalt_h -//#ifndef OLD_PATHING -//#define NEW_PATHING -//#endif - #include "convoihandle_t.h" #include "linehandle_t.h" #include "halthandle_t.h" @@ -235,9 +231,9 @@ class haltestelle_t #ifdef NEW_PATHING // Table of all direct connexions to this halt, with routing information. // Array: one entry per goods type. - quickstone_hashtable_tpl<haltestelle_t, connexion> connexions[16]; + quickstone_hashtable_tpl<haltestelle_t, connexion*> *connexions; - quickstone_hashtable_tpl<haltestelle_t, path> paths[16]; + quickstone_hashtable_tpl<haltestelle_t, path> *paths; // The number of iterations of paths currently traversed. Used for // detecting when max_transfers has been reached. @@ -247,6 +243,8 @@ class haltestelle_t // @author: jamespetts path_node* path_nodes; + void reset_connexions(uint8 category); + #else // List with all reachable destinations (old method) vector_tpl<halthandle_t>* warenziele; @@ -766,7 +764,7 @@ class haltestelle_t inline uint16 get_waiting_minutes(uint32 waiting_ticks) const; #ifdef NEW_PATHING - quickstone_hashtable_tpl<haltestelle_t, connexion>* get_connexions(uint8 c); + quickstone_hashtable_tpl<haltestelle_t, connexion*>* get_connexions(uint8 c); // Finds the best path from here to the goal halt. // Looks up the paths in the hashtable - if the table diff --git a/vehicle/simvehikel.cc b/vehicle/simvehikel.cc index 299b7c69fc8..1c3237c065f 100644 --- a/vehicle/simvehikel.cc +++ b/vehicle/simvehikel.cc @@ -805,8 +805,8 @@ bool vehikel_t::load_freight(halthandle_t halt, bool overcrowd) //hinein = inside (Google) ware_t ware = halt->hole_ab(besch->get_ware(), hinein, fpl, cnv); - - if(ware.menge==0) + + if(ware.menge == 0) { // now empty, but usually, we can get it here ... return ok; @@ -829,6 +829,7 @@ bool vehikel_t::load_freight(halthandle_t halt, bool overcrowd) // New system: only merges if origins are alike. // @author: jamespetts + if(ware.can_merge_with(tmp)) { tmp.menge += ware.menge; From 61fd0a79cd998dbd5fc7addfbc9fe3b715bca376 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Wed, 15 Apr 2009 22:46:18 +0100 Subject: [PATCH 59/61] FIX: Further memory leak. --- simhalt.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/simhalt.cc b/simhalt.cc index 31e5edc2272..ae01ff672ac 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -988,6 +988,7 @@ uint16 haltestelle_t::get_average_waiting_time(halthandle_t halt, uint8 category void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fpl, const convoihandle_t cnv, const linehandle_t line) { + if(type != warenbauer_t::nichts) { ITERATE_PTR(fpl,i) @@ -1087,12 +1088,17 @@ void haltestelle_t::add_connexion(const ware_besch_t *type, const schedule_t *fp if(!connexions[type->get_catg_index()].put(halt, new_connexion)) { // The key exists in the hashtable already - check whether this entry is better. - const connexion* existing_connexion = connexions[type->get_catg_index()].get(halt); + connexion* existing_connexion = connexions[type->get_catg_index()].get(halt); if(existing_connexion->journey_time > new_connexion->journey_time) { // The new connexion is better - replace it. + delete existing_connexion; connexions[type->get_catg_index()].set(halt, new_connexion); } + else + { + delete new_connexion; + } //TODO: Consider whether to add code for comfort here, too. if( waren[type->get_catg_index()] == NULL ) @@ -1230,7 +1236,7 @@ void haltestelle_t::reset_connexions(uint8 category) //@author: jamespetts (although much is taken from the original rebuild_destinations()) void haltestelle_t::rebuild_connexions(uint8 category) -{ +{ reset_connexions(category); connexions_timestamp = welt->get_base_pathing_counter(); if(connexions_timestamp == 0 || reschedule) @@ -1362,7 +1368,7 @@ void haltestelle_t::calculate_paths(halthandle_t goal, uint8 category) // not until a destination from this halt is requested, to prevent // the game pausing and becoming unresponsive whilst everything is // re-calculated all at the same time. - + if((category == 0 && !get_pax_enabled()) || (category == 1 && !get_post_enabled()) || (category > 1 && !get_ware_enabled())) { // Cannot route from this station: do not try. From b4b9ffadc2defdf7e6062dd3123c278a90fe25b5 Mon Sep 17 00:00:00 2001 From: "James E. Petts" <jamespetts@yahoo.com> Date: Thu, 16 Apr 2009 23:01:16 +0100 Subject: [PATCH 60/61] CHANGE: AI players now try to build roads for which their vehicles are not too heavy. --- bauer/tunnelbauer.cc | 4 ++-- bauer/wegbauer.cc | 33 +++++++++++++++++++++++++++++++++ bauer/wegbauer.h | 4 +++- player/ai_goods.cc | 2 +- player/ai_passenger.cc | 8 ++++---- 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/bauer/tunnelbauer.cc b/bauer/tunnelbauer.cc index 8eccad95f2f..9901d339e4f 100644 --- a/bauer/tunnelbauer.cc +++ b/bauer/tunnelbauer.cc @@ -296,8 +296,8 @@ DBG_MESSAGE("tunnelbauer_t::baue()","build from (%d,%d,%d) to (%d,%d,%d) ", pos. // now we seach a matchin way for the tunnels top speed const weg_besch_t *weg_besch = besch->get_weg_besch(); if(weg_besch==NULL) { - // now we seach a matchin wy for the tunnels top speed - weg_besch = wegbauer_t::weg_search( wegtyp, besch->get_topspeed(), welt->get_timeline_year_month(), weg_t::type_flat ); + // now we seach a matching way for the tunnels top speed + weg_besch = wegbauer_t::weg_search( wegtyp, besch->get_topspeed(), besch->get_max_weight(), welt->get_timeline_year_month(), weg_t::type_flat ); } const weg_besch_t *einfahrt_weg_besch = baue_einfahrt(welt, sp, pos, zv, besch, NULL, cost); diff --git a/bauer/wegbauer.cc b/bauer/wegbauer.cc index 08caf456d6c..ab0c1ffda4d 100644 --- a/bauer/wegbauer.cc +++ b/bauer/wegbauer.cc @@ -142,6 +142,39 @@ const weg_besch_t* wegbauer_t::weg_search(const waytype_t wtyp, const uint32 spe return best; } +// Finds a way with a given speed *and* weight limit +// for a given way type. +// @author: jamespetts (slightly adapted from the standard version with just speed limit) +const weg_besch_t* wegbauer_t::weg_search(const waytype_t wtyp, const uint32 speed_limit, const uint32 weight_limit, const uint16 time, const weg_t::system_type system_type) +{ + const weg_besch_t* best = NULL; + for( stringhashtable_iterator_tpl<const weg_besch_t*> iter(alle_wegtypen); iter.next(); ) + { + const weg_besch_t* const test = iter.get_current_value(); + if( ((test->get_wtyp()==wtyp && + (test->get_styp()==system_type || system_type==weg_t::type_all)) || (test->get_wtyp()==track_wt && test->get_styp()==weg_t::type_tram && wtyp==tram_wt)) + && test->get_cursor()->get_bild_nr(1)!=IMG_LEER ) + { + if( best==NULL || time==0 || (test->get_intro_year_month()<=time && time<test->get_retire_year_month())) + { + if( best == NULL || + ((best->get_topspeed() < speed_limit && test->get_topspeed() >= speed_limit) || + (best->get_max_weight() < weight_limit && test->get_max_weight() >= weight_limit)) || + ((test->get_topspeed() <= speed_limit && best->get_topspeed() < test->get_topspeed()) || + (((test->get_max_weight() <= weight_limit && best->get_max_weight() < test->get_max_weight())))) || + ((best->get_topspeed() > speed_limit && test->get_topspeed() < best->get_topspeed()) || + ((best->get_max_weight() > weight_limit && test->get_max_weight()) < best->get_max_weight())) || + (time != 0 && (best->get_intro_year_month()>time || time>=best->get_retire_year_month())) + ) + { + best = test; + } + } + } + } + return best; +} + const weg_besch_t * wegbauer_t::get_besch(const char * way_name,const uint16 time) diff --git a/bauer/wegbauer.h b/bauer/wegbauer.h index ca3508a9a8c..3d8a74e6aa2 100644 --- a/bauer/wegbauer.h +++ b/bauer/wegbauer.h @@ -44,7 +44,9 @@ class wegbauer_t * Finds a way with a given speed limit for a given waytype * @author prissi */ - static const weg_besch_t * weg_search(const waytype_t wtyp,const uint32 speed_limit,const uint16 time, const weg_t::system_type system_type); + static const weg_besch_t * weg_search(const waytype_t wtyp,const uint32 speed_limit, const uint16 time, const weg_t::system_type system_type); + + static const weg_besch_t * weg_search(const waytype_t wtyp,const uint32 speed_limit, const uint32 weight_limit, const uint16 time, const weg_t::system_type system_type); static const weg_besch_t * get_besch(const char *way_name,const uint16 time=0); diff --git a/player/ai_goods.cc b/player/ai_goods.cc index f0290050e1f..7b462c402bc 100755 --- a/player/ai_goods.cc +++ b/player/ai_goods.cc @@ -835,7 +835,7 @@ DBG_MESSAGE("do_ki()","check railway"); if( road_vehicle!=NULL ) { best_road_speed = road_vehicle->get_geschw(); // find cheapest road - road_weg = wegbauer_t::weg_search( road_wt, best_road_speed, welt->get_timeline_year_month(),weg_t::type_flat ); + road_weg = wegbauer_t::weg_search( road_wt, best_road_speed, road_vehicle->get_gewicht(), welt->get_timeline_year_month(),weg_t::type_flat ); if( road_weg!=NULL ) { if( best_road_speed>road_weg->get_topspeed() ) { best_road_speed = road_weg->get_topspeed(); diff --git a/player/ai_passenger.cc b/player/ai_passenger.cc index 4aec1aa7a5a..8e325bb32f3 100755 --- a/player/ai_passenger.cc +++ b/player/ai_passenger.cc @@ -306,7 +306,7 @@ bool ai_passenger_t::create_water_transport_vehikel(const stadt_t* start_stadt, if(town_road!=bushalt) { wegbauer_t bauigel(welt, this); // no bridges => otherwise first tile might be bridge start ... - bauigel.route_fuer( wegbauer_t::strasse, wegbauer_t::weg_search( road_wt, 25, welt->get_timeline_year_month(), weg_t::type_flat ), tunnelbauer_t::find_tunnel(road_wt,road_vehicle->get_geschw(),welt->get_timeline_year_month()), NULL ); + bauigel.route_fuer( wegbauer_t::strasse, wegbauer_t::weg_search( road_wt, road_vehicle->get_geschw(), road_vehicle->get_gewicht(), welt->get_timeline_year_month(), weg_t::type_flat ), tunnelbauer_t::find_tunnel(road_wt,road_vehicle->get_geschw(),welt->get_timeline_year_month()), NULL ); bauigel.set_keep_existing_faster_ways(true); bauigel.set_keep_city_roads(true); bauigel.set_maximum(10000); @@ -324,7 +324,7 @@ bool ai_passenger_t::create_water_transport_vehikel(const stadt_t* start_stadt, if(town_road!=bushalt) { wegbauer_t bauigel(welt, this); // no bridges => otherwise first tile might be bridge start ... - bauigel.route_fuer( wegbauer_t::strasse, wegbauer_t::weg_search( road_wt, 25, welt->get_timeline_year_month(), weg_t::type_flat ), tunnelbauer_t::find_tunnel(road_wt,road_vehicle->get_geschw(),welt->get_timeline_year_month()), NULL ); + bauigel.route_fuer( wegbauer_t::strasse, wegbauer_t::weg_search( road_wt, road_vehicle->get_geschw(), road_vehicle->get_gewicht(), welt->get_timeline_year_month(), weg_t::type_flat ), tunnelbauer_t::find_tunnel(road_wt,road_vehicle->get_geschw(),welt->get_timeline_year_month()), NULL ); bauigel.set_keep_existing_faster_ways(true); bauigel.set_keep_city_roads(true); bauigel.set_maximum(10000); @@ -542,7 +542,7 @@ halthandle_t ai_passenger_t::build_airport(const stadt_t* city, koord pos, int r sint32 lenght=9999; rotation=-1; - bauigel.route_fuer( wegbauer_t::strasse, wegbauer_t::weg_search( road_wt, 25, welt->get_timeline_year_month(), weg_t::type_flat ), tunnelbauer_t::find_tunnel(road_wt,road_vehicle->get_geschw(),welt->get_timeline_year_month()), brueckenbauer_t::find_bridge(road_wt,road_vehicle->get_geschw(),welt->get_timeline_year_month()) ); + bauigel.route_fuer( wegbauer_t::strasse, wegbauer_t::weg_search( road_wt, road_vehicle->get_geschw(), road_vehicle->get_gewicht(), welt->get_timeline_year_month(), weg_t::type_flat ), tunnelbauer_t::find_tunnel(road_wt,road_vehicle->get_geschw(),welt->get_timeline_year_month()), brueckenbauer_t::find_bridge(road_wt,road_vehicle->get_geschw(),welt->get_timeline_year_month()) ); bauigel.set_keep_existing_faster_ways(true); bauigel.set_keep_city_roads(true); bauigel.set_maximum(10000); @@ -1183,7 +1183,7 @@ DBG_MESSAGE("ai_passenger_t::do_passenger_ki()","no suitable hub found"); // find the best => AI will never survive // road_weg = wegbauer_t::weg_search( road_wt, road_vehicle->get_geschw(), welt->get_timeline_year_month(),weg_t::type_flat ); // find the really cheapest road - road_weg = wegbauer_t::weg_search( road_wt, 10, welt->get_timeline_year_month(), weg_t::type_flat ); + road_weg = wegbauer_t::weg_search( road_wt, road_vehicle->get_geschw(), road_vehicle->get_gewicht(), welt->get_timeline_year_month(), weg_t::type_flat ); state = NR_BAUE_STRASSEN_ROUTE; DBG_MESSAGE("ai_passenger_t::do_passenger_ki()","using %s on %s",road_vehicle->get_name(),road_weg->get_name()); } From 6e7fcb3261f8f2b73beeae2b559cd5fb2dfb4b20 Mon Sep 17 00:00:00 2001 From: Ansgar Burchardt <ansgar@2008.43-1.org> Date: Sat, 18 Apr 2009 18:05:55 +0200 Subject: [PATCH 61/61] Fix complilation with GCC 4.3.2 on Linux Signed-off-by: Ansgar Burchardt <ansgar@2008.43-1.org> --- simconvoi.cc | 16 +++++++++------- simhalt.cc | 6 +++--- simhalt.h | 2 +- simworld.cc | 4 ++-- tpl/quickstone_hashtable_tpl.h | 3 ++- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/simconvoi.cc b/simconvoi.cc index 53fb772b869..6c22036fd09 100644 --- a/simconvoi.cc +++ b/simconvoi.cc @@ -243,11 +243,11 @@ DBG_MESSAGE("convoi_t::~convoi_t()", "destroying %d, %p", self.get_id(), this); tmp_halt->force_paths_stale(); } } + } #else // Old method - brute force welt->set_schedule_counter(); #endif - } delete fpl; } @@ -2401,18 +2401,18 @@ convoi_t::rdwr(loadsave_t *file) { if(file->get_experimental_version() <= 1) { - uint32 old_go_on_ticks = (uint32)go_on_ticks; + uint32 old_go_on_ticks = (uint32)go_on_ticks; file->rdwr_long( old_go_on_ticks, "dt" ); } else { - file->rdwr_longlong((sint64)go_on_ticks, "dt" ); + file->rdwr_longlong(go_on_ticks, "dt" ); } } else { sint64 diff_ticks= welt->get_zeit_ms()>go_on_ticks ? 0 : go_on_ticks-welt->get_zeit_ms(); - file->rdwr_longlong((sint64)diff_ticks, "dt" ); + file->rdwr_longlong(diff_ticks, "dt" ); } } else @@ -2425,7 +2425,7 @@ convoi_t::rdwr(loadsave_t *file) } else { - file->rdwr_longlong((sint64)go_on_ticks, "dt" ); + file->rdwr_longlong(go_on_ticks, "dt" ); } if(go_on_ticks!=WAIT_INFINITE) @@ -2516,7 +2516,7 @@ convoi_t::rdwr(loadsave_t *file) } if(file->get_experimental_version() >= 2) { - file->rdwr_longlong((sint64)last_departure_time, ""); + file->rdwr_longlong(last_departure_time, ""); for(uint8 i = 0; i < MAX_CONVOI_COST; i ++) { file->rdwr_long(rolling_average[i], ""); @@ -3535,12 +3535,14 @@ void convoi_t::set_line(linehandle_t org_line) schedule_t *new_fpl= org_line->get_schedule()->copy(); set_schedule(new_fpl); +#ifdef NEW_PATHING ITERATE_PTR(new_fpl, j) { halthandle_t tmp_halt = haltestelle_t::get_halt(welt, fpl->eintrag[j].pos); tmp_halt->reschedule = true; tmp_halt->force_paths_stale(); } +#endif line->add_convoy(self); } @@ -4025,4 +4027,4 @@ convoi_t::calc_longest_loading_time() } } return longest; -} \ No newline at end of file +} diff --git a/simhalt.cc b/simhalt.cc index ae01ff672ac..5ba8afef3e3 100644 --- a/simhalt.cc +++ b/simhalt.cc @@ -250,7 +250,7 @@ haltestelle_t::haltestelle_t(karte_t* wl, loadsave_t* file) #ifdef NEW_PATHING iterations = 0; search_complete = false; - waiting_times = new quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>>[warenbauer_t::get_max_catg_index()]; + waiting_times = new quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16> >[warenbauer_t::get_max_catg_index()]; connexions = new quickstone_hashtable_tpl<haltestelle_t, connexion*>[warenbauer_t::get_max_catg_index()]; paths = new quickstone_hashtable_tpl<haltestelle_t, path>[warenbauer_t::get_max_catg_index()]; #else @@ -302,7 +302,7 @@ haltestelle_t::haltestelle_t(karte_t* wl, koord k, spieler_t* sp) #ifdef NEW_PATHING iterations = 0; search_complete = false; - waiting_times = new quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>>[warenbauer_t::get_max_catg_index()]; + waiting_times = new quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16> >[warenbauer_t::get_max_catg_index()]; connexions = new quickstone_hashtable_tpl<haltestelle_t, connexion*>[warenbauer_t::get_max_catg_index()]; paths = new quickstone_hashtable_tpl<haltestelle_t, path>[warenbauer_t::get_max_catg_index()]; #else @@ -2875,7 +2875,7 @@ void haltestelle_t::rdwr(loadsave_t *file) halts_count = waiting_times[i].get_count(); file->rdwr_short(halts_count, ""); - quickstone_hashtable_iterator_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>> iter(waiting_times[i]); + quickstone_hashtable_iterator_tpl<haltestelle_t, fixed_list_tpl<uint16, 16> > iter(waiting_times[i]); //iter.begin(); while(iter.next()) diff --git a/simhalt.h b/simhalt.h index 03b713c900d..3386e16056f 100644 --- a/simhalt.h +++ b/simhalt.h @@ -344,7 +344,7 @@ class haltestelle_t // Record of waiting times. Takes a list of the last 16 waiting times per type of goods. // Getter method will need to average the waiting times. // @author: jamespetts - quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16>>* waiting_times; + quickstone_hashtable_tpl<haltestelle_t, fixed_list_tpl<uint16, 16> >* waiting_times; #ifdef NEW_PATHING // Used for pathfinding. The list is stored on the heap so that it can be re-used diff --git a/simworld.cc b/simworld.cc index 9db3f643888..40a60c1e0a3 100644 --- a/simworld.cc +++ b/simworld.cc @@ -3287,7 +3287,7 @@ DBG_MESSAGE("karte_t::speichern(loadsave_t *file)", "start"); } else { - file->rdwr_longlong((sint64)ticks, " "); + file->rdwr_longlong(ticks, " "); } file->rdwr_long(letzter_monat, " "); file->rdwr_long(letztes_jahr, "\n"); @@ -3538,7 +3538,7 @@ DBG_DEBUG("karte_t::laden", "einstellungen loaded (groesse %i,%i) timeline=%i be } else { - file->rdwr_longlong((sint64)ticks, ""); + file->rdwr_longlong(ticks, ""); } file->rdwr_long(letzter_monat, " "); file->rdwr_long(letztes_jahr, "\n"); diff --git a/tpl/quickstone_hashtable_tpl.h b/tpl/quickstone_hashtable_tpl.h index 9a01ac21618..29734ea0084 100644 --- a/tpl/quickstone_hashtable_tpl.h +++ b/tpl/quickstone_hashtable_tpl.h @@ -6,6 +6,7 @@ #ifndef quickstone_hashtable_tpl_h #define quickstone_hashtable_tpl_h +#include "ptrhashtable_tpl.h" #include "hashtable_tpl.h" #include "quickstone_tpl.h" #include <stdlib.h> @@ -53,7 +54,7 @@ class quickstone_hashtable_iterator_tpl : public hashtable_iterator_tpl<quicksto { public: quickstone_hashtable_iterator_tpl(const hashtable_tpl<quickstone_tpl<key_t>, value_t, quickstone_hash_tpl<key_t> > *hashtable) : - hashtable_iterator_tpl<quickstone_tpl<key_t>, value_t, ptrhash_tpl<quickstone_tpl<key_t>> >(hashtable) + hashtable_iterator_tpl<quickstone_tpl<key_t>, value_t, ptrhash_tpl<quickstone_tpl<key_t> > >(hashtable) { } quickstone_hashtable_iterator_tpl(const hashtable_tpl<quickstone_tpl<key_t>, value_t, quickstone_hash_tpl<key_t> > &hashtable) :