Merge remote-tracking branch 'upstream/master'

master
dvere 2014-12-01 19:17:53 +00:00
commit 5fd0e1676a
113 changed files with 1867 additions and 724 deletions

View File

@ -15,7 +15,7 @@
android:label="Minetest"
android:launchMode="singleTask"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="landscape"
android:screenOrientation="sensorLandscape"
android:clearTaskOnLaunch="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@ -125,6 +125,11 @@ FREETYPE_URL_GIT = https://github.com/cdave1/freetype2-android
-include $(PATHCFGFILE)
#use interim target variable to switch leveldb on or off
ifeq ($(HAVE_LEVELDB),1)
LEVELDB_TARGET = $(LEVELDB_LIB)
endif
.PHONY : debug release reconfig delconfig \
leveldb_download clean_leveldb leveldb\
irrlicht_download clean_irrlicht irrlicht \
@ -140,11 +145,6 @@ FREETYPE_URL_GIT = https://github.com/cdave1/freetype2-android
$(OPENSSL_TIMESTAMP) curl_binary \
$(ROOT)/jni/src/android_version.h
#use interim target variable to switch leveldb on or off
ifeq ($(HAVE_LEVELDB),1)
LEVELDB_TARGET = $(LEVELDB_LIB)
endif
debug : $(PATHCFGFILE)
export NDEBUG=; \
export BUILD_TYPE=debug; \
@ -172,9 +172,9 @@ $(PATHCFGFILE) :
exit 1; \
fi; \
echo "ANDROID_NDK = $$ANDROID_NDK" > ${PATHCFGFILE}; \
echo "NDK_MODULE_PATH = $$ANDROID_NDK/tools" >> ${PATHCFGFILE}; \
echo "NDK_MODULE_PATH = $$ANDROID_NDK/toolchains" >> ${PATHCFGFILE}; \
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";\
echo "+ Note: NDK_MODULE_PATH is set to $$ANDROID_NDK/tools"; \
echo "+ Note: NDK_MODULE_PATH is set to $$ANDROID_NDK/toolchains"; \
echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";\
echo "Please specify path of ANDROID SDK"; \
echo "e.g. /home/user/adt-bundle-linux-x86_64-20131030/sdk/"; \

View File

@ -159,6 +159,7 @@ LOCAL_SRC_FILES := \
jni/src/mapblock_mesh.cpp \
jni/src/mapgen.cpp \
jni/src/mapgen_singlenode.cpp \
jni/src/mapgen_v5.cpp \
jni/src/mapgen_v6.cpp \
jni/src/mapgen_v7.cpp \
jni/src/mapnode.cpp \

View File

@ -490,6 +490,18 @@ function core.pos_to_string(pos)
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
end
--------------------------------------------------------------------------------
function table.copy(t, seen)
local n = {}
seen = seen or {}
seen[t] = n
for k, v in pairs(t) do
n[type(k) ~= "table" and k or seen[k] or table.copy(k, seen)] =
type(v) ~= "table" and v or seen[v] or table.copy(v, seen)
end
return n
end
--------------------------------------------------------------------------------
-- mainmenu only functions
--------------------------------------------------------------------------------

View File

@ -252,7 +252,7 @@ core.register_chatcommand("clearpassword", {
description = "set empty password",
privs = {password=true},
func = function(name, param)
toname = param
local toname = param
if toname == "" then
return false, "Name field required"
end
@ -426,6 +426,7 @@ local function handle_give_command(cmd, giver, receiver, stackstring)
return false, receiver .. " is not a known player"
end
local leftover = receiverref:get_inventory():add_item("main", itemstack)
local partiality
if leftover:is_empty() then
partiality = ""
elseif leftover:get_count() == itemstack:get_count() then

View File

@ -30,7 +30,7 @@ core.register_entity(":__builtin:falling_node", {
item_texture = core.registered_items[itemname].inventory_image
item_type = core.registered_items[itemname].type
end
prop = {
local prop = {
is_visible = true,
textures = {node.name},
}
@ -112,7 +112,7 @@ core.register_entity(":__builtin:falling_node", {
})
function spawn_falling_node(p, node)
obj = core.add_entity(p, "__builtin:falling_node")
local obj = core.add_entity(p, "__builtin:falling_node")
obj:get_luaentity():set_node(node)
end
@ -163,10 +163,10 @@ end
--
function nodeupdate_single(p, delay)
n = core.get_node(p)
local n = core.get_node(p)
if core.get_item_group(n.name, "falling_node") ~= 0 then
p_bottom = {x=p.x, y=p.y-1, z=p.z}
n_bottom = core.get_node(p_bottom)
local p_bottom = {x=p.x, y=p.y-1, z=p.z}
local n_bottom = core.get_node(p_bottom)
-- Note: walkable is in the node definition, not in item groups
if core.registered_nodes[n_bottom.name] and
(core.get_item_group(n.name, "float") == 0 or

View File

@ -97,7 +97,7 @@ local function init_globals()
local found_singleplayerworld = false
for world in pairs(world_list) do
for i,world in pairs(world_list) do
if world.name == "singleplayerworld" then
found_singleplayerworld = true
gamedata.worldindex = i
@ -110,10 +110,10 @@ local function init_globals()
local world_list = core.get_worlds()
for world in pairs(world_list) do
for i,world in pairs(world_list) do
if world.name == "singleplayerworld" then
gamedata.worldindex = i
return
break
end
end
end

View File

@ -1303,13 +1303,15 @@ string:trim()
minetest.pos_to_string({x=X,y=Y,z=Z}) -> "(X,Y,Z)"
^ Convert position to a printable string
minetest.string_to_pos(string) -> position
^ Same but in reverse
^ Same but in reverse. Returns nil if the string can't be parsed to a position.
minetest.formspec_escape(string) -> string
^ escapes characters [ ] \ , ; that can not be used in formspecs
minetest.is_yes(arg)
^ returns whether arg can be interpreted as yes
minetest.get_us_time()
^ returns time with microsecond precision
table.copy(table) -> table
^ returns a deep copy of a table
minetest namespace reference
-----------------------------
@ -1503,6 +1505,7 @@ minetest.place_node(pos, node)
^ Place node with the same effects that a player would cause
minetest.dig_node(pos)
^ Dig node with the same effects that a player would cause
Returns true if successful, false on failure (e.g. protected location)
minetest.punch_node(pos)
^ Punch node with the same effects that a player would cause
@ -1883,7 +1886,7 @@ Class reference
----------------
NodeMetaRef: Node metadata - reference extra data and functionality stored
in a node
- Can be gotten via minetest.get_nodemeta(pos)
- Can be gotten via minetest.get_meta(pos)
methods:
- set_string(name, value)
- get_string(name)
@ -2050,8 +2053,11 @@ methods:
can be fully added to the list
- contains_item(listname, stack): returns true if the stack of items
can be fully taken from the list
remove_item(listname, stack): take as many items as specified from the list,
returns the items that were actually removed (as an ItemStack)
- remove_item(listname, stack): take as many items as specified from the list,
returns the items that were actually removed (as an ItemStack) - note that
any item metadata is ignored, so attempting to remove a specific unique
item this way will likely remove the wrong one - to do that use set_stack
with an empty ItemStack
- get_location() -> location compatible to minetest.get_inventory(location)
-> {type="undefined"} in case location is not known
@ -2222,7 +2228,9 @@ Registered entities
- on_activate(self, staticdata)
^ Called when the object is instantiated.
- on_step(self, dtime)
^ Called on every server tick (dtime is usually 0.1 seconds)
^ Called on every server tick, after movement and collision processing.
dtime is usually 0.1 seconds, as per the dedicated_server_step setting
in minetest.conf.
- on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
^ Called when somebody punches the object.
^ Note that you probably want to handle most punches using the

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -0,0 +1,100 @@
<?xml version="1.0"?>
<font type="bitmap">
<Texture index="0" filename="liberation_sans_14_img.png" hasAlpha="true" />
<c c="!" r="0, 0, 6, 18" />
<c c="&quot;" r="6, 0, 15, 9" />
<c c="#" r="15, 0, 30, 18" />
<c c="$" r="30, 0, 43, 20" />
<c c="%" r="43, 0, 62, 18" />
<c c="&amp;" r="62, 0, 78, 18" />
<c c="'" r="78, 0, 84, 9" />
<c c="(" r="84, 0, 93, 22" />
<c c=")" r="93, 0, 103, 22" />
<c c="*" r="103, 0, 114, 12" />
<c c="+" r="114, 0, 127, 16" />
<c c="," r="127, 0, 133, 20" />
<c c="-" r="133, 0, 141, 13" />
<c c="." r="141, 0, 147, 18" />
<c c="/" r="147, 0, 156, 18" />
<c c="0" r="156, 0, 169, 18" />
<c c="1" r="169, 0, 181, 18" />
<c c="2" r="181, 0, 195, 18" />
<c c="3" r="195, 0, 208, 18" />
<c c="4" r="208, 0, 222, 18" />
<c c="5" r="222, 0, 235, 18" />
<c c="6" r="235, 0, 248, 18" />
<c c="7" r="248, 0, 261, 18" />
<c c="8" r="261, 0, 274, 18" />
<c c="9" r="274, 0, 287, 18" />
<c c=":" r="287, 0, 293, 18" />
<c c=";" r="293, 0, 299, 20" />
<c c="&lt;" r="299, 0, 312, 16" />
<c c="=" r="312, 0, 325, 15" />
<c c="&gt;" r="325, 0, 338, 16" />
<c c="?" r="338, 0, 351, 18" />
<c c="@" r="351, 0, 370, 21" />
<c c="A" r="370, 0, 386, 18" />
<c c="B" r="386, 0, 400, 18" />
<c c="C" r="400, 0, 415, 18" />
<c c="D" r="415, 0, 430, 18" />
<c c="E" r="430, 0, 444, 18" />
<c c="F" r="444, 0, 457, 18" />
<c c="G" r="457, 0, 473, 18" />
<c c="H" r="473, 0, 487, 18" />
<c c="I" r="487, 0, 493, 18" />
<c c="J" r="493, 0, 506, 18" />
<c c="K" r="0, 22, 15, 40" />
<c c="L" r="15, 22, 27, 40" />
<c c="M" r="27, 22, 43, 40" />
<c c="N" r="43, 22, 57, 40" />
<c c="O" r="57, 22, 73, 40" />
<c c="P" r="73, 22, 87, 40" />
<c c="Q" r="87, 22, 103, 44" />
<c c="R" r="103, 22, 118, 40" />
<c c="S" r="118, 22, 133, 40" />
<c c="T" r="133, 22, 147, 40" />
<c c="U" r="147, 22, 161, 40" />
<c c="V" r="161, 22, 177, 40" />
<c c="W" r="177, 22, 199, 40" />
<c c="X" r="199, 22, 216, 40" />
<c c="Y" r="216, 22, 232, 40" />
<c c="Z" r="232, 22, 247, 40" />
<c c="[" r="247, 22, 255, 44" />
<c c="\" r="255, 22, 264, 40" />
<c c="]" r="264, 22, 272, 44" />
<c c="^" r="272, 22, 283, 34" />
<c c="_" r="283, 22, 298, 44" />
<c c="`" r="298, 22, 306, 29" />
<c c="a" r="306, 22, 319, 40" />
<c c="b" r="319, 22, 333, 40" />
<c c="c" r="333, 22, 345, 40" />
<c c="d" r="345, 22, 358, 40" />
<c c="e" r="358, 22, 371, 40" />
<c c="f" r="371, 22, 381, 40" />
<c c="g" r="381, 22, 394, 44" />
<c c="h" r="394, 22, 406, 40" />
<c c="i" r="406, 22, 412, 40" />
<c c="j" r="412, 22, 420, 44" />
<c c="k" r="420, 22, 432, 40" />
<c c="l" r="432, 22, 438, 40" />
<c c="m" r="438, 22, 456, 40" />
<c c="n" r="456, 22, 468, 40" />
<c c="o" r="468, 22, 481, 40" />
<c c="p" r="481, 22, 495, 44" />
<c c="q" r="495, 22, 508, 44" />
<c c="r" r="0, 44, 10, 62" />
<c c="s" r="10, 44, 22, 62" />
<c c="t" r="22, 44, 31, 62" />
<c c="u" r="31, 44, 43, 62" />
<c c="v" r="43, 44, 56, 62" />
<c c="w" r="56, 44, 73, 62" />
<c c="x" r="73, 44, 86, 62" />
<c c="y" r="86, 44, 99, 66" />
<c c="z" r="99, 44, 111, 62" />
<c c="{" r="111, 44, 121, 66" />
<c c="|" r="121, 44, 127, 66" />
<c c="}" r="127, 44, 137, 66" />
<c c="~" r="137, 44, 150, 57" />
</font>

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
fonts/lucida_sans_10.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_100.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
fonts/lucida_sans_11.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_110.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
fonts/lucida_sans_12.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_120.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
fonts/lucida_sans_14.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_140.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
fonts/lucida_sans_16.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_160.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
fonts/lucida_sans_18.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_180.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
fonts/lucida_sans_20.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_200.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
fonts/lucida_sans_22.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_220.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
fonts/lucida_sans_24.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_240.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
fonts/lucida_sans_26.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_260.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
fonts/lucida_sans_28.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_280.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
fonts/lucida_sans_36.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_360.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
fonts/lucida_sans_4.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_40.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
fonts/lucida_sans_48.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_480.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
fonts/lucida_sans_56.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_560.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

BIN
fonts/lucida_sans_6.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_60.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
fonts/lucida_sans_8.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_80.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

BIN
fonts/lucida_sans_9.xml Executable file

Binary file not shown.

BIN
fonts/lucida_sans_90.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
fonts/mono_dejavu_sans_10.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_100.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
fonts/mono_dejavu_sans_11.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_110.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
fonts/mono_dejavu_sans_12.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_120.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

BIN
fonts/mono_dejavu_sans_14.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_140.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
fonts/mono_dejavu_sans_16.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_160.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
fonts/mono_dejavu_sans_18.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_180.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

BIN
fonts/mono_dejavu_sans_20.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_200.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

BIN
fonts/mono_dejavu_sans_22.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_220.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
fonts/mono_dejavu_sans_24.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_240.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
fonts/mono_dejavu_sans_26.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_260.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

BIN
fonts/mono_dejavu_sans_28.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_280.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

BIN
fonts/mono_dejavu_sans_4.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_40.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
fonts/mono_dejavu_sans_6.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_60.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
fonts/mono_dejavu_sans_8.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_80.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
fonts/mono_dejavu_sans_9.xml Executable file

Binary file not shown.

BIN
fonts/mono_dejavu_sans_90.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -62,6 +62,9 @@
#keymap_quicktune_dec = KEY_NEXT
#keymap_quicktune_inc = KEY_PRIOR
#if set to true, you can place blocks at the position (feet + eye level) where you stand; this is helpful when working with nodeboxes
#enable_build_where_you_stand = false
# Minimum FPS
# The amount of rendered stuff is dynamically set according to this
#wanted_fps = 30
@ -212,6 +215,8 @@
#directional_colored_fog = true
#tooltip_show_delay = 400
# Delay showing tooltips, in miliseconds
#screen_dpi = 72
# adjust dpi configuration to your screen (Desktop only) e.g. for 4k screens
# Default timeout for cURL, in milliseconds
# Only has an effect if compiled with cURL

View File

@ -8,15 +8,15 @@ msgstr ""
"Project-Id-Version: minetest\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-23 17:37+0100\n"
"PO-Revision-Date: 2014-09-30 1:00+0200\n"
"Last-Translator: Rui Takeda\n"
"PO-Revision-Date: 2014-10-29 21:01+0900\n"
"Last-Translator: Rui Takeda <mrrst0914@gmail.com>\n"
"Language-Team: Japanese\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 1.7-dev\n"
"X-Generator: Poedit 1.6.10\n"
#: builtin/gamemgr.lua:23
msgid "Game Name"
@ -33,7 +33,7 @@ msgstr "キャンセル"
#: builtin/gamemgr.lua:118
msgid "Gamemgr: Unable to copy mod \"$1\" to game \"$2\""
msgstr "Gamemgr:\"$1\"のModを\"$2\"にコピーできません"
msgstr "Gamemgr: \"$1\"のModを \"$2\" にコピーできません"
#: builtin/gamemgr.lua:216
msgid "GAMES"
@ -45,7 +45,7 @@ msgstr "ゲーム"
#: builtin/gamemgr.lua:234
msgid "Mods:"
msgstr "Mod"
msgstr "Mod:"
#: builtin/gamemgr.lua:235
msgid "edit game"
@ -150,7 +150,7 @@ msgstr "設定"
#: builtin/mainmenu.lua:877
msgid "Start Game"
msgstr "プレイ"
msgstr "ゲームスタート"
#: builtin/mainmenu.lua:878 builtin/mainmenu.lua:941
msgid "Select World:"
@ -189,7 +189,7 @@ msgid "SETTINGS"
msgstr "SETTINGS"
#: builtin/mainmenu.lua:900
msgid "Fancy trees"
msgid "Fancy Trees"
msgstr "きれいな木"
#: builtin/mainmenu.lua:902
@ -242,7 +242,7 @@ msgstr "キー割当て変更"
#: builtin/mainmenu.lua:940 src/keycode.cpp:248
msgid "Play"
msgstr "プレイ"
msgstr "ゲームスタート"
#: builtin/mainmenu.lua:942
msgid "SINGLE PLAYER"
@ -274,23 +274,23 @@ msgstr "以前の貢献者"
#: builtin/mainmenu.lua:1069
msgid "Singleplayer"
msgstr "シングルプレイヤー"
msgstr "シングルプレイ"
#: builtin/mainmenu.lua:1070
msgid "Client"
msgstr "クライアント"
msgstr "クライアント"
#: builtin/mainmenu.lua:1071
msgid "Server"
msgstr "サーバー"
msgstr "マルチプレイ"
#: builtin/mainmenu.lua:1072
msgid "Settings"
msgstr "設定"
#: builtin/mainmenu.lua:1073
msgid "Texture Packs"
msgstr "テクスチャパック"
msgid "Texturepacks"
msgstr "テクスチャパック"
#: builtin/mainmenu.lua:1080
msgid "Mods"
@ -298,11 +298,11 @@ msgstr "Mod"
#: builtin/mainmenu.lua:1082
msgid "Credits"
msgstr "クレジット"
msgstr "クレジット"
#: builtin/modmgr.lua:236
msgid "MODS"
msgstr "MODS"
msgstr "MOD"
#: builtin/modmgr.lua:237
msgid "Installed Mods:"
@ -354,15 +354,15 @@ msgstr "ワールド:"
#: builtin/modmgr.lua:427 builtin/modmgr.lua:429
msgid "Hide Game"
msgstr "内部Modを非表示"
msgstr "内部Mod"
#: builtin/modmgr.lua:433 builtin/modmgr.lua:435
msgid "Hide mp content"
msgstr "Modパックを簡略表示"
msgstr "Modパックの簡略化"
#: builtin/modmgr.lua:442
msgid "Mod:"
msgstr "Mod:"
msgstr "Mod:"
#: builtin/modmgr.lua:444
msgid "Depends:"
@ -448,15 +448,14 @@ msgstr "再インストール"
msgid "Install"
msgstr "インストール"
#client
# client
#: src/client.cpp:2917
msgid "Item textures..."
msgstr "アイテムのテクスチャ設定中..."
#: src/game.cpp:940
msgid "Loading..."
msgstr "読み込み中..."
msgstr "ロード中..."
#: src/game.cpp:1000
msgid "Creating server...."
@ -482,9 +481,10 @@ msgstr "アイテム定義中..."
msgid "Node definitions..."
msgstr "ノード定義中..."
# 翻訳不可
#: src/game.cpp:1233
msgid "Media..."
msgstr "読み込み中..."
msgstr "..."
#: src/game.cpp:3409
msgid "Shutting down stuff..."
@ -517,11 +517,11 @@ msgstr "キーバインド"
#: src/guiKeyChangeMenu.cpp:161
msgid "\"Use\" = climb down"
msgstr "「\"Use\"」で降りる"
msgstr "「使う」キーで降りる"
#: src/guiKeyChangeMenu.cpp:176
msgid "Double tap \"jump\" to toggle fly"
msgstr "「\"jump\"」の二回押しで飛行"
msgstr "ジャンプの二回押しで飛行"
#: src/guiKeyChangeMenu.cpp:288
msgid "Key already in use"
@ -633,7 +633,7 @@ msgstr "音量"
#: src/guiPauseMenu.cpp:152
msgid "Exit to Menu"
msgstr "タイトルへ戻る"
msgstr "タイトル"
#: src/guiPauseMenu.cpp:161
msgid "Exit to OS"
@ -653,7 +653,7 @@ msgid ""
"- Mouse wheel: select item\n"
"- T: chat\n"
msgstr ""
"Default Controls:\n"
"基本操作:\n"
"WASD:移動\n"
"スペース:ジャンプ/登る\n"
"シフト:忍び歩き/降りる\n"
@ -687,7 +687,7 @@ msgstr "右ボタン"
#: src/keycode.cpp:223
msgid "X Button 1"
msgstr ""
msgstr "Xボタン1"
#: src/keycode.cpp:224
msgid "Back"
@ -707,7 +707,7 @@ msgstr "Tab"
#: src/keycode.cpp:224
msgid "X Button 2"
msgstr ""
msgstr "Xボタン2"
#: src/keycode.cpp:225
msgid "Capital"
@ -743,11 +743,11 @@ msgstr "Esc"
#: src/keycode.cpp:226
msgid "Final"
msgstr ""
msgstr "Finalキー"
#: src/keycode.cpp:226
msgid "Junja"
msgstr ""
msgstr "Junjaキー"
#: src/keycode.cpp:226
msgid "Kanji"
@ -963,7 +963,7 @@ msgstr "ズーム"
#: src/main.cpp:1472
msgid "needs_fallback_font"
msgstr "fallback_fontが必要"
msgstr "yes"
#: src/main.cpp:1547
msgid "Main Menu"
@ -971,11 +971,13 @@ msgstr "メインメニュー"
#: src/main.cpp:1723
msgid "No world selected and no address provided. Nothing to do."
msgstr "ワールドが選択できていないか、アドレスが入力されていません。そのため実行されません。"
msgstr ""
"ワールドが選択できていないか、アドレスが入力されていません。そのため実行されませ"
"ん。"
#: src/main.cpp:1731
msgid "Could not find or load game \""
msgstr "読み込みか検索に失敗:\""
msgstr "読み込みか検索に失敗: \""
#: src/main.cpp:1745
msgid "Invalid gamespec."
@ -984,3 +986,34 @@ msgstr "無効なgamespecです"
#: src/main.cpp:1790
msgid "Connection error (timed out?)"
msgstr "接続エラー(タイムアウト)"
# 以下追加
msgid "Bumpmapping"
msgstr "バンプマッピング"
msgid "Generate Normalmaps"
msgstr "法線マッピング"
msgid "Parallax Occlusion"
msgstr "視差オクルージョンマッピング"
msgid "Waving Water"
msgstr "揺れる水"
msgid "Waving Leaves"
msgstr "揺れる葉"
msgid "Waving Plants"
msgstr "揺れる草花"
msgid "GUI scale factor"
msgstr "メニューの大きさ"
msgid "Unsorted"
msgstr "未分類"
msgid "Search"
msgstr "検索"
msgid "Close store"
msgstr "閉じる"

View File

@ -463,6 +463,7 @@ set(minetest_SRCS
convert_json.cpp
drawscene.cpp
filecache.cpp
fontengine.cpp
game.cpp
guiChatConsole.cpp
guiEngine.cpp

View File

@ -255,7 +255,7 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime,
{
f32 oldy = old_player_position.Y;
f32 newy = player_position.Y;
f32 t = exp(-23*frametime);
f32 t = exp(-10*frametime);
player_position.Y = oldy * t + newy * (1-t);
}

View File

@ -219,6 +219,7 @@ Client::Client(
IrrlichtDevice *device,
const char *playername,
std::string password,
bool is_simple_singleplayer_game,
MapDrawControl &control,
IWritableTextureSource *tsrc,
IWritableShaderSource *shsrc,
@ -254,10 +255,11 @@ Client::Client(
m_inventory_updated(false),
m_inventory_from_server(NULL),
m_inventory_from_server_age(0.0),
m_show_hud(true),
m_show_highlighted(false),
m_animation_time(0),
m_crack_level(-1),
m_crack_pos(0,0,0),
m_highlighted_pos(0,0,0),
m_map_seed(0),
m_password(password),
m_access_denied(false),
@ -280,7 +282,8 @@ Client::Client(
m_env.addPlayer(player);
}
if (g_settings->getBool("enable_local_map_saving")) {
if (g_settings->getBool("enable_local_map_saving")
&& !is_simple_singleplayer_game) {
const std::string world_path = porting::path_user + DIR_DELIM + "worlds"
+ DIR_DELIM + "server_" + g_settings->get("address")
+ "_" + g_settings->get("remote_port");
@ -2513,9 +2516,9 @@ int Client::getCrackLevel()
return m_crack_level;
}
void Client::setHighlighted(v3s16 pos, bool show_hud)
void Client::setHighlighted(v3s16 pos, bool show_highlighted)
{
m_show_hud = show_hud;
m_show_highlighted = show_highlighted;
v3s16 old_highlighted_pos = m_highlighted_pos;
m_highlighted_pos = pos;
addUpdateMeshTaskForNode(old_highlighted_pos, false, true);
@ -2605,7 +2608,7 @@ void Client::addUpdateMeshTask(v3s16 p, bool ack_to_server, bool urgent)
// Debug: 1-6ms, avg=2ms
data->fill(b);
data->setCrack(m_crack_level, m_crack_pos);
data->setHighlighted(m_highlighted_pos, m_show_hud);
data->setHighlighted(m_highlighted_pos, m_show_highlighted);
data->setSmoothLighting(g_settings->getBool("smooth_lighting"));
}
@ -2724,7 +2727,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
{
verbosestream<<"Updating item textures and meshes"<<std::endl;
wchar_t* text = wgettext("Item textures...");
draw_load_screen(text, device, guienv, font, 0, 0);
draw_load_screen(text, device, guienv, 0, 0);
std::set<std::string> names = m_itemdef->getAll();
size_t size = names.size();
size_t count = 0;
@ -2737,7 +2740,7 @@ void Client::afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font)
count++;
percent = count*100/size;
if (count%50 == 0) // only update every 50 item
draw_load_screen(text, device, guienv, font, 0, percent);
draw_load_screen(text, device, guienv, 0, percent);
}
delete[] text;
}
@ -2773,7 +2776,7 @@ void Client::makeScreenshot(IrrlichtDevice *device)
irr::video::IVideoDriver *driver = device->getVideoDriver();
irr::video::IImage* const raw_image = driver->createScreenShot();
if (raw_image) {
irr::video::IImage* const image = driver->createImage(video::ECF_R8G8B8,
irr::video::IImage* const image = driver->createImage(video::ECF_R8G8B8,
raw_image->getDimension());
if (image) {

View File

@ -305,6 +305,7 @@ public:
IrrlichtDevice *device,
const char *playername,
std::string password,
bool is_simple_singleplayer_game,
MapDrawControl &control,
IWritableTextureSource *tsrc,
IWritableShaderSource *shsrc,
@ -397,7 +398,7 @@ public:
int getCrackLevel();
void setCrack(int level, v3s16 pos);
void setHighlighted(v3s16 pos, bool show_hud);
void setHighlighted(v3s16 pos, bool show_higlighted);
v3s16 getHighlighted(){ return m_highlighted_pos; }
u16 getHP();
@ -508,7 +509,7 @@ private:
float m_inventory_from_server_age;
std::set<v3s16> m_active_blocks;
PacketCounter m_packetcounter;
bool m_show_hud;
bool m_show_highlighted;
// Block mesh animation parameters
float m_animation_time;
int m_crack_level;

View File

@ -98,10 +98,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
* GUI related things
*/
#define LEGACY_SCALING (2./3.)
#define DEFAULT_FONT_SIZE (13.0 / LEGACY_SCALING)
#define DEFAULT_IMGSIZE (48.0)
#define DEFAULT_XSPACING ((15.0 + (1.0 / 3.0)))
#define DEFAULT_YSPACING (9.0)
#define TTF_DEFAULT_FONT_SIZE (13.0 / LEGACY_SCALING)
#define DEFAULT_FONT_SIZE (14)
#endif

View File

@ -52,12 +52,18 @@ void set_default_settings(Settings *settings)
settings->setDefault("keymap_toggle_hud", "KEY_F1");
settings->setDefault("keymap_toggle_chat", "KEY_F2");
settings->setDefault("keymap_toggle_force_fog_off", "KEY_F3");
settings->setDefault("keymap_toggle_update_camera", "KEY_F4");
settings->setDefault("keymap_toggle_update_camera",
#if DEBUG
"KEY_F4");
#else
"none");
#endif
settings->setDefault("keymap_toggle_debug", "KEY_F5");
settings->setDefault("keymap_toggle_profiler", "KEY_F6");
settings->setDefault("keymap_camera_mode", "KEY_F7");
settings->setDefault("keymap_increase_viewing_range_min", "+");
settings->setDefault("keymap_decrease_viewing_range_min", "-");
settings->setDefault("enable_build_where_you_stand", "false" );
settings->setDefault("3d_mode", "none");
settings->setDefault("3d_paralax_strength", "0.025");
settings->setDefault("aux1_descends", "false");
@ -181,10 +187,23 @@ void set_default_settings(Settings *settings)
settings->setDefault("fallback_font_shadow", "1");
settings->setDefault("fallback_font_shadow_alpha", "128");
std::stringstream fontsize;
fontsize << TTF_DEFAULT_FONT_SIZE;
settings->setDefault("font_size", fontsize.str());
settings->setDefault("mono_font_size", fontsize.str());
settings->setDefault("fallback_font_size", fontsize.str());
#else
settings->setDefault("freetype", "false");
settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "fontlucida.png"));
settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "fontdejavusansmono.png"));
settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "lucida_sans"));
settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "mono_dejavu_sans"));
std::stringstream fontsize;
fontsize << DEFAULT_FONT_SIZE;
settings->setDefault("font_size", fontsize.str());
settings->setDefault("mono_font_size", fontsize.str());
#endif
// Server stuff
@ -311,22 +330,8 @@ void set_default_settings(Settings *settings)
settings->setDefault("gui_scaling", "0.7");
}
settings->setDefault("curl_verify_cert","false");
#endif
}
void late_init_default_settings(Settings* settings)
{
#ifndef SERVER
std::stringstream fontsize;
fontsize << floor(
DEFAULT_FONT_SIZE *
porting::getDisplayDensity() *
settings->getFloat("gui_scaling")
);
settings->setDefault("font_size", fontsize.str());
settings->setDefault("mono_font_size", fontsize.str());
settings->setDefault("fallback_font_size", fontsize.str());
#else
settings->setDefault("screen_dpi", "72");
#endif
}

View File

@ -28,12 +28,6 @@ class Settings;
*/
void set_default_settings(Settings *settings);
/**
* initialize default values which require knowledge about gui
* @param settings pointer to settings
*/
void late_init_default_settings(Settings* settings);
/**
* override a default settings by settings from another settings element
* @param settings target settings pointer

View File

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clouds.h"
#include "clientmap.h"
#include "util/timetaker.h"
#include "fontengine.h"
typedef enum {
LEFT = -1,
@ -500,21 +501,18 @@ void draw_scene(video::IVideoDriver* driver, scene::ISceneManager* smgr,
Text will be removed when the screen is drawn the next time.
Additionally, a progressbar can be drawn when percent is set between 0 and 100.
*/
/*gui::IGUIStaticText **/
void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
gui::IGUIEnvironment* guienv, gui::IGUIFont* font, float dtime,
int percent, bool clouds )
gui::IGUIEnvironment* guienv, float dtime, int percent, bool clouds )
{
video::IVideoDriver* driver = device->getVideoDriver();
v2u32 screensize = driver->getScreenSize();
const wchar_t *loadingtext = text.c_str();
core::vector2d<u32> textsize_u = font->getDimension(loadingtext);
core::vector2d<s32> textsize(textsize_u.X,textsize_u.Y);
core::vector2d<s32> center(screensize.X/2, screensize.Y/2);
core::rect<s32> textrect(center - textsize/2, center + textsize/2);
video::IVideoDriver* driver = device->getVideoDriver();
v2u32 screensize = porting::getWindowSize();
v2s32 textsize(g_fontengine->getTextWidth(text), g_fontengine->getLineHeight());
v2s32 center(screensize.X / 2, screensize.Y / 2);
core::rect<s32> textrect(center - textsize / 2, center + textsize / 2);
gui::IGUIStaticText *guitext = guienv->addStaticText(
loadingtext, textrect, false, false);
text.c_str(), textrect, false, false);
guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds");
@ -522,25 +520,33 @@ void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
{
g_menuclouds->step(dtime*3);
g_menuclouds->render();
driver->beginScene(true, true, video::SColor(255,140,186,250));
driver->beginScene(true, true, video::SColor(255, 140, 186, 250));
g_menucloudsmgr->drawAll();
}
else
driver->beginScene(true, true, video::SColor(255,0,0,0));
driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
if (percent >= 0 && percent <= 100) // draw progress bar
// draw progress bar
if ((percent >= 0) && (percent <= 100))
{
core::vector2d<s32> barsize(256,32);
core::rect<s32> barrect(center-barsize/2, center+barsize/2);
driver->draw2DRectangle(video::SColor(255,255,255,255),barrect, NULL); // border
driver->draw2DRectangle(video::SColor(255,64,64,64), core::rect<s32> (
barrect.UpperLeftCorner+1,
v2s32 barsize(
// 342 is (approximately) 256/0.75 to keep bar on same size as
// before with default settings
342 * porting::getDisplayDensity() *
g_settings->getFloat("gui_scaling"),
g_fontengine->getTextHeight() * 2);
core::rect<s32> barrect(center - barsize / 2, center + barsize / 2);
driver->draw2DRectangle(video::SColor(255, 255, 255, 255),barrect, NULL); // border
driver->draw2DRectangle(video::SColor(255, 64, 64, 64), core::rect<s32> (
barrect.UpperLeftCorner + 1,
barrect.LowerRightCorner-1), NULL); // black inside the bar
driver->draw2DRectangle(video::SColor(255,128,128,128), core::rect<s32> (
barrect.UpperLeftCorner+1,
driver->draw2DRectangle(video::SColor(255, 128, 128, 128), core::rect<s32> (
barrect.UpperLeftCorner + 1,
core::vector2d<s32>(
barrect.LowerRightCorner.X-(barsize.X-1)+percent*(barsize.X-2)/100,
barrect.LowerRightCorner.Y-1)), NULL); // the actual progress
barrect.LowerRightCorner.X -
(barsize.X - 1) + percent * (barsize.X - 2) / 100,
barrect.LowerRightCorner.Y - 1)), NULL); // the actual progress
}
guienv->drawAll();
driver->endScene();

View File

@ -26,8 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
gui::IGUIEnvironment* guienv, gui::IGUIFont* font, float dtime=0,
int percent=0, bool clouds=true);
gui::IGUIEnvironment* guienv, float dtime=0, int percent=0,
bool clouds=true);
void draw_scene(video::IVideoDriver* driver, scene::ISceneManager* smgr,
Camera& camera, Client& client, LocalPlayer* player, Hud& hud,

View File

@ -125,6 +125,18 @@ public:
Some "old-style" interrupts:
*/
class InvalidNoiseParamsException : public BaseException {
public:
InvalidNoiseParamsException():
BaseException("One or more noise parameters were invalid or require "
"too much memory")
{}
InvalidNoiseParamsException(const std::string &s):
BaseException(s)
{}
};
class InvalidPositionException : public BaseException
{
public:

462
src/fontengine.cpp Normal file
View File

@ -0,0 +1,462 @@
/*
Minetest
Copyright (C) 2010-2014 sapier <sapier at gmx dot net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "fontengine.h"
#include "log.h"
#include "main.h"
#include "config.h"
#include "porting.h"
#include "constants.h"
#include "filesys.h"
#if USE_FREETYPE
#include "gettext.h"
#include "xCGUITTFont.h"
#endif
/** maximum size distance for getting a "similar" font size */
#define MAX_FONT_SIZE_OFFSET 10
/** reference to access font engine, has to be initialized by main */
FontEngine* g_fontengine = NULL;
/** callback to be used on change of font size setting */
static void font_setting_changed(const std::string) {
g_fontengine->readSettings();
}
/******************************************************************************/
FontEngine::FontEngine(Settings* main_settings, gui::IGUIEnvironment* env) :
m_settings(main_settings),
m_env(env),
m_font_cache(),
m_default_size(),
m_currentMode(FM_Standard),
m_lastMode(),
m_lastSize(0),
m_lastFont(NULL)
{
for ( unsigned int i = 0; i < FM_MaxMode; i++) {
m_default_size[i] = (FontMode) FONT_SIZE_UNSPECIFIED;
}
assert(m_settings != NULL);
assert(m_env != NULL);
assert(m_env->getSkin() != NULL);
m_currentMode = FM_Simple;
#if USE_FREETYPE
if (g_settings->getBool("freetype")) {
m_default_size[FM_Standard] = m_settings->getU16("font_size");
m_default_size[FM_Fallback] = m_settings->getU16("fallback_font_size");
m_default_size[FM_Mono] = m_settings->getU16("mono_font_size");
if (is_yes(gettext("needs_fallback_font"))) {
m_currentMode = FM_Fallback;
}
else {
m_currentMode = FM_Standard;
}
}
// having freetype but not using it is quite a strange case so we need to do
// special handling for it
if (m_currentMode == FM_Simple) {
std::stringstream fontsize;
fontsize << DEFAULT_FONT_SIZE;
m_settings->setDefault("font_size", fontsize.str());
m_settings->setDefault("mono_font_size", fontsize.str());
}
#endif
m_default_size[FM_Simple] = m_settings->getU16("font_size");
m_default_size[FM_SimpleMono] = m_settings->getU16("mono_font_size");
updateSkin();
if (m_currentMode == FM_Standard) {
m_settings->registerChangedCallback("font_size", font_setting_changed);
m_settings->registerChangedCallback("font_path", font_setting_changed);
m_settings->registerChangedCallback("font_shadow", font_setting_changed);
m_settings->registerChangedCallback("font_shadow_alpha", font_setting_changed);
}
else if (m_currentMode == FM_Fallback) {
m_settings->registerChangedCallback("fallback_font_size", font_setting_changed);
m_settings->registerChangedCallback("fallback_font_path", font_setting_changed);
m_settings->registerChangedCallback("fallback_font_shadow", font_setting_changed);
m_settings->registerChangedCallback("fallback_font_shadow_alpha", font_setting_changed);
}
m_settings->registerChangedCallback("mono_font_path", font_setting_changed);
m_settings->registerChangedCallback("mono_font_size", font_setting_changed);
m_settings->registerChangedCallback("screen_dpi", font_setting_changed);
m_settings->registerChangedCallback("gui_scaling", font_setting_changed);
}
/******************************************************************************/
FontEngine::~FontEngine()
{
cleanCache();
}
/******************************************************************************/
void FontEngine::cleanCache()
{
for ( unsigned int i = 0; i < FM_MaxMode; i++) {
for (std::map<unsigned int, irr::gui::IGUIFont*>::iterator iter
= m_font_cache[i].begin();
iter != m_font_cache[i].end(); iter++) {
iter->second->drop();
iter->second = NULL;
}
m_font_cache[i].clear();
}
}
/******************************************************************************/
irr::gui::IGUIFont* FontEngine::getFont(unsigned int font_size, FontMode mode)
{
if (mode == FM_Unspecified) {
mode = m_currentMode;
}
else if ((mode == FM_Mono) && (m_currentMode == FM_Simple)) {
mode = FM_SimpleMono;
}
if (font_size == FONT_SIZE_UNSPECIFIED) {
font_size = m_default_size[mode];
}
if ((font_size == m_lastSize) && (mode == m_lastMode)) {
return m_lastFont;
}
if (m_font_cache[mode].find(font_size) == m_font_cache[mode].end()) {
initFont(font_size, mode);
}
if (m_font_cache[mode].find(font_size) == m_font_cache[mode].end()) {
return NULL;
}
m_lastSize = font_size;
m_lastMode = mode;
m_lastFont = m_font_cache[mode][font_size];
return m_font_cache[mode][font_size];
}
/******************************************************************************/
unsigned int FontEngine::getTextHeight(unsigned int font_size, FontMode mode)
{
irr::gui::IGUIFont* font = getFont(font_size, mode);
// use current skin font as fallback
if (font == NULL) {
font = m_env->getSkin()->getFont();
}
assert(font != NULL);
return font->getDimension(L"Some unimportant example String").Height;
}
/******************************************************************************/
unsigned int FontEngine::getTextWidth(const std::wstring& text,
unsigned int font_size, FontMode mode)
{
irr::gui::IGUIFont* font = getFont(font_size, mode);
// use current skin font as fallback
if (font == NULL) {
font = m_env->getSkin()->getFont();
}
assert(font != NULL);
return font->getDimension(text.c_str()).Width;
}
/** get line height for a specific font (including empty room between lines) */
unsigned int FontEngine::getLineHeight(unsigned int font_size, FontMode mode)
{
irr::gui::IGUIFont* font = getFont(font_size, mode);
// use current skin font as fallback
if (font == NULL) {
font = m_env->getSkin()->getFont();
}
assert(font != NULL);
return font->getDimension(L"Some unimportant example String").Height
+ font->getKerningHeight();
}
/******************************************************************************/
unsigned int FontEngine::getDefaultFontSize()
{
return m_default_size[m_currentMode];
}
/******************************************************************************/
void FontEngine::readSettings()
{
#if USE_FREETYPE
if (g_settings->getBool("freetype")) {
m_default_size[FM_Standard] = m_settings->getU16("font_size");
m_default_size[FM_Fallback] = m_settings->getU16("fallback_font_size");
m_default_size[FM_Mono] = m_settings->getU16("mono_font_size");
if (is_yes(gettext("needs_fallback_font"))) {
m_currentMode = FM_Fallback;
}
else {
m_currentMode = FM_Standard;
}
}
#endif
m_default_size[FM_Simple] = m_settings->getU16("font_size");
m_default_size[FM_SimpleMono] = m_settings->getU16("mono_font_size");
cleanCache();
updateFontCache();
updateSkin();
}
/******************************************************************************/
void FontEngine::updateSkin()
{
gui::IGUIFont *font = getFont();
if (font)
m_env->getSkin()->setFont(font);
else
errorstream << "FontEngine: Default font file: " <<
"\n\t\"" << m_settings->get("font_path") << "\"" <<
"\n\trequired for current screen configuration was not found" <<
" or was invalid file format." <<
"\n\tUsing irrlicht default font." << std::endl;
// If we did fail to create a font our own make irrlicht find a default one
font = m_env->getSkin()->getFont();
assert(font);
u32 text_height = font->getDimension(L"Hello, world!").Height;
infostream << "text_height=" << text_height << std::endl;
}
/******************************************************************************/
void FontEngine::updateFontCache()
{
/* the only font to be initialized is default one,
* all others are re-initialized on demand */
initFont(m_default_size[m_currentMode], m_currentMode);
/* reset font quick access */
m_lastMode = FM_Unspecified;
m_lastSize = 0;
m_lastFont = NULL;
}
/******************************************************************************/
void FontEngine::initFont(unsigned int basesize, FontMode mode)
{
std::string font_config_prefix;
if (mode == FM_Unspecified) {
mode = m_currentMode;
}
switch (mode) {
case FM_Standard:
font_config_prefix = "";
break;
case FM_Fallback:
font_config_prefix = "fallback_";
break;
case FM_Mono:
font_config_prefix = "mono_";
if (m_currentMode == FM_Simple)
mode = FM_SimpleMono;
break;
case FM_Simple: /* Fallthrough */
case FM_SimpleMono: /* Fallthrough */
default:
font_config_prefix = "";
}
if (m_font_cache[mode].find(basesize) != m_font_cache[mode].end())
return;
if ((mode == FM_Simple) || (mode == FM_SimpleMono)) {
initSimpleFont(basesize, mode);
return;
}
#if USE_FREETYPE
else {
if (! is_yes(m_settings->get("freetype"))) {
return;
}
unsigned int size = floor(
porting::getDisplayDensity() *
m_settings->getFloat("gui_scaling") *
basesize);
u32 font_shadow = 0;
u32 font_shadow_alpha = 0;
try {
font_shadow =
g_settings->getU16(font_config_prefix + "font_shadow");
} catch (SettingNotFoundException&) {}
try {
font_shadow_alpha =
g_settings->getU16(font_config_prefix + "font_shadow_alpha");
} catch (SettingNotFoundException&) {}
std::string font_path = g_settings->get(font_config_prefix + "font_path");
if (font_path.substr(font_path.length() -4) != ".ttf") {
errorstream << "FontEngine: \"" << font_path
<< "\" doesn't seem to be a ttf File." << std::endl;
return;
}
irr::gui::IGUIFont* font = gui::CGUITTFont::createTTFont(m_env,
font_path.c_str(), size, true, true, font_shadow,
font_shadow_alpha);
if (font != NULL) {
m_font_cache[mode][basesize] = font;
}
else {
errorstream << "FontEngine: failed to load freetype font: "
<< font_path << std::endl;
}
}
#endif
}
/** initialize a font without freetype */
void FontEngine::initSimpleFont(unsigned int basesize, FontMode mode)
{
assert((mode == FM_Simple) || (mode == FM_SimpleMono));
std::string font_path = "";
if (mode == FM_Simple) {
font_path = m_settings->get("font_path");
} else {
font_path = m_settings->get("mono_font_path");
}
std::string basename = font_path;
std::string ending = font_path.substr(font_path.length() -4);
if (ending == ".ttf") {
errorstream << "FontEngine: Not trying to open \"" << font_path
<< "\" which seems to be a truetype font." << std::endl;
return;
}
if ((ending == ".xml") || ( ending == ".png")) {
basename = font_path.substr(0,font_path.length()-4);
}
if (basesize == FONT_SIZE_UNSPECIFIED)
basesize = DEFAULT_FONT_SIZE;
unsigned int size = floor(
porting::getDisplayDensity() *
m_settings->getFloat("gui_scaling") *
basesize);
irr::gui::IGUIFont* font = NULL;
for(unsigned int offset = 0; offset < MAX_FONT_SIZE_OFFSET; offset++) {
// try opening positive offset
std::stringstream fontsize_plus_png;
fontsize_plus_png << basename << "_" << (size + offset) << ".png";
if (fs::PathExists(fontsize_plus_png.str())) {
font = m_env->getFont(fontsize_plus_png.str().c_str());
if (font) {
verbosestream << "FontEngine: found font: " << fontsize_plus_png.str() << std::endl;
break;
}
}
std::stringstream fontsize_plus_xml;
fontsize_plus_xml << basename << "_" << (size + offset) << ".xml";
if (fs::PathExists(fontsize_plus_xml.str())) {
font = m_env->getFont(fontsize_plus_xml.str().c_str());
if (font) {
verbosestream << "FontEngine: found font: " << fontsize_plus_xml.str() << std::endl;
break;
}
}
// try negative offset
std::stringstream fontsize_minus_png;
fontsize_minus_png << basename << "_" << (size - offset) << ".png";
if (fs::PathExists(fontsize_minus_png.str())) {
font = m_env->getFont(fontsize_minus_png.str().c_str());
if (font) {
verbosestream << "FontEngine: found font: " << fontsize_minus_png.str() << std::endl;
break;
}
}
std::stringstream fontsize_minus_xml;
fontsize_minus_xml << basename << "_" << (size - offset) << ".xml";
if (fs::PathExists(fontsize_minus_xml.str())) {
font = m_env->getFont(fontsize_minus_xml.str().c_str());
if (font) {
verbosestream << "FontEngine: found font: " << fontsize_minus_xml.str() << std::endl;
break;
}
}
}
// try name direct
if (font == NULL) {
if (fs::PathExists(font_path)) {
font = m_env->getFont(font_path.c_str());
if (font)
verbosestream << "FontEngine: found font: " << font_path << std::endl;
}
}
if (font != NULL) {
font->grab();
m_font_cache[mode][basesize] = font;
}
}

140
src/fontengine.h Normal file
View File

@ -0,0 +1,140 @@
/*
Minetest
Copyright (C) 2010-2014 sapier <sapier at gmx dot net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __FONTENGINE_H__
#define __FONTENGINE_H__
#include <map>
#include <vector>
#include "IGUIFont.h"
#include "IGUISkin.h"
#include "IGUIEnvironment.h"
#include "settings.h"
#define FONT_SIZE_UNSPECIFIED 0xFFFFFFFF
enum FontMode {
FM_Standard = 0,
FM_Mono,
FM_Fallback,
FM_Simple,
FM_SimpleMono,
FM_MaxMode,
FM_Unspecified
};
class FontEngine
{
public:
FontEngine(Settings* main_settings, gui::IGUIEnvironment* env);
~FontEngine();
/** get Font */
irr::gui::IGUIFont* getFont(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified);
/** get text height for a specific font */
unsigned int getTextHeight(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified);
/** get text width if a text for a specific font */
unsigned int getTextWidth(const std::string& text,
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified)
{
return getTextWidth(narrow_to_wide(text));
}
/** get text width if a text for a specific font */
unsigned int getTextWidth(const std::wstring& text,
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified);
/** get line height for a specific font (including empty room between lines) */
unsigned int getLineHeight(unsigned int font_size=FONT_SIZE_UNSPECIFIED,
FontMode mode=FM_Unspecified);
/** get default font size */
unsigned int getDefaultFontSize();
/** initialize font engine */
void initialize(Settings* main_settings, gui::IGUIEnvironment* env);
/** update internal parameters from settings */
void readSettings();
private:
/** disable copy constructor */
FontEngine() :
m_settings(NULL),
m_env(NULL),
m_font_cache(),
m_default_size(),
m_currentMode(FM_Standard),
m_lastMode(),
m_lastSize(0),
m_lastFont(NULL)
{};
/** update content of font cache in case of a setting change made it invalid */
void updateFontCache();
/** initialize a new font */
void initFont(unsigned int basesize, FontMode mode=FM_Unspecified);
/** initialize a font without freetype */
void initSimpleFont(unsigned int basesize, FontMode mode);
/** update current minetest skin with font changes */
void updateSkin();
/** clean cache */
void cleanCache();
/** pointer to settings for registering callbacks or reading config */
Settings* m_settings;
/** pointer to irrlicht gui environment */
gui::IGUIEnvironment* m_env;
/** internal storage for caching fonts of different size */
std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode];
/** default font size to use */
unsigned int m_default_size[FM_MaxMode];
/** current font engine mode */
FontMode m_currentMode;
/** font mode of last request */
FontMode m_lastMode;
/** size of last request */
unsigned int m_lastSize;
/** last font returned */
irr::gui::IGUIFont* m_lastFont;
};
/** interface to access main font engine*/
extern FontEngine* g_fontengine;
#endif

View File

@ -70,6 +70,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/pointedthing.h"
#include "drawscene.h"
#include "content_cao.h"
#include "fontengine.h"
#ifdef HAVE_TOUCHSCREENGUI
#include "touchscreengui.h"
@ -437,9 +438,8 @@ PointedThing getPointedThing(Client *client, v3f player_position,
/* Profiler display */
void update_profiler_gui(gui::IGUIStaticText *guitext_profiler,
gui::IGUIFont *font, u32 text_height, u32 show_profiler,
u32 show_profiler_max)
void update_profiler_gui(gui::IGUIStaticText *guitext_profiler, FontEngine *fe,
u32 show_profiler, u32 show_profiler_max)
{
if (show_profiler == 0) {
guitext_profiler->setVisible(false);
@ -451,14 +451,14 @@ void update_profiler_gui(gui::IGUIStaticText *guitext_profiler,
guitext_profiler->setText(text.c_str());
guitext_profiler->setVisible(true);
s32 w = font->getDimension(text.c_str()).Width;
s32 w = fe->getTextWidth(text.c_str());
if (w < 400)
w = 400;
core::rect<s32> rect(6, 4 + (text_height + 5) * 2, 12 + w,
8 + (text_height + 5) * 2 +
font->getDimension(text.c_str()).Height);
core::rect<s32> rect(6, 4 + (fe->getTextHeight() + 5) * 2, 12 + w,
8 + (fe->getTextHeight() + 5) * 2 +
fe->getTextHeight());
guitext_profiler->setRelativePosition(rect);
guitext_profiler->setVisible(true);
}
@ -967,6 +967,7 @@ bool nodePlacementPrediction(Client &client,
// Dont place node when player would be inside new node
// NOTE: This is to be eventually implemented by a mod as client-side Lua
if (!nodedef->get(n).walkable ||
g_settings->getBool("enable_build_where_you_stand") ||
(client.checkPrivilege("noclip") && g_settings->getBool("noclip")) ||
(nodedef->get(n).walkable &&
neighbourpos != player->getStandingNodePos() + v3s16(0, 1, 0) &&
@ -1135,8 +1136,7 @@ static void show_pause_menu(GUIFormSpecMenu **cur_formspec,
/******************************************************************************/
static void updateChat(Client &client, f32 dtime, bool show_debug,
const v2u32 &screensize, bool show_chat, u32 show_profiler,
ChatBackend &chat_backend, gui::IGUIStaticText *guitext_chat,
gui::IGUIFont *font)
ChatBackend &chat_backend, gui::IGUIStaticText *guitext_chat)
{
// Add chat log output for errors to be shown in chat
static LogOutputBuffer chat_log_error_buf(LMT_ERROR);
@ -1159,9 +1159,7 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
// Display all messages in a static text element
unsigned int recent_chat_count = chat_backend.getRecentBuffer().getLineCount();
std::wstring recent_chat = chat_backend.getRecentChat();
// TODO replace by fontengine fcts
unsigned int line_height = font->getDimension(L"Ay").Height + font->getKerningHeight();
unsigned int line_height = g_fontengine->getLineHeight();
guitext_chat->setText(recent_chat.c_str());
@ -1172,7 +1170,7 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
chat_y += line_height;
// first pass to calculate height of text to be set
s32 width = std::min(font->getDimension(recent_chat.c_str()).Width + 10,
s32 width = std::min(g_fontengine->getTextWidth(recent_chat) + 10,
porting::getWindowSize().X - 20);
core::rect<s32> rect(10, chat_y, width, chat_y + porting::getWindowSize().Y);
guitext_chat->setRelativePosition(rect);
@ -1401,7 +1399,6 @@ public:
bool random_input,
InputHandler *input,
IrrlichtDevice *device,
gui::IGUIFont *font,
const std::string &map_dir,
const std::string &playername,
const std::string &password,
@ -1521,8 +1518,6 @@ private:
Client *client;
Server *server;
gui::IGUIFont *font;
IWritableTextureSource *texture_src;
IWritableShaderSource *shader_src;
@ -1557,7 +1552,6 @@ private:
IrrlichtDevice *device;
video::IVideoDriver *driver;
scene::ISceneManager *smgr;
u32 text_height;
bool *kill;
std::wstring *error_message;
IGameDef *gamedef; // Convenience (same as *client)
@ -1591,7 +1585,6 @@ private:
Game::Game() :
client(NULL),
server(NULL),
font(NULL),
texture_src(NULL),
shader_src(NULL),
itemdef_manager(NULL),
@ -1647,7 +1640,6 @@ bool Game::startup(bool *kill,
bool random_input,
InputHandler *input,
IrrlichtDevice *device,
gui::IGUIFont *font,
const std::string &map_dir,
const std::string &playername,
const std::string &password,
@ -1660,7 +1652,6 @@ bool Game::startup(bool *kill,
{
// "cache"
this->device = device;
this->font = font;
this->kill = kill;
this->error_message = error_message;
this->random_input = random_input;
@ -1670,7 +1661,6 @@ bool Game::startup(bool *kill,
driver = device->getVideoDriver();
smgr = device->getSceneManager();
text_height = font->getDimension(L"Random test string").Height;
if (!init(map_dir, address, port, gamespec))
return false;
@ -1933,7 +1923,7 @@ bool Game::createClient(const std::string &playername,
}
// Update cached textures, meshes and materials
client->afterContentReceived(device, font);
client->afterContentReceived(device, g_fontengine->getFont());
/* Camera
*/
@ -1991,8 +1981,7 @@ bool Game::createClient(const std::string &playername,
player->hurt_tilt_timer = 0;
player->hurt_tilt_strength = 0;
hud = new Hud(driver, smgr, guienv, font, text_height, gamedef,
player, local_inventory);
hud = new Hud(driver, smgr, guienv, gamedef, player, local_inventory);
if (!hud) {
*error_message = L"Memory error: could not create HUD";
@ -2021,7 +2010,7 @@ bool Game::initGui(std::wstring *error_message)
// Object infos are shown in this
guitext_info = guienv->addStaticText(
L"",
core::rect<s32>(0, 0, 400, text_height * 5 + 5) + v2s32(100, 200),
core::rect<s32>(0, 0, 400, g_fontengine->getTextHeight() * 5 + 5) + v2s32(100, 200),
false, true, guiroot);
// Status text (displays info when showing and hiding GUI stuff, etc.)
@ -2061,7 +2050,7 @@ bool Game::initGui(std::wstring *error_message)
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui)
g_touchscreengui->init(tsrc, porting::getDisplayDensity());
g_touchscreengui->init(texture_src, porting::getDisplayDensity());
#endif
@ -2103,9 +2092,11 @@ bool Game::connectToServer(const std::string &playername,
return false;
}
client = new Client(device, playername.c_str(), password, *draw_control,
texture_src, shader_src, itemdef_manager, nodedef_manager, sound,
eventmgr, connect_address.isIPv6());
client = new Client(device,
playername.c_str(), password, simple_singleplayer_mode,
*draw_control, texture_src, shader_src,
itemdef_manager, nodedef_manager, sound, eventmgr,
connect_address.isIPv6());
if (!client)
return false;
@ -2221,12 +2212,12 @@ bool Game::getServerContent(bool *aborted)
if (!client->itemdefReceived()) {
wchar_t *text = wgettext("Item definitions...");
progress = 0;
draw_load_screen(text, device, guienv, font, dtime, progress);
draw_load_screen(text, device, guienv, dtime, progress);
delete[] text;
} else if (!client->nodedefReceived()) {
wchar_t *text = wgettext("Node definitions...");
progress = 25;
draw_load_screen(text, device, guienv, font, dtime, progress);
draw_load_screen(text, device, guienv, dtime, progress);
delete[] text;
} else {
std::stringstream message;
@ -2248,7 +2239,7 @@ bool Game::getServerContent(bool *aborted)
progress = 50 + client->mediaReceiveProgress() * 50 + 0.5;
draw_load_screen(narrow_to_wide(message.str().c_str()), device,
guienv, font, dtime, progress);
guienv, dtime, progress);
}
}
@ -2350,7 +2341,7 @@ void Game::updateProfilers(const GameRunData &run_data, const RunStats &stats,
g_profiler->print(infostream);
}
update_profiler_gui(guitext_profiler, font, text_height,
update_profiler_gui(guitext_profiler, g_fontengine,
run_data.profiler_current_page, run_data.profiler_max_page);
g_profiler->clear();
@ -2706,7 +2697,8 @@ void Game::toggleHud(float *statustext_time, bool *flag)
*flag = !*flag;
*statustext_time = 0;
statustext = msg[*flag];
client->setHighlighted(client->getHighlighted(), *flag);
if (g_settings->getBool("enable_node_highlighting"))
client->setHighlighted(client->getHighlighted(), *flag);
}
@ -2761,8 +2753,8 @@ void Game::toggleProfiler(float *statustext_time, u32 *profiler_current_page,
*profiler_current_page = (*profiler_current_page + 1) % (profiler_max_page + 1);
// FIXME: This updates the profiler with incomplete values
update_profiler_gui(guitext_profiler, font, text_height,
*profiler_current_page, profiler_max_page);
update_profiler_gui(guitext_profiler, g_fontengine, *profiler_current_page,
profiler_max_page);
if (*profiler_current_page != 0) {
std::wstringstream sstr;
@ -2852,8 +2844,8 @@ void Game::updateCameraDirection(CameraOrientation *cam,
#ifdef HAVE_TOUCHSCREENGUI
if (g_touchscreengui) {
camera_yaw = g_touchscreengui->getYaw();
camera_pitch = g_touchscreengui->getPitch();
cam->camera_yaw = g_touchscreengui->getYaw();
cam->camera_pitch = g_touchscreengui->getPitch();
} else {
#endif
s32 dx = input->getMousePos().X - (driver->getScreenSize().Width / 2);
@ -3802,7 +3794,7 @@ void Game::updateFrame(std::vector<aabb3f> &highlight_boxes,
updateChat(*client, dtime, flags.show_debug, screensize,
flags.show_chat, runData->profiler_current_page,
*chat_backend, guitext_chat, font);
*chat_backend, guitext_chat);
/*
Inventory
@ -3880,7 +3872,7 @@ void Game::updateFrame(std::vector<aabb3f> &highlight_boxes,
Profiler graph
*/
if (flags.show_profiler_graph)
graph->draw(10, screensize.Y - 10, driver, font);
graph->draw(10, screensize.Y - 10, driver, g_fontengine->getFont());
/*
Damage flash
@ -3963,7 +3955,7 @@ void Game::updateGui(float *statustext_time, const RunStats& stats,
if (guitext->isVisible()) {
core::rect<s32> rect(
5, 5,
screensize.X, 5 + text_height
screensize.X, 5 + g_fontengine->getTextHeight()
);
guitext->setRelativePosition(rect);
}
@ -3981,8 +3973,8 @@ void Game::updateGui(float *statustext_time, const RunStats& stats,
guitext2->setVisible(true);
core::rect<s32> rect(
5, 5 + text_height,
screensize.X, 5 + text_height * 2
5, 5 + g_fontengine->getTextHeight(),
screensize.X, 5 + g_fontengine->getTextHeight() * 2
);
guitext2->setRelativePosition(rect);
} else {
@ -4093,7 +4085,7 @@ void Game::showOverlayMessage(const char *msg, float dtime,
int percent, bool draw_clouds)
{
wchar_t *text = wgettext(msg);
draw_load_screen(text, device, guienv, font, dtime, percent, draw_clouds);
draw_load_screen(text, device, guienv, dtime, percent, draw_clouds);
delete[] text;
}
@ -4133,7 +4125,6 @@ void the_game(bool *kill,
bool random_input,
InputHandler *input,
IrrlichtDevice *device,
gui::IGUIFont *font,
const std::string &map_dir,
const std::string &playername,
@ -4156,7 +4147,7 @@ void the_game(bool *kill,
try {
if (game.startup(kill, random_input, input, device, font, map_dir,
if (game.startup(kill, random_input, input, device, map_dir,
playername, password, &server_address, port,
&error_message, &chat_backend, gamespec,
simple_singleplayer_mode)) {

View File

@ -140,7 +140,6 @@ void the_game(bool *kill,
bool random_input,
InputHandler *input,
IrrlichtDevice *device,
gui::IGUIFont *font,
const std::string &map_dir,
const std::string &playername,
const std::string &password,

View File

@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "main.h" // for g_settings
#include "porting.h"
#include "tile.h"
#include "IGUIFont.h"
#include "fontengine.h"
#include <string>
#include "gettext.h"
@ -92,23 +92,11 @@ GUIChatConsole::GUIChatConsole(
m_background_color.setBlue(255);
}
// load the font
// FIXME should a custom texture_path be searched too?
std::string font_name = g_settings->get("mono_font_path");
#if USE_FREETYPE
m_use_freetype = g_settings->getBool("freetype");
if (m_use_freetype) {
u16 font_size = g_settings->getU16("mono_font_size");
m_font = gui::CGUITTFont::createTTFont(env, font_name.c_str(), font_size);
} else {
m_font = env->getFont(font_name.c_str());
}
#else
m_font = env->getFont(font_name.c_str());
#endif
m_font = g_fontengine->getFont(FONT_SIZE_UNSPECIFIED, FM_Mono);
if (m_font == NULL)
{
dstream << "Unable to load font: " << font_name << std::endl;
errorstream << "GUIChatConsole: Unable to load mono font ";
}
else
{
@ -124,12 +112,7 @@ GUIChatConsole::GUIChatConsole(
}
GUIChatConsole::~GUIChatConsole()
{
#if USE_FREETYPE
if (m_use_freetype)
m_font->drop();
#endif
}
{}
void GUIChatConsole::openConsole(f32 height)
{

View File

@ -35,6 +35,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clouds.h"
#include "httpfetch.h"
#include "log.h"
#include "fontengine.h"
#ifdef __ANDROID__
#include "tile.h"
#include <GLES/gl.h>
@ -169,12 +171,14 @@ GUIEngine::GUIEngine( irr::IrrlichtDevice* dev,
m_sound_manager = &dummySoundManager;
//create topleft header
core::rect<s32> rect(0, 0, 500, 20);
std::wstring t = narrow_to_wide(std::string("Minetest ") +
minetest_version_hash);
core::rect<s32> rect(0, 0, g_fontengine->getTextWidth(t), g_fontengine->getTextHeight());
rect += v2s32(4, 0);
std::string t = std::string("Minetest ") + minetest_version_hash;
m_irr_toplefttext =
m_device->getGUIEnvironment()->addStaticText(narrow_to_wide(t).c_str(),
m_device->getGUIEnvironment()->addStaticText(t.c_str(),
rect,false,true,0,-1);
//create formspecsource
@ -256,7 +260,16 @@ void GUIEngine::run()
cloudInit();
while(m_device->run() && (!m_startgame) && (!m_kill)) {
unsigned int text_height = g_fontengine->getTextHeight();
while(m_device->run() && (!m_startgame) && (!m_kill))
{
//check if we need to update the "upper left corner"-text
if (text_height != g_fontengine->getTextHeight()) {
updateTopLeftTextSize();
text_height = g_fontengine->getTextHeight();
}
driver->beginScene(true, true, video::SColor(255,140,186,250));
if (m_clouds_enabled)
@ -558,14 +571,32 @@ bool GUIEngine::downloadFile(std::string url, std::string target)
/******************************************************************************/
void GUIEngine::setTopleftText(std::string append)
{
std::string toset = std::string("Minetest ") + minetest_version_hash;
std::wstring toset = narrow_to_wide( std::string("Minetest ") +
minetest_version_hash);
if (append != "") {
toset += " / ";
toset += append;
if (append != "")
{
toset += L" / ";
toset += narrow_to_wide(append);
}
m_irr_toplefttext->setText(narrow_to_wide(toset).c_str());
m_irr_toplefttext->setText(toset.c_str());
updateTopLeftTextSize();
}
/******************************************************************************/
void GUIEngine::updateTopLeftTextSize()
{
std::wstring text = m_irr_toplefttext->getText();
core::rect<s32> rect(0, 0, g_fontengine->getTextWidth(text), g_fontengine->getTextHeight());
rect += v2s32(4, 0);
m_irr_toplefttext->remove();
m_irr_toplefttext =
m_device->getGUIEnvironment()->addStaticText(text.c_str(),
rect,false,true,0,-1);
}
/******************************************************************************/

View File

@ -188,6 +188,9 @@ private:
/** handler to limit frame rate within main menu */
void limitFrameRate();
/** update size of topleftext element */
void updateTopLeftTextSize();
/** device to draw at */
irr::IrrlichtDevice* m_device;
/** parent gui element */

View File

@ -51,6 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "client.h"
#include "util/string.h" // for parseColorString()
#include "fontengine.h"
#define MY_CHECKPOS(a,b) \
if (v_pos.size() != 2) { \
@ -68,6 +69,44 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/*
GUIFormSpecMenu
*/
static unsigned int font_line_height(gui::IGUIFont *font)
{
return font->getDimension(L"Ay").Height + font->getKerningHeight();
}
static gui::IGUIFont *select_font_by_line_height(double target_line_height)
{
// We don't get to directly select a font according to its
// baseline-to-baseline height. Rather, we select by em size.
// The ratio between these varies between fonts. The font
// engine also takes its size parameter not specified in pixels,
// as we want, but scaled by display density and gui_scaling,
// so invert that scaling here. Use a binary search among
// requested sizes to find the right font. Our starting bounds
// are an em height of 1 (being careful not to request size 0,
// which crashes the freetype system) and an em height of the
// target baseline-to-baseline height.
unsigned int loreq = ceil(1 / porting::getDisplayDensity()
/ g_settings->getFloat("gui_scaling"));
unsigned int hireq = ceil(target_line_height
/ porting::getDisplayDensity()
/ g_settings->getFloat("gui_scaling"));
unsigned int lohgt = font_line_height(g_fontengine->getFont(loreq));
unsigned int hihgt = font_line_height(g_fontengine->getFont(hireq));
while(hireq - loreq > 1 && lohgt != hihgt) {
unsigned int nureq = (loreq + hireq) >> 1;
unsigned int nuhgt = font_line_height(g_fontengine->getFont(nureq));
if(nuhgt < target_line_height) {
loreq = nureq;
lohgt = nuhgt;
} else {
hireq = nureq;
hihgt = nuhgt;
}
}
return g_fontengine->getFont(target_line_height - lohgt < hihgt - target_line_height ? loreq : hireq);
}
GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
gui::IGUIElement* parent, s32 id, IMenuManager *menumgr,
InventoryManager *invmgr, IGameDef *gamedef,
@ -89,8 +128,8 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
m_lock(false),
m_form_src(fsrc),
m_text_dst(tdst),
m_font(dev->getGUIEnvironment()->getSkin()->getFont()),
m_formspec_version(0)
m_formspec_version(0),
m_font(NULL)
#ifdef __ANDROID__
,m_JavaDialogFieldName(L"")
#endif
@ -107,9 +146,6 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
m_doubleclickdetect[1].pos = v2s32(0, 0);
m_tooltip_show_delay = (u32)g_settings->getS32("tooltip_show_delay");
m_btn_height = g_settings->getS32("font_size") +2;
assert(m_btn_height > 0);
}
GUIFormSpecMenu::~GUIFormSpecMenu()
@ -270,13 +306,11 @@ void GUIFormSpecMenu::parseSize(parserData* data,std::string element)
if (((parts.size() == 2) || parts.size() == 3) ||
((parts.size() > 3) && (m_formspec_version > FORMSPEC_API_VERSION)))
{
v2f invsize;
if (parts[1].find(';') != std::string::npos)
parts[1] = parts[1].substr(0,parts[1].find(';'));
invsize.X = stof(parts[0]);
invsize.Y = stof(parts[1]);
data->invsize.X = MYMAX(0, stof(parts[0]));
data->invsize.Y = MYMAX(0, stof(parts[1]));
lockSize(false);
if (parts.size() == 3) {
@ -285,70 +319,7 @@ void GUIFormSpecMenu::parseSize(parserData* data,std::string element)
}
}
double cur_scaling = porting::getDisplayDensity() *
g_settings->getFloat("gui_scaling");
if (m_lock) {
v2u32 current_screensize = m_device->getVideoDriver()->getScreenSize();
v2u32 delta = current_screensize - m_lockscreensize;
if (current_screensize.Y > m_lockscreensize.Y)
delta.Y /= 2;
else
delta.Y = 0;
if (current_screensize.X > m_lockscreensize.X)
delta.X /= 2;
else
delta.X = 0;
offset = v2s32(delta.X,delta.Y);
data->screensize = m_lockscreensize;
// fixed scaling for fixed size gui elements */
cur_scaling = LEGACY_SCALING;
}
else {
offset = v2s32(0,0);
}
/* adjust image size to dpi */
int y_partition = 15;
imgsize = v2s32(data->screensize.Y/y_partition, data->screensize.Y/y_partition);
int min_imgsize = DEFAULT_IMGSIZE * cur_scaling;
while ((min_imgsize > imgsize.Y) && (y_partition > 1)) {
y_partition--;
imgsize = v2s32(data->screensize.Y/y_partition, data->screensize.Y/y_partition);
}
assert(y_partition > 0);
/* adjust spacing to dpi */
spacing = v2s32(imgsize.X+(DEFAULT_XSPACING * cur_scaling),
imgsize.Y+(DEFAULT_YSPACING * cur_scaling));
padding = v2s32(data->screensize.Y/imgsize.Y, data->screensize.Y/imgsize.Y);
/* adjust padding to dpi */
padding = v2s32(
(padding.X/(2.0/3.0)) * cur_scaling,
(padding.X/(2.0/3.0)) * cur_scaling
);
data->size = v2s32(
padding.X*2+spacing.X*(invsize.X-1.0)+imgsize.X,
padding.Y*2+spacing.Y*(invsize.Y-1.0)+imgsize.Y + m_btn_height - 5
);
data->rect = core::rect<s32>(
data->screensize.X/2 - data->size.X/2 + offset.X,
data->screensize.Y/2 - data->size.Y/2 + offset.Y,
data->screensize.X/2 + data->size.X/2 + offset.X,
data->screensize.Y/2 + data->size.Y/2 + offset.Y
);
DesiredRect = data->rect;
recalculateAbsolutePosition(false);
data->basepos = getBasePos();
data->bp_set = 2;
data->explicit_size = true;
return;
}
errorstream<< "Invalid size element (" << parts.size() << "): '" << element << "'" << std::endl;
@ -401,7 +372,7 @@ void GUIFormSpecMenu::parseList(parserData* data,std::string element)
return;
}
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of list without a size[] element"<<std::endl;
m_inventorylists.push_back(ListDrawSpec(loc, listname, pos, geom, start_i));
return;
@ -517,35 +488,6 @@ void GUIFormSpecMenu::parseScrollBar(parserData* data, std::string element)
e->setSmallStep(10);
e->setLargeStep(100);
if (!m_lock) {
core::rect<s32> relative_rect = e->getRelativePosition();
if (!is_horizontal) {
s32 original_width = relative_rect.getWidth();
s32 width = (original_width/(2.0/3.0))
* porting::getDisplayDensity()
* g_settings->getFloat("gui_scaling");
e->setRelativePosition(core::rect<s32>(
relative_rect.UpperLeftCorner.X,
relative_rect.UpperLeftCorner.Y,
relative_rect.LowerRightCorner.X + (width - original_width),
relative_rect.LowerRightCorner.Y
));
}
else {
s32 original_height = relative_rect.getHeight();
s32 height = (original_height/(2.0/3.0))
* porting::getDisplayDensity()
* g_settings->getFloat("gui_scaling");
e->setRelativePosition(core::rect<s32>(
relative_rect.UpperLeftCorner.X,
relative_rect.UpperLeftCorner.Y,
relative_rect.LowerRightCorner.X,
relative_rect.LowerRightCorner.Y + (height - original_height)
));
}
}
m_scrollbars.push_back(std::pair<FieldSpec,gui::IGUIScrollBar*>(spec,e));
m_fields.push_back(spec);
return;
@ -575,7 +517,7 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element)
geom.X = stof(v_geom[0]) * (float)imgsize.X;
geom.Y = stof(v_geom[1]) * (float)imgsize.Y;
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of image without a size[] element"<<std::endl;
m_images.push_back(ImageDrawSpec(name, pos, geom));
return;
@ -591,7 +533,7 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element)
pos.X += stof(v_pos[0]) * (float) spacing.X;
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of image without a size[] element"<<std::endl;
m_images.push_back(ImageDrawSpec(name, pos));
return;
@ -621,7 +563,7 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element)
geom.X = stof(v_geom[0]) * (float)imgsize.X;
geom.Y = stof(v_geom[1]) * (float)imgsize.Y;
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of item_image without a size[] element"<<std::endl;
m_itemimages.push_back(ImageDrawSpec(name, pos, geom));
return;
@ -657,7 +599,7 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element,
core::rect<s32>(pos.X, pos.Y - m_btn_height,
pos.X + geom.X, pos.Y + m_btn_height);
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
label = unescape_string(label);
@ -716,7 +658,7 @@ void GUIFormSpecMenu::parseBackground(parserData* data,std::string element)
}
}
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of background without a size[] element"<<std::endl;
m_backgrounds.push_back(ImageDrawSpec(name, pos, geom));
return;
@ -1007,8 +949,9 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element)
if (label.length() >= 1)
{
rect.UpperLeftCorner.Y -= m_btn_height;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + m_btn_height;
int font_height = font_line_height(m_font);
rect.UpperLeftCorner.Y -= font_height;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, 0);
}
@ -1037,20 +980,7 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,
core::rect<s32> rect;
if(!data->bp_set)
{
rect = core::rect<s32>(
data->screensize.X/2 - 580/2,
data->screensize.Y/2 - 300/2,
data->screensize.X/2 + 580/2,
data->screensize.Y/2 + 300/2
);
DesiredRect = rect;
recalculateAbsolutePosition(false);
data->basepos = getBasePos();
data->bp_set = 1;
}
else if(data->bp_set == 2)
if(data->explicit_size)
errorstream<<"WARNING: invalid use of unpositioned \"field\" in inventory"<<std::endl;
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner;
@ -1102,8 +1032,9 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,
if (label.length() >= 1)
{
rect.UpperLeftCorner.Y -= m_btn_height;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + m_btn_height;
int font_height = font_line_height(m_font);
rect.UpperLeftCorner.Y -= font_height;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, 0);
}
}
@ -1146,7 +1077,7 @@ void GUIFormSpecMenu::parseTextArea(parserData* data,
core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of positioned "<<type<<" without a size[] element"<<std::endl;
if(m_form_src)
@ -1198,8 +1129,9 @@ void GUIFormSpecMenu::parseTextArea(parserData* data,
if (label.length() >= 1)
{
rect.UpperLeftCorner.Y -= m_btn_height;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + m_btn_height;
int font_height = font_line_height(m_font);
rect.UpperLeftCorner.Y -= font_height;
rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + font_height;
Environment->addStaticText(spec.flabel.c_str(), rect, false, true, this, 0);
}
}
@ -1239,28 +1171,46 @@ void GUIFormSpecMenu::parseLabel(parserData* data,std::string element)
v2s32 pos = padding;
pos.X += stof(v_pos[0]) * (float)spacing.X;
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
pos.Y += (stof(v_pos[1]) + 7.0/30.0) * (float)spacing.Y;
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of label without a size[] element"<<std::endl;
int font_height = font_line_height(m_font);
text = unescape_string(text);
std::vector<std::string> lines = split(text, '\n');
std::wstring wlabel = narrow_to_wide(text.c_str());
core::rect<s32> rect = core::rect<s32>(
pos.X, pos.Y+((imgsize.Y/2) - m_btn_height),
for (unsigned int i = 0; i != lines.size(); i++) {
// Lines are spaced at the nominal distance of
// 2/5 inventory slot, even if the font doesn't
// quite match that. This provides consistent
// form layout, at the expense of sometimes
// having sub-optimal spacing for the font.
// We multiply by 2 and then divide by 5, rather
// than multiply by 0.4, to get exact results
// in the integer cases: 0.4 is not exactly
// representable in binary floating point.
s32 posy = pos.Y + ((float)i) * spacing.Y * 2.0 / 5.0;
std::wstring wlabel = narrow_to_wide(lines[i].c_str());
core::rect<s32> rect = core::rect<s32>(
pos.X, posy - font_height,
pos.X + m_font->getDimension(wlabel.c_str()).Width,
pos.Y+((imgsize.Y/2) + m_btn_height));
posy + font_height);
FieldSpec spec(
L"",
wlabel,
L"",
258+m_fields.size()
);
gui::IGUIStaticText *e =
Environment->addStaticText(spec.flabel.c_str(),
rect, false, false, this, spec.fid);
e->setTextAlignment(gui::EGUIA_UPPERLEFT,
gui::EGUIA_CENTER);
m_fields.push_back(spec);
}
FieldSpec spec(
L"",
wlabel,
L"",
258+m_fields.size()
);
Environment->addStaticText(spec.flabel.c_str(), rect, false, false, this, spec.fid);
m_fields.push_back(spec);
return;
}
errorstream<< "Invalid label element(" << parts.size() << "): '" << element << "'" << std::endl;
@ -1285,12 +1235,12 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element)
core::rect<s32> rect = core::rect<s32>(
pos.X, pos.Y+((imgsize.Y/2)- m_btn_height),
pos.X+15, pos.Y +
(m_font->getKerningHeight() +
m_font->getDimension(text.c_str()).Height)
* (text.length()+1));
font_line_height(m_font)
* (text.length()+1)
+((imgsize.Y/2)- m_btn_height));
//actually text.length() would be correct but adding +1 avoids to break all mods
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of label without a size[] element"<<std::endl;
std::wstring label = L"";
@ -1356,7 +1306,7 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,
core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of image_button without a size[] element"<<std::endl;
image_name = unescape_string(image_name);
@ -1440,7 +1390,7 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element)
pos.X += stof(v_pos[0]) * (float)spacing.X;
pos.Y += stof(v_pos[1]) * (float)spacing.Y - m_btn_height * 2;
v2s32 geom;
geom.X = data->screensize.Y;
geom.X = DesiredRect.getWidth();
geom.Y = m_btn_height*2;
core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X,
@ -1507,7 +1457,7 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
core::rect<s32> rect = core::rect<s32>(pos.X, pos.Y, pos.X+geom.X, pos.Y+geom.Y);
if(data->bp_set != 2)
if(!data->explicit_size)
errorstream<<"WARNING: invalid use of item_image_button without a size[] element"<<std::endl;
IItemDefManager *idef = m_gamedef->idef();
@ -1671,6 +1621,30 @@ bool GUIFormSpecMenu::parseVersionDirect(std::string data)
return false;
}
bool GUIFormSpecMenu::parseSizeDirect(parserData* data, std::string element)
{
if (element == "")
return false;
std::vector<std::string> parts = split(element,'[');
if (parts.size() < 2)
return false;
std::string type = trim(parts[0]);
std::string description = trim(parts[1]);
if (type != "size" && type != "invsize")
return false;
if (type == "invsize")
log_deprecated("Deprecated formspec element \"invsize\" is used");
parseSize(data, description);
return true;
}
void GUIFormSpecMenu::parseElement(parserData* data, std::string element)
{
//some prechecks
@ -1696,17 +1670,6 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element)
std::string type = trim(parts[0]);
std::string description = trim(parts[1]);
if (type == "size") {
parseSize(data,description);
return;
}
if (type == "invsize") {
log_deprecated("Deprecated formspec element \"invsize\" is used");
parseSize(data,description);
return;
}
if (type == "list") {
parseList(data,description);
return;
@ -1875,12 +1838,6 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
// Base position of contents of form
mydata.basepos = getBasePos();
// State of basepos, 0 = not set, 1= set by formspec, 2 = set by size[] element
// Used to adjust form size automatically if needed
// A proceed button is added if there is no size[] element
mydata.bp_set = 0;
/* Convert m_init_draw_spec to m_inventorylists */
m_inventorylists.clear();
@ -1934,13 +1891,132 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
}
}
/* we need size first in order to calculate image scale */
mydata.explicit_size = false;
for (; i< elements.size(); i++) {
if (!parseSizeDirect(&mydata, elements[i])) {
break;
}
}
if (mydata.explicit_size) {
// compute scaling for specified form size
if (m_lock) {
v2u32 current_screensize = m_device->getVideoDriver()->getScreenSize();
v2u32 delta = current_screensize - m_lockscreensize;
if (current_screensize.Y > m_lockscreensize.Y)
delta.Y /= 2;
else
delta.Y = 0;
if (current_screensize.X > m_lockscreensize.X)
delta.X /= 2;
else
delta.X = 0;
offset = v2s32(delta.X,delta.Y);
mydata.screensize = m_lockscreensize;
} else {
offset = v2s32(0,0);
}
double gui_scaling = g_settings->getFloat("gui_scaling");
double screen_dpi = porting::getDisplayDensity() * 96;
double use_imgsize;
if (m_lock) {
// In fixed-size mode, inventory image size
// is 0.53 inch multiplied by the gui_scaling
// config parameter. This magic size is chosen
// to make the main menu (15.5 inventory images
// wide, including border) just fit into the
// default window (800 pixels wide) at 96 DPI
// and default scaling (1.00).
use_imgsize = 0.53 * screen_dpi * gui_scaling;
} else {
// In variable-size mode, we prefer to make the
// inventory image size 1/15 of screen height,
// multiplied by the gui_scaling config parameter.
// If the preferred size won't fit the whole
// form on the screen, either horizontally or
// vertically, then we scale it down to fit.
// (The magic numbers in the computation of what
// fits arise from the scaling factors in the
// following stanza, including the form border,
// help text space, and 0.1 inventory slot spare.)
// However, a minimum size is also set, that
// the image size can't be less than 0.3 inch
// multiplied by gui_scaling, even if this means
// the form doesn't fit the screen.
double prefer_imgsize = mydata.screensize.Y / 15 *
gui_scaling;
double fitx_imgsize = mydata.screensize.X /
((5.0/4.0) * (0.5 + mydata.invsize.X));
double fity_imgsize = mydata.screensize.Y /
((15.0/13.0) * (0.85 * mydata.invsize.Y));
double screen_dpi = porting::getDisplayDensity() * 96;
double min_imgsize = 0.3 * screen_dpi * gui_scaling;
use_imgsize = MYMAX(min_imgsize, MYMIN(prefer_imgsize,
MYMIN(fitx_imgsize, fity_imgsize)));
}
// Everything else is scaled in proportion to the
// inventory image size. The inventory slot spacing
// is 5/4 image size horizontally and 15/13 image size
// vertically. The padding around the form (incorporating
// the border of the outer inventory slots) is 3/8
// image size. Font height (baseline to baseline)
// is 2/5 vertical inventory slot spacing, and button
// half-height is 7/8 of font height.
imgsize = v2s32(use_imgsize, use_imgsize);
spacing = v2s32(use_imgsize*5.0/4, use_imgsize*15.0/13);
padding = v2s32(use_imgsize*3.0/8, use_imgsize*3.0/8);
double target_font_height = use_imgsize*15.0/13 * 0.4;
m_btn_height = use_imgsize*15.0/13 * 0.35;
m_font = select_font_by_line_height(target_font_height);
mydata.size = v2s32(
padding.X*2+spacing.X*(mydata.invsize.X-1.0)+imgsize.X,
padding.Y*2+spacing.Y*(mydata.invsize.Y-1.0)+imgsize.Y + m_btn_height*2.0/3.0
);
DesiredRect = mydata.rect = core::rect<s32>(
mydata.screensize.X/2 - mydata.size.X/2 + offset.X,
mydata.screensize.Y/2 - mydata.size.Y/2 + offset.Y,
mydata.screensize.X/2 + mydata.size.X/2 + offset.X,
mydata.screensize.Y/2 + mydata.size.Y/2 + offset.Y
);
} else {
// Non-size[] form must consist only of text fields and
// implicit "Proceed" button. Use default font, and
// temporary form size which will be recalculated below.
m_font = g_fontengine->getFont();
m_btn_height = font_line_height(m_font) * 0.875;
DesiredRect = core::rect<s32>(
mydata.screensize.X/2 - 580/2,
mydata.screensize.Y/2 - 300/2,
mydata.screensize.X/2 + 580/2,
mydata.screensize.Y/2 + 300/2
);
}
recalculateAbsolutePosition(false);
mydata.basepos = getBasePos();
m_tooltip_element->setOverrideFont(m_font);
gui::IGUISkin* skin = Environment->getSkin();
assert(skin != NULL);
gui::IGUIFont *old_font = skin->getFont();
skin->setFont(m_font);
for (; i< elements.size(); i++) {
parseElement(&mydata, elements[i]);
}
// If there's fields, add a Proceed button
if (m_fields.size() && mydata.bp_set != 2) {
// if the size wasn't set by an invsize[] or size[] adjust it now to fit all the fields
// If there are fields without explicit size[], add a "Proceed"
// button and adjust size to fit all the fields.
if (m_fields.size() && !mydata.explicit_size) {
mydata.rect = core::rect<s32>(
mydata.screensize.X/2 - 580/2,
mydata.screensize.Y/2 - 300/2,
@ -1972,6 +2048,8 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|| !isMyChild(focused_element)
|| focused_element->getType() == gui::EGUIET_TAB_CONTROL)
setInitialFocus();
skin->setFont(old_font);
}
#ifdef __ANDROID__
@ -2048,12 +2126,6 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
{
video::IVideoDriver* driver = Environment->getVideoDriver();
// Get font
gui::IGUIFont *font = NULL;
gui::IGUISkin* skin = Environment->getSkin();
if (skin)
font = skin->getFont();
Inventory *inv = m_invmgr->getInventory(s.inventoryloc);
if(!inv){
infostream<<"GUIFormSpecMenu::drawList(): WARNING: "
@ -2130,7 +2202,7 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
}
if(!item.empty())
{
drawItemStack(driver, font, item,
drawItemStack(driver, m_font, item,
rect, &AbsoluteClippingRect, m_gamedef);
}
@ -2164,12 +2236,6 @@ void GUIFormSpecMenu::drawSelectedItem()
video::IVideoDriver* driver = Environment->getVideoDriver();
// Get font
gui::IGUIFont *font = NULL;
gui::IGUISkin* skin = Environment->getSkin();
if (skin)
font = skin->getFont();
Inventory *inv = m_invmgr->getInventory(m_selected_item->inventoryloc);
assert(inv);
InventoryList *list = inv->getList(m_selected_item->listname);
@ -2179,7 +2245,7 @@ void GUIFormSpecMenu::drawSelectedItem()
core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
core::rect<s32> rect = imgrect + (m_pointer - imgrect.getCenter());
drawItemStack(driver, font, stack, rect, NULL, m_gamedef);
drawItemStack(driver, m_font, stack, rect, NULL, m_gamedef);
}
void GUIFormSpecMenu::drawMenu()
@ -2192,11 +2258,13 @@ void GUIFormSpecMenu::drawMenu()
}
}
gui::IGUISkin* skin = Environment->getSkin();
assert(skin != NULL);
gui::IGUIFont *old_font = skin->getFont();
skin->setFont(m_font);
updateSelectedItem();
gui::IGUISkin* skin = Environment->getSkin();
if (!skin)
return;
video::IVideoDriver* driver = Environment->getVideoDriver();
v2u32 screenSize = driver->getScreenSize();
@ -2393,6 +2461,8 @@ void GUIFormSpecMenu::drawMenu()
Draw dragged item stack
*/
drawSelectedItem();
skin->setFont(old_font);
}
void GUIFormSpecMenu::updateSelectedItem()
@ -2649,6 +2719,30 @@ static bool isChild(gui::IGUIElement * tocheck, gui::IGUIElement * parent)
bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
{
// The IGUITabControl renders visually using the skin's selected
// font, which we override for the duration of form drawing,
// but computes tab hotspots based on how it would have rendered
// using the font that is selected at the time of button release.
// To make these two consistent, temporarily override the skin's
// font while the IGUITabControl is processing the event.
if (event.EventType == EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) {
s32 x = event.MouseInput.X;
s32 y = event.MouseInput.Y;
gui::IGUIElement *hovered =
Environment->getRootGUIElement()->getElementFromPoint(
core::position2d<s32>(x, y));
if (hovered->getType() == gui::EGUIET_TAB_CONTROL) {
gui::IGUISkin* skin = Environment->getSkin();
assert(skin != NULL);
gui::IGUIFont *old_font = skin->getFont();
skin->setFont(m_font);
bool retval = hovered->OnEvent(event);
skin->setFont(old_font);
return retval;
}
}
// Fix Esc/Return key being eaten by checkboxen and tables
if(event.EventType==EET_KEY_INPUT_EVENT) {
KeyPress kp(event.KeyInput);

View File

@ -345,14 +345,14 @@ protected:
private:
IFormSource *m_form_src;
TextDest *m_text_dst;
gui::IGUIFont *m_font;
unsigned int m_formspec_version;
typedef struct {
bool explicit_size;
v2f invsize;
v2s32 size;
core::rect<s32> rect;
v2s32 basepos;
int bp_set;
v2u32 screensize;
std::wstring focused_fieldname;
GUITable::TableOptions table_options;
@ -399,6 +399,7 @@ private:
void parseListColors(parserData* data,std::string element);
void parseTooltip(parserData* data,std::string element);
bool parseVersionDirect(std::string data);
bool parseSizeDirect(parserData* data, std::string element);
void parseScrollBar(parserData* data, std::string element);
/**
@ -416,6 +417,7 @@ private:
clickpos m_doubleclickdetect[2];
int m_btn_height;
gui::IGUIFont *m_font;
std::wstring getLabelByID(s32 id);
std::wstring getNameByID(s32 id);

View File

@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "localplayer.h"
#include "camera.h"
#include "porting.h"
#include "fontengine.h"
#include <IGUIStaticText.h>
#ifdef HAVE_TOUCHSCREENGUI
@ -38,14 +39,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#endif
Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
gui::IGUIEnvironment* guienv, gui::IGUIFont *font,
u32 text_height, IGameDef *gamedef,
LocalPlayer *player, Inventory *inventory) {
gui::IGUIEnvironment* guienv, IGameDef *gamedef, LocalPlayer *player,
Inventory *inventory) {
this->driver = driver;
this->smgr = smgr;
this->guienv = guienv;
this->font = font;
this->text_height = text_height;
this->gamedef = gamedef;
this->player = player;
this->inventory = inventory;
@ -156,7 +154,7 @@ void Hud::drawItem(const ItemStack &item, const core::rect<s32>& rect, bool sele
video::SColor bgcolor2(128, 0, 0, 0);
if (!use_hotbar_image)
driver->draw2DRectangle(bgcolor2, rect, NULL);
drawItemStack(driver, font, item, rect, NULL, gamedef);
drawItemStack(driver, g_fontengine->getFont(), item, rect, NULL, gamedef);
}
//NOTE: selectitem = 0 -> no selected; selectitem 1-based
@ -240,6 +238,8 @@ void Hud::drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
void Hud::drawLuaElements(v3s16 camera_offset) {
uint32_t text_height = g_fontengine->getTextHeight();
irr::gui::IGUIFont* font = g_fontengine->getFont();
for (size_t i = 0; i != player->maxHudId(); i++) {
HudElement *e = player->getHud(i);
if (!e)

Some files were not shown because too many files have changed in this diff Show More